headmin 0.3.4 → 0.4.2

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.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.gitignore +14 -0
  4. data/.lock-487e157d270f3062a98b7b2a012753708-1272821827 +0 -0
  5. data/.nvmrc +1 -0
  6. data/CHANGELOG.md +31 -0
  7. data/Gemfile +7 -4
  8. data/Gemfile.lock +191 -25
  9. data/README.md +7 -0
  10. data/Rakefile +1 -7
  11. data/app/assets/javascripts/headmin/config/i18n.js +9 -9
  12. data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +318 -0
  13. data/app/assets/javascripts/headmin/controllers/blocks_controller.js +74 -79
  14. data/app/assets/javascripts/headmin/controllers/date_range_controller.js +24 -24
  15. data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +23 -25
  16. data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +237 -237
  17. data/app/assets/javascripts/headmin/controllers/filter_controller.js +44 -44
  18. data/app/assets/javascripts/headmin/controllers/filters_controller.js +57 -61
  19. data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +29 -29
  20. data/app/assets/javascripts/headmin/controllers/hello_controller.js +3 -3
  21. data/app/assets/javascripts/headmin/controllers/notification_controller.js +7 -6
  22. data/app/assets/javascripts/headmin/controllers/popup_controller.js +57 -51
  23. data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +36 -9
  24. data/app/assets/javascripts/headmin/controllers/repeater_controller.js +122 -125
  25. data/app/assets/javascripts/headmin/controllers/select_controller.js +40 -39
  26. data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +100 -101
  27. data/app/assets/javascripts/headmin/controllers/table_controller.js +115 -115
  28. data/app/assets/javascripts/headmin/index.js +38 -35
  29. data/app/assets/javascripts/headmin.js +295 -37
  30. data/app/assets/stylesheets/headmin/forms/autocomplete.scss +21 -0
  31. data/app/assets/stylesheets/headmin/forms/file.scss +46 -0
  32. data/app/assets/stylesheets/headmin/forms/repeater.scss +62 -0
  33. data/app/assets/stylesheets/headmin/forms/search.scss +12 -0
  34. data/app/assets/stylesheets/headmin/forms.scss +11 -0
  35. data/app/assets/stylesheets/headmin/general.scss +14 -0
  36. data/app/assets/stylesheets/headmin/overrides/bootstrap.scss +5 -3
  37. data/app/assets/stylesheets/headmin/overrides/redactorx.scss +74 -0
  38. data/app/assets/stylesheets/headmin/popup.scss +1 -0
  39. data/app/assets/stylesheets/headmin/syntax.scss +36 -349
  40. data/app/assets/stylesheets/headmin/table.scss +1 -1
  41. data/app/assets/stylesheets/headmin/utilities/buttons.scss +19 -0
  42. data/app/assets/stylesheets/headmin/utilities/dropzone.scss +72 -0
  43. data/app/assets/stylesheets/headmin/utilities.scss +2 -68
  44. data/app/assets/stylesheets/headmin.css +209 -205
  45. data/app/assets/stylesheets/headmin.scss +1 -1
  46. data/app/helpers/headmin/admin_helper.rb +0 -1
  47. data/app/helpers/headmin/form_helper.rb +2 -8
  48. data/app/models/concerns/headmin/blockable.rb +1 -1
  49. data/app/models/concerns/headmin/field.rb +4 -1
  50. data/app/models/concerns/headmin/fieldable.rb +138 -44
  51. data/app/models/concerns/headmin/form/autocompletable.rb +38 -0
  52. data/app/models/concerns/headmin/form/hintable.rb +19 -0
  53. data/app/models/concerns/headmin/form/input_groupable.rb +23 -0
  54. data/app/models/concerns/headmin/form/labelable.rb +33 -0
  55. data/app/models/concerns/headmin/form/listable.rb +28 -0
  56. data/app/models/concerns/headmin/form/placeholderable.rb +13 -0
  57. data/app/models/concerns/headmin/form/validatable.rb +40 -0
  58. data/app/models/concerns/headmin/form/wrappable.rb +21 -0
  59. data/app/models/headmin/.DS_Store +0 -0
  60. data/app/models/headmin/blocks_view.rb +15 -0
  61. data/app/models/headmin/form/blocks_view.rb +29 -0
  62. data/app/models/headmin/form/checkbox_view.rb +52 -0
  63. data/app/models/headmin/form/date_range_view.rb +25 -0
  64. data/app/models/headmin/form/date_view.rb +45 -0
  65. data/app/models/headmin/form/email_view.rb +48 -0
  66. data/app/models/headmin/form/file_view.rb +116 -0
  67. data/app/models/headmin/form/flatpickr_range_view.rb +102 -0
  68. data/app/models/headmin/form/flatpickr_view.rb +37 -0
  69. data/app/models/headmin/form/hidden_view.rb +10 -0
  70. data/app/models/headmin/form/hint_view.rb +6 -0
  71. data/app/models/headmin/form/input_group_view.rb +19 -0
  72. data/app/models/headmin/form/label_view.rb +24 -0
  73. data/app/models/headmin/form/number_view.rb +49 -0
  74. data/app/models/headmin/form/password_view.rb +44 -0
  75. data/app/models/headmin/form/redactorx_view.rb +59 -0
  76. data/app/models/headmin/form/search_view.rb +48 -0
  77. data/app/models/headmin/form/select_view.rb +62 -0
  78. data/app/models/headmin/form/switch_view.rb +23 -0
  79. data/app/models/headmin/form/text_view.rb +48 -0
  80. data/app/models/headmin/form/textarea_view.rb +44 -0
  81. data/app/models/headmin/form/url_view.rb +48 -0
  82. data/app/models/headmin/form/wrapper_view.rb +19 -0
  83. data/app/models/headmin/form/wysiwyg_view.rb +17 -0
  84. data/app/models/headmin/{thumbnail.rb → thumbnail_view.rb} +6 -1
  85. data/app/models/view_model.rb +58 -0
  86. data/app/views/headmin/_blocks.html.erb +13 -9
  87. data/app/views/headmin/_heading.html.erb +7 -1
  88. data/app/views/headmin/_thumbnail.html.erb +1 -37
  89. data/app/views/headmin/forms/_autocomplete.html.erb +11 -0
  90. data/app/views/headmin/forms/_blocks.html.erb +16 -17
  91. data/app/views/headmin/forms/_checkbox.html.erb +24 -29
  92. data/app/views/headmin/forms/_datalist.html.erb +3 -0
  93. data/app/views/headmin/forms/_date.html.erb +24 -24
  94. data/app/views/headmin/forms/_date_range.html.erb +19 -21
  95. data/app/views/headmin/forms/_email.html.erb +27 -32
  96. data/app/views/headmin/forms/_errors.html.erb +2 -3
  97. data/app/views/headmin/forms/_file.html.erb +84 -181
  98. data/app/views/headmin/forms/_flatpickr.html.erb +19 -20
  99. data/app/views/headmin/forms/_flatpickr_range.html.erb +28 -37
  100. data/app/views/headmin/forms/_hidden.html.erb +9 -10
  101. data/app/views/headmin/forms/_hint.html.erb +16 -0
  102. data/app/views/headmin/forms/_input_group.html.erb +21 -0
  103. data/app/views/headmin/forms/_label.html.erb +5 -13
  104. data/app/views/headmin/forms/_number.html.erb +23 -35
  105. data/app/views/headmin/forms/_password.html.erb +21 -30
  106. data/app/views/headmin/forms/_redactorx.html.erb +21 -40
  107. data/app/views/headmin/forms/_repeater.html.erb +55 -60
  108. data/app/views/headmin/forms/_search.html.erb +43 -0
  109. data/app/views/headmin/forms/_select.html.erb +24 -49
  110. data/app/views/headmin/forms/_switch.html.erb +29 -0
  111. data/app/views/headmin/forms/_text.html.erb +42 -96
  112. data/app/views/headmin/forms/_textarea.html.erb +21 -32
  113. data/app/views/headmin/forms/_url.html.erb +26 -31
  114. data/app/views/headmin/forms/_validation.html.erb +10 -13
  115. data/app/views/headmin/forms/_wrapper.html.erb +9 -0
  116. data/app/views/headmin/forms/_wysiwyg.html.erb +28 -0
  117. data/app/views/headmin/forms/autocomplete/_item.html.erb +3 -0
  118. data/app/views/headmin/forms/autocomplete/_list.html.erb +3 -0
  119. data/app/views/headmin/forms/fields/_file.html.erb +1 -1
  120. data/app/views/headmin/forms/fields/_files.html.erb +17 -0
  121. data/app/views/headmin/forms/fields/_group.html.erb +9 -2
  122. data/app/views/headmin/forms/repeater/_row.html.erb +4 -4
  123. data/bin/console +0 -1
  124. data/config/locales/headmin/forms/en.yml +1 -12
  125. data/config/locales/headmin/forms/nl.yml +1 -12
  126. data/esbuild-css.js +18 -18
  127. data/esbuild-js.js +8 -8
  128. data/headmin.gemspec +1 -3
  129. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +0 -2
  130. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +0 -2
  131. data/lib/generators/templates/controllers/auth/passwords_controller.rb +0 -2
  132. data/lib/generators/templates/controllers/auth/registrations_controller.rb +0 -2
  133. data/lib/generators/templates/controllers/auth/sessions_controller.rb +0 -2
  134. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +0 -2
  135. data/lib/headmin/version.rb +1 -3
  136. data/lib/headmin.rb +0 -2
  137. data/package-lock.json +5359 -0
  138. data/package.json +12 -4
  139. data/view_model_benchmark.rb +74 -0
  140. data/yarn-error.log +17 -12
  141. data/yarn.lock +1575 -31
  142. metadata +64 -25
  143. data/app/assets/stylesheets/headmin/form.scss +0 -132
  144. data/app/assets/stylesheets/headmin/overrides/redactorx.css +0 -3
  145. data/app/helpers/headmin/documentation_helper.rb +0 -35
  146. data/app/models/headmin/documentation_renderer.rb +0 -32
  147. data/app/models/headmin/form/base.rb +0 -78
  148. data/app/models/headmin/form/text.rb +0 -51
  149. data/app/services/block_service.rb +0 -72
  150. data/app/views/headmin/_card.html.erb +0 -52
  151. data/app/views/headmin/forms/_actions.html.erb +0 -28
  152. data/app/views/headmin/forms/_base.html.erb +0 -114
  153. data/app/views/headmin/forms/_image.html.erb +0 -21
  154. data/app/views/headmin/forms/_video.html.erb +0 -21
  155. data/app/views/headmin/forms/actions/_destroy.html.erb +0 -13
  156. data/app/views/headmin/forms/actions/_save.html.erb +0 -12
  157. data/app/views/headmin/forms/actions/_view.html.erb +0 -15
  158. data/app/views/headmin/forms/fields/_image.html.erb +0 -17
  159. data/docs/blocks-and-fields.md +0 -54
  160. data/docs/blocks.md +0 -48
  161. data/docs/devise.md +0 -41
  162. data/docs/fields.md +0 -79
