bootstrap4_rails_components 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +362 -0
  4. data/Rakefile +23 -0
  5. data/app/assets/config/bootstrap4_rails_components_manifest.js +3 -0
  6. data/app/assets/javascripts/bootstrap4_rails_components/application.js +8 -0
  7. data/app/assets/javascripts/bootstrap4_rails_components/vendor/tooltips.js +42 -0
  8. data/app/assets/stylesheets/bootstrap4_rails_components/bootstrap/application.scss +2 -0
  9. data/app/controllers/bootstrap4_rails_components/application_controller.rb +5 -0
  10. data/app/helpers/bootstrap4_rails_components/application_helper.rb +38 -0
  11. data/app/models/bootstrap4_rails_components/application_record.rb +5 -0
  12. data/config/initializers/web_app_manifest.rb +3 -0
  13. data/config/locales/en.yml +63 -0
  14. data/config/routes.rb +2 -0
  15. data/config/spring.rb +1 -0
  16. data/lib/bootstrap4_rails_components.rb +75 -0
  17. data/lib/bootstrap4_rails_components/bootstrap/components/alert.rb +52 -0
  18. data/lib/bootstrap4_rails_components/bootstrap/components/badge.rb +39 -0
  19. data/lib/bootstrap4_rails_components/bootstrap/components/base.rb +151 -0
  20. data/lib/bootstrap4_rails_components/bootstrap/components/breadcrumb.rb +23 -0
  21. data/lib/bootstrap4_rails_components/bootstrap/components/breadcrumb_item.rb +28 -0
  22. data/lib/bootstrap4_rails_components/bootstrap/components/button.rb +74 -0
  23. data/lib/bootstrap4_rails_components/bootstrap/components/button_group.rb +36 -0
  24. data/lib/bootstrap4_rails_components/bootstrap/components/button_toolbar.rb +21 -0
  25. data/lib/bootstrap4_rails_components/bootstrap/components/card.rb +81 -0
  26. data/lib/bootstrap4_rails_components/bootstrap/components/card_body.rb +15 -0
  27. data/lib/bootstrap4_rails_components/bootstrap/components/card_footer.rb +15 -0
  28. data/lib/bootstrap4_rails_components/bootstrap/components/card_header.rb +35 -0
  29. data/lib/bootstrap4_rails_components/bootstrap/components/card_image.rb +33 -0
  30. data/lib/bootstrap4_rails_components/bootstrap/components/card_image_overlay.rb +46 -0
  31. data/lib/bootstrap4_rails_components/bootstrap/components/carousel.rb +57 -0
  32. data/lib/bootstrap4_rails_components/bootstrap/components/carousel_caption.rb +34 -0
  33. data/lib/bootstrap4_rails_components/bootstrap/components/carousel_control.rb +73 -0
  34. data/lib/bootstrap4_rails_components/bootstrap/components/carousel_indicators.rb +54 -0
  35. data/lib/bootstrap4_rails_components/bootstrap/components/carousel_item.rb +49 -0
  36. data/lib/bootstrap4_rails_components/bootstrap/components/collapse.rb +32 -0
  37. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown.rb +51 -0
  38. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown_divider.rb +19 -0
  39. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown_header.rb +23 -0
  40. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown_item.rb +41 -0
  41. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown_menu.rb +32 -0
  42. data/lib/bootstrap4_rails_components/bootstrap/components/dropdown_toggle.rb +82 -0
  43. data/lib/bootstrap4_rails_components/bootstrap/components/embed.rb +80 -0
  44. data/lib/bootstrap4_rails_components/bootstrap/components/form.rb +13 -0
  45. data/lib/bootstrap4_rails_components/bootstrap/components/input_group.rb +13 -0
  46. data/lib/bootstrap4_rails_components/bootstrap/components/jumbotron.rb +13 -0
  47. data/lib/bootstrap4_rails_components/bootstrap/components/list_group.rb +39 -0
  48. data/lib/bootstrap4_rails_components/bootstrap/components/list_group_item.rb +69 -0
  49. data/lib/bootstrap4_rails_components/bootstrap/components/media.rb +15 -0
  50. data/lib/bootstrap4_rails_components/bootstrap/components/media_body.rb +15 -0
  51. data/lib/bootstrap4_rails_components/bootstrap/components/media_object.rb +23 -0
  52. data/lib/bootstrap4_rails_components/bootstrap/components/modal.rb +66 -0
  53. data/lib/bootstrap4_rails_components/bootstrap/components/modal_body.rb +16 -0
  54. data/lib/bootstrap4_rails_components/bootstrap/components/modal_footer.rb +16 -0
  55. data/lib/bootstrap4_rails_components/bootstrap/components/modal_header.rb +37 -0
  56. data/lib/bootstrap4_rails_components/bootstrap/components/nav.rb +71 -0
  57. data/lib/bootstrap4_rails_components/bootstrap/components/nav_item.rb +103 -0
  58. data/lib/bootstrap4_rails_components/bootstrap/components/nav_link.rb +62 -0
  59. data/lib/bootstrap4_rails_components/bootstrap/components/navbar.rb +97 -0
  60. data/lib/bootstrap4_rails_components/bootstrap/components/navbar_brand.rb +25 -0
  61. data/lib/bootstrap4_rails_components/bootstrap/components/navbar_nav.rb +48 -0
  62. data/lib/bootstrap4_rails_components/bootstrap/components/navbar_text.rb +21 -0
  63. data/lib/bootstrap4_rails_components/bootstrap/components/navbar_toggler.rb +38 -0
  64. data/lib/bootstrap4_rails_components/bootstrap/components/page_item.rb +66 -0
  65. data/lib/bootstrap4_rails_components/bootstrap/components/pagination.rb +30 -0
  66. data/lib/bootstrap4_rails_components/bootstrap/components/popover.rb +12 -0
  67. data/lib/bootstrap4_rails_components/bootstrap/components/progress.rb +44 -0
  68. data/lib/bootstrap4_rails_components/bootstrap/components/progress_bar.rb +51 -0
  69. data/lib/bootstrap4_rails_components/bootstrap/components/tab_content.rb +15 -0
  70. data/lib/bootstrap4_rails_components/bootstrap/components/tab_pane.rb +49 -0
  71. data/lib/bootstrap4_rails_components/bootstrap/components/table.rb +17 -0
  72. data/lib/bootstrap4_rails_components/bootstrap/readme.md +1 -0
  73. data/lib/bootstrap4_rails_components/bootstrap/utilities/activatable.rb +32 -0
  74. data/lib/bootstrap4_rails_components/bootstrap/utilities/alignable.rb +33 -0
  75. data/lib/bootstrap4_rails_components/bootstrap/utilities/collapse_toggleable.rb +35 -0
  76. data/lib/bootstrap4_rails_components/bootstrap/utilities/collapsible.rb +42 -0
  77. data/lib/bootstrap4_rails_components/bootstrap/utilities/disableable.rb +49 -0
  78. data/lib/bootstrap4_rails_components/bootstrap/utilities/dismissible.rb +24 -0
  79. data/lib/bootstrap4_rails_components/bootstrap/utilities/dropdown_directionable.rb +40 -0
  80. data/lib/bootstrap4_rails_components/bootstrap/utilities/headable.rb +20 -0
  81. data/lib/bootstrap4_rails_components/bootstrap/utilities/modalable.rb +104 -0
  82. data/lib/bootstrap4_rails_components/bootstrap/utilities/progressable.rb +42 -0
  83. data/lib/bootstrap4_rails_components/bootstrap/utilities/remotable.rb +24 -0
  84. data/lib/bootstrap4_rails_components/bootstrap/utilities/sizable.rb +40 -0
  85. data/lib/bootstrap4_rails_components/bootstrap/utilities/themeable.rb +51 -0
  86. data/lib/bootstrap4_rails_components/bootstrap/utilities/titleable.rb +20 -0
  87. data/lib/bootstrap4_rails_components/bootstrap/utilities/tooltipable.rb +95 -0
  88. data/lib/bootstrap4_rails_components/bootstrap/utilities/wrappable.rb +48 -0
  89. data/lib/bootstrap4_rails_components/engine.rb +38 -0
  90. data/lib/bootstrap4_rails_components/ui/base.rb +42 -0
  91. data/lib/bootstrap4_rails_components/ui/bootstrap.rb +44 -0
  92. data/lib/bootstrap4_rails_components/ui/utilities.rb +10 -0
  93. data/lib/bootstrap4_rails_components/ui/utilities/initializer.rb +88 -0
  94. data/lib/bootstrap4_rails_components/version.rb +5 -0
  95. metadata +372 -0
@@ -0,0 +1,5 @@
1
+ module Bootstrap4RailsComponents
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootstrap4RailsComponents
4
+ # Core rendering helper methods
5
+ module ApplicationHelper
6
+ # `ui` is an initiator method so that this system allows for
7
+ # extension when used in a cascade of frameworks, for example when
8
+ # building a custom design system that is based on Bootstrap4.
9
+ # One would utilize this the `ui` method to initiate this engine
10
+ # and then call a specific framework / system as a second method.
11
+ #
12
+ # Example use for bootstrap4:
13
+ # <%= ui.bootstrap(:my_component, :optional_trait1, :optional_trait2, option: :value, option2: :value2) %>
14
+ #
15
+ # Real-world usage:
16
+ # A normal button link with a tooltip:
17
+ # <%= ui.bootstrap(:button, :primary, body: 'Get Started', href: marketing_page_path, tooltip: 'Save big!') %>
18
+ #
19
+ # A complex ajax-y delete button:
20
+ # <%= ui.bootstrap(:button, :primary, disabled: user.payments.any?, method: :delete, href: user_path(user), confirm: "Please confirm #{user.name} should be deleted", disable_with: ui.bootstrap(:icon, :loader), remote: true, tooltip: "Permanently delete #{user.name}" render_if: user.admin?) %>
21
+ def ui
22
+ @ui ||= Bootstrap4RailsComponents::UI::Base.new(get_view_context)
23
+ end
24
+
25
+ private
26
+
27
+ # In the event that a controller isn't defined, we'll supply ApplicationController's view_context, instead.
28
+ # While not ideal, this'll work for basic implementation scenarios that aren't leaning heavily on the
29
+ # view_context in play.
30
+ def get_view_context
31
+ if defined?(controller) && controller.present?
32
+ controller.view_context
33
+ else
34
+ ApplicationController.new.view_context
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ module Bootstrap4RailsComponents
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.config.assets.configure do |env|
2
+ env.register_mime_type('application/manifest+json', extensions: ['.webmanifest'])
3
+ end
@@ -0,0 +1,63 @@
1
+ en:
2
+ bootstrap4_rails_components:
3
+ errors:
4
+ argument_error:
5
+ # required keys -- :modal, :class_name, :options, :file, :method
6
+ #
7
+ # Example keys:
8
+ #
9
+ # modal: '#example'
10
+ # class_name: self.class.name
11
+ # options: options
12
+ # file: __FILE__
13
+ # method: __method__
14
+ modalable:
15
+ tooltip: |
16
+ ArgumentError: :modal & :tooltip may not both be present in :options hash
17
+
18
+ Raised from gem file: %{file}
19
+ Raised from gem method: #%{method}
20
+
21
+ To fix this error:
22
+ Remove `tooltip: [the tooltip]` or `modal: '%{modal}'` from your component's :options hash
23
+
24
+ Component Reference:
25
+ Invalid component: %{class_name}
26
+ Component options: %{options}
27
+
28
+ About:
29
+ Modal and Tooltip both utilize the data-toggle HTML data attribute. When :modal is present,
30
+ it will always overwrite the tooltip's data-toggle attribute causing a silent failure
31
+ in which the tooltip does not render (though the modal HTML does).
32
+
33
+ remote: |
34
+ ArgumentError: :modal & remote: true may not both be present in :options hash
35
+
36
+ Raised from gem file: %{file}
37
+ Raised from gem method: #%{method}
38
+
39
+ To fix this error:
40
+ Remove `remote: true` or `modal: '%{modal}'` from your component's :options hash
41
+
42
+ Example incorrect usage:
43
+ = ui.bootstrap :button, remote: true, modal: '%{modal}', ...
44
+
45
+ Component Reference:
46
+ Invalid component: %{class_name}
47
+ Component options: %{options}
48
+
49
+ About:
50
+ Components may not include both `modal: %{modal}` and `remote: true` in their options because modalable components
51
+ that fire remote actions can result in undesirable modal activation behavior.
52
+
53
+ This tends to occur when a modal is injected into the page from a remote action, is subsequently dismissed
54
+ and then opened again from the same remote link.
55
+
56
+ The previously dismissed modal appears (because it's still on the page, and referenced in the component's HTML)
57
+ and the modal is then, visibly to the user, re-animated (overwritten and re-started) by the newly injected modal from the remote ajax action.
58
+
59
+
60
+
61
+
62
+
63
+
@@ -0,0 +1,2 @@
1
+ Bootstrap4RailsComponents::Engine.routes.draw do
2
+ end
@@ -0,0 +1 @@
1
+ Spring.application_root = './spec/test_app'
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bootstrap4_rails_components/engine'
4
+
5
+ module Bootstrap4RailsComponents
6
+ require 'bootstrap'
7
+ require 'haml'
8
+ require 'jquery-rails'
9
+ require 'sass-rails'
10
+
11
+ DEFAULT_BOOTSTRAP_THEME = :primary
12
+
13
+ BOOTSTRAP_THEMES = %i[primary
14
+ secondary
15
+ success
16
+ danger
17
+ warning
18
+ info
19
+ light
20
+ dark].freeze
21
+
22
+ BOOTSTRAP_COMPONENT_NAMES = %i[alert
23
+ badge
24
+ breadcrumb
25
+ breadcrumb_item
26
+ button
27
+ button_group
28
+ button_toolbar
29
+ card
30
+ card_body
31
+ card_footer
32
+ card_header
33
+ card_image
34
+ card_image_overlay
35
+ carousel
36
+ carousel_caption
37
+ carousel_control
38
+ carousel_indicators
39
+ carousel_item
40
+ collapse
41
+ dropdown
42
+ dropdown_divider
43
+ dropdown_header
44
+ dropdown_item
45
+ dropdown_menu
46
+ dropdown_toggle
47
+ embed
48
+ form
49
+ input_group
50
+ jumbotron
51
+ list_group
52
+ list_group_item
53
+ media
54
+ media_body
55
+ media_object
56
+ modal
57
+ modal_body
58
+ modal_footer
59
+ modal_header
60
+ nav
61
+ nav_item
62
+ nav_link
63
+ navbar
64
+ navbar_brand
65
+ navbar_nav
66
+ navbar_text
67
+ navbar_toggler
68
+ page_item
69
+ pagination
70
+ popover
71
+ progress
72
+ tab_content
73
+ tab_pane
74
+ table].freeze
75
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootstrap4RailsComponents
4
+ module Bootstrap
5
+ module Components
6
+ # Bootstrap Alert Component
7
+ # https://getbootstrap.com/docs/4.1/components/alerts/
8
+ class Alert < Bootstrap4RailsComponents::Bootstrap::Components::Base
9
+ include Bootstrap::Utilities::Dismissible
10
+ include Bootstrap::Utilities::Headable
11
+ include Bootstrap::Utilities::Themeable
12
+
13
+ def render
14
+ content_tag(:div, html_options) do
15
+ capture do
16
+ if dismissible
17
+ concat(
18
+ Bootstrap4RailsComponents::Bootstrap::Components::Button.new({ as: :button, class: 'close', theme: nil, data: { dismiss: 'alert' }, aria: { label: 'Close' } }, view_context).render do
19
+ content_tag(:span, "&times;".html_safe, aria: { hidden: 'true' } )
20
+ end
21
+ )
22
+ end
23
+ if heading
24
+ concat(content_tag(:h4, heading, class: 'alert-heading'))
25
+ end
26
+ concat(block_given? ? yield : body)
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def assistive_html_attributes
34
+ super.merge!(role: 'alert')
35
+ end
36
+
37
+ def css_classes
38
+ [
39
+ super,
40
+ ("#{component_css_class}-dismissible" if dismissible),
41
+ ('fade' if dismissible),
42
+ ('show' if dismissible)
43
+ ].join(' ').squish
44
+ end
45
+
46
+ def outlineable?
47
+ false
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootstrap4RailsComponents
4
+ module Bootstrap
5
+ module Components
6
+ # Bootstrap Badge Component
7
+ # https://getbootstrap.com/docs/4.1/components/badge/
8
+ class Badge < Bootstrap4RailsComponents::Bootstrap::Components::Base
9
+ include Bootstrap::Utilities::Themeable
10
+ include Bootstrap::Utilities::Wrappable
11
+
12
+ def pill
13
+ options.fetch(:pill, false)
14
+ end
15
+
16
+ private
17
+
18
+ def base_element
19
+ as #comes from the wrappable module
20
+ end
21
+
22
+ def css_classes
23
+ [
24
+ super,
25
+ ("#{component_css_class}-pill" if pill)
26
+ ].join(' ').squish
27
+ end
28
+
29
+ def default_html_wrapper_element
30
+ :span
31
+ end
32
+
33
+ def non_html_attribute_options
34
+ super.push(:pill)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bootstrap4RailsComponents
4
+ module Bootstrap
5
+ module Components
6
+ # Base Component
7
+ # Defines conventional, shared behavior across
8
+ # Bootstrap components
9
+ class Base
10
+ include ActionView::Helpers::TagHelper
11
+ include ActionView::Helpers::TextHelper
12
+ include ActionView::Helpers::AssetTagHelper
13
+ include ActionView::Context
14
+
15
+ attr_reader :body
16
+
17
+ attr_accessor :options,
18
+ :view_context
19
+
20
+ def initialize(component_options, view_context)
21
+ self.options = defaults.merge!(component_options)
22
+ self.view_context = view_context
23
+ @body = options.fetch(:body, '')
24
+ utility_initialize
25
+ component_initialize
26
+ end
27
+
28
+
29
+ # This base render handles many of the components and
30
+ # can be changed to have a different base element by
31
+ # overriding the base_element.
32
+ # in some cases, the child component can also call
33
+ # super with a block to have this render as the wrapping
34
+ # element.
35
+ def render
36
+ content_tag(base_element, html_options) do
37
+ (block_given? ? yield : body)
38
+ end
39
+ end
40
+
41
+ # This is used to help identify where to find partials for rendering components.
42
+ #
43
+ # Set the component family, e.g.: :breadcrumb
44
+ # on any sibling components.
45
+ #
46
+ # For example:
47
+ # BreadcrumbItem & Breadcrumb are members of the :breadcrumb component_family
48
+ def component_family
49
+ nil
50
+ end
51
+
52
+ def data
53
+ options[:data] || {}
54
+ end
55
+
56
+ def html_options
57
+ options.except(*non_html_attribute_options.uniq)
58
+ .merge!(id: id,
59
+ class: css_classes,
60
+ data: data,
61
+ href: href,
62
+ style: style,
63
+ **assistive_html_attributes)
64
+ .reject { |_k, v| v.blank? } # prevent empty attributes from showing up
65
+ # Example: <div class>Text</div>
66
+ end
67
+
68
+ def href
69
+ options[:href]
70
+ end
71
+
72
+ def id
73
+ options[:id]
74
+ end
75
+
76
+ # For components that inherit bootstrap, provide a second
77
+ # layer of initialization, for example:
78
+ # to initialize traits on design system components
79
+ # (which are not available on bootstrap)
80
+ def component_initialize; end
81
+ def utility_initialize; end
82
+
83
+ def style
84
+ options[:style]
85
+ end
86
+
87
+ private
88
+
89
+ # Assigned on individual components as needed
90
+ # Ex: { role: 'alert' }
91
+ #
92
+ # If aria assistive html is needed, see:
93
+ # Bootstrap::Utilities::AriaAssistable
94
+ # avoid passing aria to assistive_html_attributes directly
95
+ def assistive_html_attributes
96
+ @assistive_html_attributes ||= {}
97
+ end
98
+
99
+ # the base_element is used in the default render for all components
100
+ # as the outer wrapping element. Typically, this is a div, but
101
+ # can be overriddent as a different static element in a child class
102
+ # or as a dynamic element in the child class.
103
+ # this allows most child components to not have to have their
104
+ # own render statement if their wrapping element is not a div
105
+ def base_element
106
+ :div
107
+ end
108
+
109
+ # Fallback component css class name.
110
+ # Overwritten within individual classes for situations like
111
+ # Button's css class is 'btn'...
112
+ # Example: returns 'alert' from Bootstrap4RailsComponents::Bootstrap::Components::Alert
113
+ def component_css_class
114
+ @component_css_class ||= component_class_name_string.underscore.dasherize.downcase
115
+ end
116
+
117
+ def component_class_name_string
118
+ self.class.name.demodulize.to_s
119
+ end
120
+
121
+ # Manage or adjust the css_classes of the component by
122
+ # adding a new string of css classes to this method
123
+ # ex: super.push('new-class')
124
+ def css_classes
125
+ @css_classes ||= [component_css_class, options[:class]].reject(&:nil?).uniq.join(' ').squish
126
+ end
127
+
128
+ def defaults
129
+ {
130
+ # HTML Defaults
131
+ class: '',
132
+ id: nil,
133
+
134
+ # Content
135
+ # heading: (nil if heading.present?),
136
+ body: nil,
137
+ data: {},
138
+
139
+ # Configuration
140
+ # traits: ([] if traits.present?)
141
+ }
142
+ end
143
+ # Remove attributes from html_options that shouldn't show up in the
144
+ # html element, ex: <div body='should not be here'>
145
+ def non_html_attribute_options
146
+ @non_html_attribute_options ||= %i[body heading traits render_if render_unless]
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end