@@ -0,0 +1,48 @@
1
+ module Headmin
2
+ module Form
3
+ class UrlView < ViewModel
4
+ include Headmin::Form::Autocompletable
5
+ include Headmin::Form::Hintable
6
+ include Headmin::Form::InputGroupable
7
+ include Headmin::Form::Labelable
8
+ include Headmin::Form::Listable
9
+ include Headmin::Form::Placeholderable
10
+ include Headmin::Form::Validatable
11
+ include Headmin::Form::Wrappable
12
+
13
+ def input_options
14
+ keys = attributes - %i[append attribute collection float form input_group label prepend validate wrapper]
15
+ options = to_h.slice(*keys)
16
+ options = default_input_options.deep_merge(options)
17
+ options.deep_merge(autocomplete_input_options)
18
+ end
19
+
20
+ def input_group_options
21
+ default_input_group_options
22
+ .deep_merge(autocomplete_input_group_options)
23
+ .deep_merge(label_input_group_options)
24
+ .deep_merge(@input_group || {})
25
+ end
26
+
27
+ def wrapper_options
28
+ default_wrapper_options.deep_merge({
29
+ class: ["mb-3", ("form-floating" if float)]
30
+ }).deep_merge(@wrapper || {})
31
+ end
32
+
33
+ private
34
+
35
+ def default_input_options
36
+ {
37
+ aria: {describedby: validation_id},
38
+ class: [form_control_class, validation_class],
39
+ placeholder: placeholder
40
+ }
41
+ end
42
+
43
+ def form_control_class
44
+ plaintext ? "form-control-plaintext" : "form-control"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module Headmin
2
+ module Form
3
+ class WrapperView < ViewModel
4
+ def options
5
+ keys = attributes - %i[bypass]
6
+ options = to_h.slice(*keys)
7
+ default_options.deep_merge(options)
8
+ end
9
+
10
+ private
11
+
12
+ def default_options
13
+ {
14
+ class: ["mb-3"]
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module Headmin
2
+ module Form
3
+ class WysiwygView < ViewModel
4
+ def options
5
+ default_options.deep_merge(to_h)
6
+ end
7
+
8
+ private
9
+
10
+ def default_options
11
+ {
12
+ hybrid: toolbar == false
13
+ }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  module Headmin
2
- class Thumbnail
2
+ class ThumbnailView
3
3
  def initialize(local_assigns)
4
4
  @local_assigns = local_assigns
5
5
  end
@@ -22,6 +22,10 @@ module Headmin
22
22
  @local_assigns[:src]
23
23
  end
24
24
 
25
+ def icon
26
+ @local_assigns[:icon]
27
+ end
28
+
25
29
  def mime_type
26
30
  if src
27
31
  stripped_path = URI.parse(src).path
@@ -36,6 +40,7 @@ module Headmin
36
40
 
37
41
  # https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
38
42
  def icon_name
43
+ return icon if icon
39
44
  type_map = {
40
45
  image: %w[image/bmp image/gif image/vnd.microsoft.icon image/jpeg image/png image/svg+xml image/tiff image/webp],
41
46
  play: %w[video/mp4 video/mpeg video/ogg video/mp2t video/webm video/3gpp video/3gpp2],
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ViewModel
4
+ # = View Model
5
+ #
6
+ # A View Model is a class that allows you to set an arbitrary hash of attributes and access all values by calling
7
+ # attribute methods.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # model = ViewModel.new(a: 1, b: {b1: 1, b2: 2}, c: 3)
12
+ #
13
+ # model.a # => 1
14
+ # model.b # => {b1: 1, b2: 2}
15
+ # model.c # => 3
16
+ #
17
+ # Reserved methods or attributes are left untouched. If you want to access an attribute that collides with a reserved
18
+ # method, you can do it via the +to_hash+ method.
19
+ #
20
+ # model = ViewModel.new(class: "test")
21
+ #
22
+ # model.class # => ViewModel
23
+ # model.to_hash[:class] # => "test"
24
+
25
+ def initialize(hash = {})
26
+ hash.each do |key, value|
27
+ instance_variable_set("@#{key}", value)
28
+ end
29
+ end
30
+
31
+ def attributes
32
+ instance_variables.map { |instance_variable| instance_variable.to_s.delete("@").to_sym }
33
+ end
34
+
35
+ def to_hash
36
+ attributes.map { |attribute| {attribute => value_for(attribute)} }.inject(:merge)
37
+ end
38
+
39
+ alias_method :to_h, :to_hash
40
+
41
+ private
42
+
43
+ def value_for(attribute)
44
+ reserved_methods.include?(attribute) ? instance_variable_get("@#{attribute}") : send(attribute)
45
+ end
46
+
47
+ def method_missing(m, *args, &block)
48
+ instance_variable_get("@#{m}")
49
+ end
50
+
51
+ def respond_to_missing?
52
+ true
53
+ end
54
+
55
+ def reserved_methods
56
+ Class.methods + Class.private_methods
57
+ end
58
+ end
@@ -1,24 +1,28 @@
1
1
  <%
2
2
  # headmin/blocks
3
3
  #
4
- # ==== Options
4
+ # ==== Required parameters
5
5
  # * +blockable</tt> - Object with blocks association
6
- # * +path</tt> - Directory where to look for block templates
6
+ #
7
+ # ==== Optional parameters
8
+ # * +paths</tt> - Directories where to look for block templates
7
9
  #
8
10
  # ==== Examples
9
- # Basic version. This will only look for blocks in 'website/blocks'
11
+ # Basic version. (looks in views/website/blocks, views/blocks or views directory )
10
12
  # <%= render "headmin/blocks", blockable: @page %#>
11
13
  #
12
- # Define the path to look for block templates like this:
13
- # <%= render "headmin/blocks", blockable: @page, path: 'website/pages/blocks' %#>
14
+ # Define one ore more path where the templates could be located:
15
+ # <%= render "headmin/blocks", blockable: @page, paths: %w(website/pages/blocks) %#>
14
16
 
15
- blockable = local_assigns.has_key?(:blockable) ? blockable : nil
16
- path = local_assigns.has_key?(:path) ? path : nil
17
+ blocks = Headmin::BlocksView.new(local_assigns)
18
+ @lookup_context.prefixes = @lookup_context.prefixes + blocks.prefixes
17
19
  %>
18
20
 
19
21
  <% if blockable && blockable.respond_to?(:blocks) %>
20
22
  <% blockable.blocks.order(:position).each do |block| %>
21
- <% view_path = BlockService.frontend_view(block.name, path: path).gsub('/_', '/').split('.').first %>
22
- <%= render view_path, block: block %>
23
+
24
+ <!-- <%= block.name %> -->
25
+ <%= render block.name, block: block %>
26
+
23
27
  <% end %>
24
28
  <% end %>
@@ -1,10 +1,16 @@
1
1
  <%
2
2
  # headmin/heading
3
3
  #
4
+ # Accepts a block
5
+ #
6
+ # ==== References
7
+ # https://headmin.dev/docs/heading
8
+ # https://headmin.dev/preview/heading
9
+ #
4
10
  # ==== Examples
5
11
  # Basic version
6
12
  # <%= render "headmin/heading" do %#>
7
- # Your content
13
+ # Title
8
14
  # <% end %#>
9
15
  %>
10
16
 
@@ -1,40 +1,4 @@
1
- <!--
2
- <% documentation do %>
3
- # Thumbnail
4
- Render thumbnails for files. Whenever possible (e.g. images) previews are generated. Icons are used instead for other file types.
5
-
6
- ```erbx
7
- <%= render 'headmin/thumbnail', src: image_path("image.jpg") %>
8
- ```
9
-
10
- ## Parameters
11
- | Name | Required | Type | Description |
12
- | ------------ | -------- | ---------------- | ----------- |
13
- | src | yes | String | Source of the file. Can be a local or external URL |
14
- | width | no | Integer | Width of the thumbnail in px |
15
- | height | no | Integer | Height of the thumbnail in px |
16
-
17
- ## Examples
18
-
19
- ### Sizing
20
- ```erbx
21
- <%= render 'headmin/thumbnail', src: image_path("image.jpg"), width: 300, height: 100 %>
22
- ```
23
-
24
- ### Types
25
- ```erbx
26
- <%= render 'headmin/thumbnail', src: asset_path("document.pdf"), width: 100, height: 100 %>
27
- <%= render 'headmin/thumbnail', src: asset_path("document.docx"), width: 100, height: 100 %>
28
- <%= render 'headmin/thumbnail', src: asset_path("spreadsheet.xls"), width: 100, height: 100 %>
29
- <%= render 'headmin/thumbnail', src: asset_path("video.mp4"), width: 100, height: 100 %>
30
- ```
31
-
32
- ## References
33
- - [Bootstrap](https://getbootstrap.com/docs/5.1/content/images/#image-thumbnails)
34
- <% end %>
35
- -->
36
-
37
- <% thumbnail = Headmin::Thumbnail.new(local_assigns) %>
1
+ <% thumbnail = Headmin::ThumbnailView.new(local_assigns) %>
38
2
 
39
3
  <div class="<%= thumbnail.class_names %>" style="width: <%= thumbnail.width %>px; height: <%= thumbnail.height %>px;">
40
4
  <% if thumbnail.image? %>
@@ -0,0 +1,11 @@
1
+ <div class="h-autocomplete d-none" data-autocomplete-target="dropdown">
2
+ <% if collection.any? %>
3
+ <%= render "headmin/forms/autocomplete/list" do %>
4
+ <% collection.each do |value, name| %>
5
+ <%= render "headmin/forms/autocomplete/item", value: value do %>
6
+ <%= name %>
7
+ <% end %>
8
+ <% end %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
@@ -1,39 +1,38 @@
1
1
  <%
2
2
  # headmin/forms/blocks
3
3
  #
4
- # ==== Options
4
+ # ==== Required parameters
5
5
  # * +form</tt> - Form object
6
- # * +path</tt> - Directory where to look for block templates
7
- # * +allow</tt> - Names of block templates that can be added
6
+ # * +names</tt> - Names of block templates that can be added
7
+ #
8
+ # ==== Optional parameters
9
+ # * +paths</tt> - Directories where to look for block templates
8
10
  #
9
11
  # ==== Examples
10
- # Basic version. This will only look for blocks in 'admin/blocks'
11
- # <%= render "headmin/forms/blocks", form: form %#>
12
+ # Basic version. (looks in views/admin/blocks, views/blocks or views directory )
13
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text image button) %#>
12
14
  #
13
- # Define the path to look for block templates like this:
14
- # <%= render "headmin/forms/blocks", form: form, path: 'admin/pages/blocks' %#>
15
+ # Define one ore more path where the templates could be located:
16
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text image button), paths: %w(admin/pages/blocks) %#>
15
17
  #
16
18
  # Limit the types of blocks
17
- # <%= render "headmin/forms/blocks", form: form, allow: ['text', 'text-image'] %#>
18
-
19
- path = local_assigns.has_key?(:path) ? path : nil
20
- allowed_block_names = local_assigns.has_key?(:allow) ? allow.map(&:to_s) : BlockService.block_names(path: path)
19
+ # <%= render "headmin/forms/blocks", form: form, names: %w(text text_image list) %#>
21
20
 
22
- templates = allowed_block_names.map { |name| BlockService.form_view(name, path: path) }
21
+ blocks = Headmin::Form::BlocksView.new(local_assigns)
22
+ @lookup_context.prefixes = @lookup_context.prefixes + blocks.prefixes
23
23
  %>
24
24
 
25
- <%= render 'headmin/forms/repeater', form: form, attribute: :blocks, templates: templates, label: false do |block_form, template| %>
26
- <% name = template ? BlockService.view_name(template) : block_form.object.name %>
25
+ <%= render 'headmin/forms/repeater', blocks.repeater_options do |block_form, template| %>
26
+ <% name = template || block_form.object.name %>
27
27
 
28
28
  <!-- Name input of the block -->
29
29
  <%= block_form.hidden_field :name, value: name %>
30
30
 
31
31
  <!-- Render block form fields -->
32
- <% view_path = BlockService.form_view(name, path: path).gsub('/_', '/').split('.')[0] %>
33
- <%= render view_path, form: block_form %>
32
+ <%= render name, form: block_form %>
34
33
 
35
34
  <!-- Label -->
36
35
  <span class="position-absolute top-0 end-0 badge bg-light text-dark">
37
- <%= name.titleize %>
36
+ <%= t("blocks.#{name}", default: name).humanize %>
38
37
  </span>
39
38
  <% end %>
@@ -1,39 +1,34 @@
1
1
  <%
2
2
  # headmin/forms/checkbox
3
3
  #
4
- # ==== Options
5
- # * +form+ - Form object
4
+ # ==== Required parameters
6
5
  # * +attribute+ - Name of the attribute of the form model
7
- # * +label+ - Text to show as label. Label will be hidden if value is false
6
+ # * +form+ - Form object
7
+ #
8
+ # ==== Optional parameters
9
+ # * +checked_value+ - Value for checked state
10
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
11
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
12
+ # * +unchecked_value+ - Value for unchecked state
13
+ # * +wrapper+ - Hash with all options for the surrounding html tag
14
+ #
15
+ # ==== References
16
+ # https://headmin.dev/docs/forms/checkbox
17
+ # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox
18
+ # https://apidock.com/rails/ActionView/Helpers/FormHelper/check_box
8
19
  #
9
20
  # ==== Examples
10
21
  # Basic version
11
- # <%= render 'headmin/forms/image', form: form, attribute: :image %#>
12
-
13
- class_names = local_assigns.has_key?(:class) ? local_assigns[:class] : false
14
- data = local_assigns.has_key?(:data) ? data : nil
15
- disabled = local_assigns.has_key?(:disabled) ? disabled : false
16
- label = local_assigns.has_key?(:label) ? label : nil
17
- readonly = local_assigns.has_key?(:readonly) ? readonly : false
18
- required = local_assigns.has_key?(:required) ? required : false
19
-
20
- options = {
21
- 'aria-describedby': form_field_validation_id(form, attribute),
22
- class: "form-checkbox-input #{form_field_validation_class(form, attribute)} #{class_names}",
23
- data: data,
24
- disabled: disabled,
25
- placeholder: attribute,
26
- readonly: readonly,
27
- required: required,
28
- }
22
+ # <%= form_with do |form| %#>
23
+ # <%= render "headmin/forms/checkbox", form: form, attribute: :active %#>
24
+ # <% end %#>
29
25
 
30
- show_label = label != false
26
+ checkbox = Headmin::Form::CheckboxView.new(local_assigns)
31
27
  %>
32
28
 
33
- <div class="<%= ('mb-3 text-start' if show_label) %>">
34
- <%= form.check_box(attribute, options) %>
35
- <% if show_label %>
36
- <%= render 'headmin/forms/label', form: form, attribute: attribute, text: label, required: required %>
37
- <% end %>
38
- <%= render 'headmin/forms/validation', form: form, attribute: attribute %>
39
- </div>
29
+ <%= render "headmin/forms/wrapper", checkbox.wrapper_options do %>
30
+ <%= form.check_box(checkbox.attribute, checkbox.input_options, checkbox.checked_value, checkbox.unchecked_value) %>
31
+ <%= render "headmin/forms/label", checkbox.label_options if checkbox.label? %>
32
+ <%= render "headmin/forms/validation", checkbox.validation_options if checkbox.validate? %>
33
+ <%= render "headmin/forms/hint", checkbox.hint_options if checkbox.hint? %>
34
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <datalist id="<%= id %>">
2
+ <%= options_for_select(collection) %>
3
+ </datalist>
@@ -2,40 +2,40 @@
2
2
  # headmin/forms/date
3
3
  #
4
4
  # ==== Required parameters
5
- # * +form+ - Form object
6
5
  # * +attribute+ - Name of the attribute of the form model
6
+ # * +form+ - Form object
7
7
  #
8
8
  # ==== Optional parameters
9
- # * +aria+ - Provide a hash to define all aria attributes
10
- # * +autocomplete+ - Value to be autofilled by the browser
11
- # * +autofocus+ - Set to true to focus on this field when the page renders
12
- # * +data+ - Optional HTML data attributes
13
- # * +disabled+ - Set to true if the input should be shown as disabled
14
- # * +id+ - Input identifier
15
- # * +list+ - Add array of options to show in a data list
16
- # * +readonly+ - Set to true if the value of the field can only be read and not be modified
17
- # * +required+ - Set to true to mark as required
18
- # * +step+ - The acceptable value granularity
19
- # * +value+ - Overrides the value of the form
20
- #
21
- # ==== Extra parameters
22
- # Listed in 'headmin/forms/base'
9
+ # * +append+ - Display as input group with text on the right-hand side
10
+ # * +float+ - Use floating labels. Defaults to false
11
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
12
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
13
+ # * +list+ - Options are passed through options_for_select
14
+ # * +plaintext+ - Render input as plain text.
15
+ # * +prepend+ - Display as input group with text on the left-hand side
16
+ # * +wrapper+ - Hash with all options for the surrounding html tag
23
17
  #
24
18
  # ==== References
19
+ # https://headmin.dev/docs/forms/date
25
20
  # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date
26
21
  # https://apidock.com/rails/ActionView/Helpers/FormHelper/date_field
27
22
  #
28
23
  # ==== Examples
29
24
  # Basic version
30
- # <%= render 'headmin/forms/date', form: form, attribute: :date %#>
25
+ # <%= form_with do |form| %#>
26
+ # <%= render "headmin/forms/date", form: form, attribute: :date_of_birth %#>
27
+ # <% end %#>
31
28
 
32
- option_keys = %i(aria autocomplete autofocus data disabled id list readonly required step value)
33
- options = local_assigns.slice(*option_keys).merge(
34
- aria: { describedby: form_field_validation_id(form, attribute) },
35
- class: ['form-control', form_field_validation_class(form, attribute)].join(' '),
36
- )
29
+ date = Headmin::Form::DateView.new(local_assigns)
37
30
  %>
38
31
 
39
- <%= render 'headmin/forms/base', local_assigns do |form| %>
40
- <%= form.date_field(attribute, options) %>
41
- <% end %>
32
+ <%= render "headmin/forms/wrapper", date.wrapper_options do %>
33
+ <%= render "headmin/forms/label", date.label_options if date.prepend_label? %>
34
+ <%= render "headmin/forms/input_group", date.input_group_options do %>
35
+ <%= form.date_field(date.attribute, date.input_options) %>
36
+ <%= render "headmin/forms/datalist", date.datalist_options if date.datalist? %>
37
+ <% end %>
38
+ <%= render "headmin/forms/validation", date.validation_options if date.validate? %>
39
+ <%= render "headmin/forms/hint", date.hint_options if date.hint? %>
40
+ <%= render "headmin/forms/label", date.label_options if date.append_label? %>
41
+ <% end %>
@@ -3,40 +3,38 @@
3
3
  #
4
4
  # ==== Required parameters
5
5
  # * +form+ - Form object
6
- # * +start_attribute+ - Name of the start date attribute of the form model
7
- # * +end_attribute+ - Name of the end date attribute of the form model
6
+ # * +start+ - Hash with all options for the start date input (:attribute is required)
7
+ # * +end+ - Hash with all options for the end date input (:attribute is required)
8
8
  #
9
9
  # ==== Optional parameters
10
- # * +end_label+ - Label for the end attribute
11
- # * +start_label+ - Label for the start attribute
10
+ # * +append+ - Display as input group with text on the right-hand side
11
+ # * +float+ - Use floating labels. Defaults to false
12
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
13
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
14
+ # * +plaintext+ - Render input as plain text.
15
+ # * +prepend+ - Display as input group with text on the left-hand side
16
+ # * +wrapper+ - Hash with all options for the surrounding html tag
12
17
  #
13
- # ==== Extra parameters
14
- # Listed in 'headmin/forms/date'
15
- # Listed in 'headmin/forms/base'
18
+ # ==== References
19
+ # https://headmin.dev/docs/forms/date_range
20
+ # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/date
21
+ # https://apidock.com/rails/ActionView/Helpers/FormHelper/date_field
16
22
  #
17
23
  # ==== Examples
18
24
  # Basic version
19
- # <%= render 'headmin/forms/date_range', form: form, start_attribute: :start_date, end_attribute: :end_date %#>
20
- #
21
- # With custom labels
22
- # <%= render 'headmin/forms/date_range', form: form, start_attribute: :start_date_2, start_label: :start_date, end_attribute: :end_date_2, end_label: :end_date %#>
25
+ # <%= form_with do |form| %#>
26
+ # <%= render 'headmin/forms/date_range', form: form, start: {attribute: :start_date}, end: {attribute: :end_date} %#>
27
+ # <% end %#>
23
28
 
24
- start_date_options = local_assigns.merge(
25
- attribute: local_assigns[:start_attribute],
26
- label: local_assigns[:start_label]
27
- )
28
- end_date_options = local_assigns.merge(
29
- attribute: local_assigns[:end_attribute],
30
- label: local_assigns[:end_label]
31
- )
29
+ date_range = Headmin::Form::DateRangeView.new(local_assigns)
32
30
  %>
33
31
 
34
32
  <div class="row">
35
33
  <div class="col">
36
- <%= render 'headmin/forms/date', start_date_options %>
34
+ <%= render 'headmin/forms/date', date_range.start_options %>
37
35
  </div>
38
36
  <div class="col">
39
- <%= render 'headmin/forms/date', end_date_options %>
37
+ <%= render 'headmin/forms/date', date_range.end_options %>
40
38
  </div>
41
39
  </div>
42
40
 
@@ -2,47 +2,42 @@
2
2
  # headmin/forms/email
3
3
  #
4
4
  # ==== Required parameters
5
- # * +form+ - Form object
6
5
  # * +attribute+ - Name of the attribute of the form model
6
+ # * +form+ - Form object
7
7
  #
8
8
  # ==== Optional parameters
9
- # * +aria+ - Provide a hash to define all aria attributes
10
- # * +autocomplete+ - Value to be autofilled by the browser
11
- # * +data+ - Provide a hash to define all data attributes
12
- # * +disabled+ - Sets the placeholder of the field
13
- # * +id+ - Input identifier
14
- # * +list+ - Add array of options to show in a data list
15
- # * +maxlength+ - Maximum amount of characters to be used
16
- # * +minlength+ - Minimum amount of characters to be used
17
- # * +multiple+ - Allow multiple comma-separated email addresses to be entered
18
- # * +pattern+ -a A regular expression that the input's value must match
19
- # * +placeholder+ - Sets the placeholder of the field
20
- # * +readonly+ - Sets the placeholder of the field
21
- # * +required+ - Set to true to mark as required
22
- # * +size+ - How much of the input should be shown
23
- # * +value+ - Overrides the value of the form
24
- #
25
- # ==== Extra parameters
26
- # Listed in 'headmin/forms/base'
9
+ # * +append+ - Display as input group with text on the right-hand side
10
+ # * +collection+ - Values to be suggested while typing. Can be an collection array or a remote URL.
11
+ # * +float+ - Use floating labels. Defaults to false
12
+ # * +hint+ - Informative text to assist with data input. HTML markup is allowed.
13
+ # * +label+ - Text to display inside label tag. Defaults to the attribute name. Set to false if you don"t want to show a label.
14
+ # * +list+ - Options are passed through options_for_select
15
+ # * +plaintext+ - Render input as plain text.
16
+ # * +prepend+ - Display as input group with text on the left-hand side
17
+ # * +wrapper+ - Hash with all options for the surrounding html tag
27
18
  #
28
19
  # ==== References
29
- # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text
30
- # https://apidock.com/rails/ActionView/Helpers/FormHelper/text_field
20
+ # https://headmin.dev/docs/forms/email
21
+ # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email
22
+ # https://apidock.com/rails/ActionView/Helpers/FormHelper/email_field
31
23
  #
32
24
  # ==== Examples
33
25
  # Basic version
34
- # <%= render 'headmin/forms/email', form: form, attribute: :email_address %#>
35
-
36
- placeholder = local_assigns[:float] ? local_assigns[:placeholder] || attribute : local_assigns[:placeholder]
26
+ # <%= form_with do |form| %#>
27
+ # <%= render "headmin/forms/email", form: form, attribute: :email_address %#>
28
+ # <% end %#>
37
29
 
38
- option_keys = %i(aria autocomplete data disabled id maxlenght minlength multiple pattern placeholder readonly required size value)
39
- options = local_assigns.slice(*option_keys).merge(
40
- aria: { describedby: form_field_validation_id(form, attribute) },
41
- class: ['form-control', form_field_validation_class(form, attribute)].join(' '),
42
- placeholder: placeholder
43
- )
30
+ email = Headmin::Form::EmailView.new(local_assigns)
44
31
  %>
45
32
 
46
- <%= render 'headmin/forms/base', local_assigns do |form| %>
47
- <%= form.email_field(attribute, options) %>
33
+ <%= render "headmin/forms/wrapper", email.wrapper_options do %>
34
+ <%= render "headmin/forms/label", email.label_options if email.prepend_label? %>
35
+ <%= render "headmin/forms/input_group", email.input_group_options do %>
36
+ <%= form.email_field(email.attribute, email.input_options) %>
37
+ <%= render "headmin/forms/datalist", email.datalist_options if email.datalist? %>
38
+ <%= render "headmin/forms/autocomplete", email.autocomplete_options if email.autocomplete? %>
39
+ <% end %>
40
+ <%= render "headmin/forms/validation", email.validation_options if email.validate? %>
41
+ <%= render "headmin/forms/hint", email.hint_options if email.hint? %>
42
+ <%= render "headmin/forms/label", email.label_options if email.append_label? %>
48
43
  <% end %>
@@ -8,12 +8,11 @@
8
8
  <% if form.object.errors.any? %>
9
9
  <div class="alert alert-danger" role="alert">
10
10
  <h5 class="alert-heading d-flex align-items-center">
11
- <%= bootstrap_icon('exclamation-triangle-fill', class: 'me-2') %>
12
11
  <%= t('errors.template.header', count: form.object.errors.size, model: form.object.model_name.human) %>
13
12
  </h5>
14
- <ul>
13
+ <ul class="mb-0">
15
14
  <% form.object.errors.full_messages.each do |message| %>
16
- <li><%= message %></li>
15
+ <li><%= message %></li>
17
16
  <% end %>
18
17
  </ul>
19
18
  </div>