headmin 0.3.4 → 0.4.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.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +27 -0
  3. data/.gitignore +14 -0
  4. data/.nvmrc +1 -0
  5. data/CHANGELOG.md +24 -0
  6. data/Gemfile +7 -4
  7. data/Gemfile.lock +171 -3
  8. data/README.md +7 -0
  9. data/Rakefile +1 -7
  10. data/app/assets/javascripts/headmin/config/i18n.js +9 -9
  11. data/app/assets/javascripts/headmin/controllers/autocomplete_controller.js +255 -0
  12. data/app/assets/javascripts/headmin/controllers/blocks_controller.js +74 -79
  13. data/app/assets/javascripts/headmin/controllers/date_range_controller.js +24 -24
  14. data/app/assets/javascripts/headmin/controllers/dropzone_controller.js +23 -25
  15. data/app/assets/javascripts/headmin/controllers/file_preview_controller.js +237 -237
  16. data/app/assets/javascripts/headmin/controllers/filter_controller.js +44 -44
  17. data/app/assets/javascripts/headmin/controllers/filters_controller.js +57 -61
  18. data/app/assets/javascripts/headmin/controllers/flatpickr_controller.js +29 -29
  19. data/app/assets/javascripts/headmin/controllers/hello_controller.js +3 -3
  20. data/app/assets/javascripts/headmin/controllers/notification_controller.js +7 -6
  21. data/app/assets/javascripts/headmin/controllers/popup_controller.js +51 -52
  22. data/app/assets/javascripts/headmin/controllers/redactorx_controller.js +36 -9
  23. data/app/assets/javascripts/headmin/controllers/repeater_controller.js +122 -125
  24. data/app/assets/javascripts/headmin/controllers/select_controller.js +40 -39
  25. data/app/assets/javascripts/headmin/controllers/table_actions_controller.js +100 -101
  26. data/app/assets/javascripts/headmin/controllers/table_controller.js +115 -115
  27. data/app/assets/javascripts/headmin/index.js +38 -35
  28. data/app/assets/javascripts/headmin.js +243 -34
  29. data/app/assets/stylesheets/headmin/forms/autocomplete.scss +21 -0
  30. data/app/assets/stylesheets/headmin/forms/file.scss +46 -0
  31. data/app/assets/stylesheets/headmin/forms/repeater.scss +62 -0
  32. data/app/assets/stylesheets/headmin/forms/search.scss +12 -0
  33. data/app/assets/stylesheets/headmin/forms.scss +11 -0
  34. data/app/assets/stylesheets/headmin/general.scss +5 -0
  35. data/app/assets/stylesheets/headmin/overrides/bootstrap.scss +5 -3
  36. data/app/assets/stylesheets/headmin/overrides/redactorx.scss +74 -0
  37. data/app/assets/stylesheets/headmin/popup.scss +1 -0
  38. data/app/assets/stylesheets/headmin/syntax.scss +36 -349
  39. data/app/assets/stylesheets/headmin/table.scss +1 -1
  40. data/app/assets/stylesheets/headmin/utilities/buttons.scss +19 -0
  41. data/app/assets/stylesheets/headmin/utilities/dropzone.scss +72 -0
  42. data/app/assets/stylesheets/headmin/utilities.scss +2 -68
  43. data/app/assets/stylesheets/headmin.css +205 -205
  44. data/app/assets/stylesheets/headmin.scss +1 -1
  45. data/app/helpers/headmin/admin_helper.rb +0 -1
  46. data/app/helpers/headmin/form_helper.rb +2 -8
  47. data/app/models/concerns/headmin/blockable.rb +1 -1
  48. data/app/models/concerns/headmin/field.rb +1 -0
  49. data/app/models/concerns/headmin/form/autocompletable.rb +38 -0
  50. data/app/models/concerns/headmin/form/hintable.rb +19 -0
  51. data/app/models/concerns/headmin/form/input_groupable.rb +23 -0
  52. data/app/models/concerns/headmin/form/labelable.rb +33 -0
  53. data/app/models/concerns/headmin/form/listable.rb +28 -0
  54. data/app/models/concerns/headmin/form/placeholderable.rb +13 -0
  55. data/app/models/concerns/headmin/form/validatable.rb +40 -0
  56. data/app/models/concerns/headmin/form/wrappable.rb +21 -0
  57. data/app/models/headmin/.DS_Store +0 -0
  58. data/app/models/headmin/blocks_view.rb +15 -0
  59. data/app/models/headmin/form/blocks_view.rb +29 -0
  60. data/app/models/headmin/form/checkbox_view.rb +52 -0
  61. data/app/models/headmin/form/date_range_view.rb +25 -0
  62. data/app/models/headmin/form/date_view.rb +45 -0
  63. data/app/models/headmin/form/email_view.rb +48 -0
  64. data/app/models/headmin/form/file_view.rb +116 -0
  65. data/app/models/headmin/form/flatpickr_range_view.rb +102 -0
  66. data/app/models/headmin/form/flatpickr_view.rb +37 -0
  67. data/app/models/headmin/form/hidden_view.rb +10 -0
  68. data/app/models/headmin/form/hint_view.rb +6 -0
  69. data/app/models/headmin/form/input_group_view.rb +19 -0
  70. data/app/models/headmin/form/label_view.rb +24 -0
  71. data/app/models/headmin/form/number_view.rb +49 -0
  72. data/app/models/headmin/form/password_view.rb +44 -0
  73. data/app/models/headmin/form/redactorx_view.rb +59 -0
  74. data/app/models/headmin/form/search_view.rb +48 -0
  75. data/app/models/headmin/form/select_view.rb +62 -0
  76. data/app/models/headmin/form/switch_view.rb +23 -0
  77. data/app/models/headmin/form/text_view.rb +48 -0
  78. data/app/models/headmin/form/textarea_view.rb +44 -0
  79. data/app/models/headmin/form/url_view.rb +48 -0
  80. data/app/models/headmin/form/wrapper_view.rb +19 -0
  81. data/app/models/headmin/form/wysiwyg_view.rb +17 -0
  82. data/app/models/headmin/{thumbnail.rb → thumbnail_view.rb} +6 -1
  83. data/app/models/view_model.rb +58 -0
  84. data/app/views/headmin/_blocks.html.erb +13 -9
  85. data/app/views/headmin/_heading.html.erb +7 -1
  86. data/app/views/headmin/_thumbnail.html.erb +1 -37
  87. data/app/views/headmin/forms/_autocomplete.html.erb +11 -0
  88. data/app/views/headmin/forms/_blocks.html.erb +16 -17
  89. data/app/views/headmin/forms/_checkbox.html.erb +24 -29
  90. data/app/views/headmin/forms/_datalist.html.erb +3 -0
  91. data/app/views/headmin/forms/_date.html.erb +24 -24
  92. data/app/views/headmin/forms/_date_range.html.erb +19 -21
  93. data/app/views/headmin/forms/_email.html.erb +27 -32
  94. data/app/views/headmin/forms/_errors.html.erb +2 -3
  95. data/app/views/headmin/forms/_file.html.erb +84 -181
  96. data/app/views/headmin/forms/_flatpickr.html.erb +19 -20
  97. data/app/views/headmin/forms/_flatpickr_range.html.erb +28 -37
  98. data/app/views/headmin/forms/_hidden.html.erb +9 -10
  99. data/app/views/headmin/forms/_hint.html.erb +16 -0
  100. data/app/views/headmin/forms/_input_group.html.erb +21 -0
  101. data/app/views/headmin/forms/_label.html.erb +5 -13
  102. data/app/views/headmin/forms/_number.html.erb +23 -35
  103. data/app/views/headmin/forms/_password.html.erb +21 -30
  104. data/app/views/headmin/forms/_redactorx.html.erb +21 -40
  105. data/app/views/headmin/forms/_repeater.html.erb +55 -60
  106. data/app/views/headmin/forms/_search.html.erb +43 -0
  107. data/app/views/headmin/forms/_select.html.erb +24 -49
  108. data/app/views/headmin/forms/_switch.html.erb +29 -0
  109. data/app/views/headmin/forms/_text.html.erb +42 -96
  110. data/app/views/headmin/forms/_textarea.html.erb +21 -32
  111. data/app/views/headmin/forms/_url.html.erb +26 -31
  112. data/app/views/headmin/forms/_validation.html.erb +10 -13
  113. data/app/views/headmin/forms/_wrapper.html.erb +9 -0
  114. data/app/views/headmin/forms/_wysiwyg.html.erb +28 -0
  115. data/app/views/headmin/forms/autocomplete/_item.html.erb +3 -0
  116. data/app/views/headmin/forms/autocomplete/_list.html.erb +3 -0
  117. data/app/views/headmin/forms/fields/_group.html.erb +5 -3
  118. data/app/views/headmin/forms/repeater/_row.html.erb +4 -4
  119. data/bin/console +0 -1
  120. data/config/locales/headmin/forms/en.yml +0 -11
  121. data/config/locales/headmin/forms/nl.yml +0 -11
  122. data/esbuild-css.js +18 -18
  123. data/esbuild-js.js +8 -8
  124. data/headmin.gemspec +1 -3
  125. data/lib/generators/templates/controllers/auth/confirmations_controller.rb +0 -2
  126. data/lib/generators/templates/controllers/auth/omniauth_callbacks_controller.rb +0 -2
  127. data/lib/generators/templates/controllers/auth/passwords_controller.rb +0 -2
  128. data/lib/generators/templates/controllers/auth/registrations_controller.rb +0 -2
  129. data/lib/generators/templates/controllers/auth/sessions_controller.rb +0 -2
  130. data/lib/generators/templates/controllers/auth/unlocks_controller.rb +0 -2
  131. data/lib/headmin/version.rb +1 -3
  132. data/lib/headmin.rb +0 -2
  133. data/package-lock.json +5359 -0
  134. data/package.json +12 -4
  135. data/view_model_benchmark.rb +74 -0
  136. data/yarn-error.log +17 -12
  137. data/yarn.lock +1575 -31
  138. metadata +62 -24
  139. data/app/assets/stylesheets/headmin/form.scss +0 -132
  140. data/app/assets/stylesheets/headmin/overrides/redactorx.css +0 -3
  141. data/app/helpers/headmin/documentation_helper.rb +0 -35
  142. data/app/models/headmin/documentation_renderer.rb +0 -32
  143. data/app/models/headmin/form/base.rb +0 -78
  144. data/app/models/headmin/form/text.rb +0 -51
  145. data/app/services/block_service.rb +0 -72
  146. data/app/views/headmin/_card.html.erb +0 -52
  147. data/app/views/headmin/forms/_actions.html.erb +0 -28
  148. data/app/views/headmin/forms/_base.html.erb +0 -114
  149. data/app/views/headmin/forms/_image.html.erb +0 -21
  150. data/app/views/headmin/forms/_video.html.erb +0 -21
  151. data/app/views/headmin/forms/actions/_destroy.html.erb +0 -13
  152. data/app/views/headmin/forms/actions/_save.html.erb +0 -12
  153. data/app/views/headmin/forms/actions/_view.html.erb +0 -15
  154. data/docs/blocks-and-fields.md +0 -54
  155. data/docs/blocks.md +0 -48
  156. data/docs/devise.md +0 -41
  157. data/docs/fields.md +0 -79
@@ -0,0 +1,28 @@
1
+ module Headmin
2
+ module Form
3
+ module Listable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def list
8
+ datalist_id if @list
9
+ end
10
+
11
+ def datalist?
12
+ @list.present?
13
+ end
14
+
15
+ def datalist_options
16
+ {
17
+ collection: @list,
18
+ id: datalist_id
19
+ }
20
+ end
21
+
22
+ def datalist_id
23
+ "#{attribute}_list"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Headmin
2
+ module Form
3
+ module Placeholderable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def placeholder
8
+ float ? @placeholder || attribute : @placeholder
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,40 @@
1
+ module Headmin
2
+ module Form
3
+ module Validatable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def validation_options
8
+ {
9
+ id: validation_id,
10
+ message: validation_message,
11
+ valid: valid?
12
+ }
13
+ end
14
+
15
+ def validate?
16
+ form.object&.errors&.any?
17
+ end
18
+
19
+ private
20
+
21
+ def valid?
22
+ !form.object&.errors&.has_key?(attribute)
23
+ end
24
+
25
+ def validation_message
26
+ form.object&.errors&.full_messages_for(attribute)&.join(", ")
27
+ end
28
+
29
+ def validation_id
30
+ [attribute.to_s, "validation"].join("_").parameterize.underscore
31
+ end
32
+
33
+ def validation_class
34
+ return unless validate?
35
+ valid? ? "is-valid" : "is-invalid"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ module Headmin
2
+ module Form
3
+ module Wrappable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ def wrapper_options
8
+ default_wrapper_options.merge(@wrapper || {})
9
+ end
10
+
11
+ private
12
+
13
+ def default_wrapper_options
14
+ {
15
+ bypass: @wrapper == false
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
Binary file
@@ -0,0 +1,15 @@
1
+ module Headmin
2
+ class BlocksView < ViewModel
3
+ def show_blocks?
4
+ blockable&.respond_to?(:blocks)
5
+ end
6
+
7
+ def paths
8
+ @paths || []
9
+ end
10
+
11
+ def prefixes
12
+ paths + ["website/blocks", "blocks", ""]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ module Headmin
2
+ module Form
3
+ class BlocksView < ViewModel
4
+ def repeater_options
5
+ keys = %i[form attribute names label]
6
+ options = to_h.slice(*keys)
7
+ default_repeater_options.merge(options)
8
+ end
9
+
10
+ def paths
11
+ @paths || []
12
+ end
13
+
14
+ def prefixes
15
+ paths + ["admin/blocks", "blocks", ""]
16
+ end
17
+
18
+ private
19
+
20
+ def default_repeater_options
21
+ {
22
+ attribute: "blocks",
23
+ label: false,
24
+ templates: names
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,52 @@
1
+ module Headmin
2
+ module Form
3
+ class CheckboxView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::Labelable
6
+ include Headmin::Form::Validatable
7
+ include Headmin::Form::Wrappable
8
+
9
+ def checked_value
10
+ @checked_value || "1"
11
+ end
12
+
13
+ def unchecked_value
14
+ @unchecked_value || "0"
15
+ end
16
+
17
+ def input_options
18
+ keys = attributes - %i[attribute form label validate wrapper checked_value unchecked_value]
19
+ options = to_h.slice(*keys)
20
+ default_input_options.merge(options)
21
+ end
22
+
23
+ def label_options
24
+ {
25
+ class: ["form-check-label"],
26
+ attribute: attribute,
27
+ form: form,
28
+ required: required,
29
+ text: label
30
+ }
31
+ end
32
+
33
+ def wrapper_options
34
+ default_wrapper_options.merge(
35
+ {
36
+ class: %w[form-check mb-3]
37
+ }
38
+ ).merge(@wrapper || {})
39
+ end
40
+
41
+ private
42
+
43
+ def default_input_options
44
+ {
45
+ aria: {describedby: validation_id},
46
+ class: ["form-check-input", validation_class],
47
+ placeholder: placeholder
48
+ }
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,25 @@
1
+ module Headmin
2
+ module Form
3
+ class DateRangeView < ViewModel
4
+ def start_options
5
+ default_start_options.merge(@start || {})
6
+ end
7
+
8
+ def end_options
9
+ default_end_options.merge(@end || {})
10
+ end
11
+
12
+ private
13
+
14
+ def default_start_options
15
+ keys = attributes - %i[start]
16
+ to_h.slice(*keys)
17
+ end
18
+
19
+ def default_end_options
20
+ keys = attributes - %i[end]
21
+ to_h.slice(*keys)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ module Headmin
2
+ module Form
3
+ class DateView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::InputGroupable
6
+ include Headmin::Form::Labelable
7
+ include Headmin::Form::Listable
8
+ include Headmin::Form::Placeholderable
9
+ include Headmin::Form::Validatable
10
+ include Headmin::Form::Wrappable
11
+
12
+ def input_options
13
+ keys = attributes - %i[append attribute float form input_group input_group label prepend validate wrapper]
14
+ options = to_h.slice(*keys)
15
+ default_input_options.merge(options)
16
+ end
17
+
18
+ def input_group_options
19
+ default_input_group_options
20
+ .merge(label_input_group_options)
21
+ .merge(@input_group || {})
22
+ end
23
+
24
+ def wrapper_options
25
+ default_wrapper_options.merge({
26
+ class: ["mb-3", ("form-floating" if float)]
27
+ }).merge(@wrapper || {})
28
+ end
29
+
30
+ private
31
+
32
+ def default_input_options
33
+ {
34
+ aria: {describedby: validation_id},
35
+ class: [form_control_class, validation_class],
36
+ placeholder: placeholder
37
+ }
38
+ end
39
+
40
+ def form_control_class
41
+ plaintext ? "form-control-plaintext" : "form-control"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,48 @@
1
+ module Headmin
2
+ module Form
3
+ class EmailView < 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.merge(options)
17
+ options.merge(autocomplete_input_options)
18
+ end
19
+
20
+ def input_group_options
21
+ default_input_group_options
22
+ .merge(autocomplete_input_group_options)
23
+ .merge(label_input_group_options)
24
+ .merge(@input_group || {})
25
+ end
26
+
27
+ def wrapper_options
28
+ default_wrapper_options.merge({
29
+ class: ["mb-3", ("form-floating" if float)]
30
+ }).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,116 @@
1
+ module Headmin
2
+ module Form
3
+ class FileView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::InputGroupable
6
+ include Headmin::Form::Labelable
7
+ include Headmin::Form::Placeholderable
8
+ include Headmin::Form::Validatable
9
+ include Headmin::Form::Wrappable
10
+
11
+ def input_options
12
+ keys = attributes - %i[append attribute dropzone destroy form input_group label prepend preview validate wrapper]
13
+ options = to_h.slice(*keys)
14
+ options = default_input_options.merge(options)
15
+ options = options.merge(required: false) if attachments.any?
16
+ options
17
+ end
18
+
19
+ def input_group_options
20
+ default_input_group_options
21
+ .merge(label_input_group_options)
22
+ .merge(@input_group || {})
23
+ end
24
+
25
+ def wrapper_options
26
+ default_wrapper_options.merge({
27
+ class: ["mb-3 h-form-file", ("form-floating" if float)],
28
+ data: {
29
+ controller: ("file-preview" if preview)
30
+ }
31
+ }).merge(@wrapper || {})
32
+ end
33
+
34
+ def preview
35
+ @preview || dropzone
36
+ end
37
+
38
+ def destroy
39
+ @destroy || false
40
+ end
41
+
42
+ def attached
43
+ form.object&.send(attribute)
44
+ end
45
+
46
+ def attachments
47
+ attached&.attachments || []
48
+ end
49
+
50
+ def number_of_files
51
+ multiple ? 2 : 1
52
+ end
53
+
54
+ def nested_attribute
55
+ attached.is_a?(ActiveStorage::Attached::Many) ? :"#{attribute}_attachments" : :"#{attribute}_attachment"
56
+ end
57
+
58
+ def thumbnail_width
59
+ 100
60
+ end
61
+
62
+ def thumbnail_height
63
+ 100
64
+ end
65
+
66
+ def dropzone_options
67
+ if dropzone
68
+ {
69
+ class: ["h-dropzone", validation_class],
70
+ data: {
71
+ controller: "dropzone"
72
+ }
73
+ }
74
+ else
75
+ {
76
+ class: validation_class
77
+ }
78
+ end
79
+ end
80
+
81
+ # def input_group_options
82
+ # {
83
+ # prepend: prepend,
84
+ # append: append,
85
+ # class: "h-form-file",
86
+ # data: {
87
+ # controller: "#{"file-preview" if preview} #{"dropzone" if dropzone}"
88
+ # }
89
+ # }
90
+ # end
91
+
92
+ private
93
+
94
+ def default_input_options
95
+ {
96
+ aria: {describedby: validation_id},
97
+ class: ["form-control", validation_class],
98
+ placeholder: placeholder,
99
+ data: preview_data
100
+ }
101
+ end
102
+
103
+ def preview_data
104
+ if preview
105
+ {
106
+ "file-preview-target": "input",
107
+ "dropzone-target": "input",
108
+ action: "change->file-preview#preview dropEnd->file-preview#preview"
109
+ }
110
+ else
111
+ {}
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,102 @@
1
+ module Headmin
2
+ module Form
3
+ class FlatpickrRangeView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::InputGroupable
6
+ include Headmin::Form::Labelable
7
+ include Headmin::Form::Listable
8
+ include Headmin::Form::Placeholderable
9
+ include Headmin::Form::Validatable
10
+ include Headmin::Form::Wrappable
11
+
12
+ def attribute
13
+ @attribute || :period
14
+ end
15
+
16
+ def start_attribute
17
+ @start.dig(:attribute) || :start_date
18
+ end
19
+
20
+ def end_attribute
21
+ @end.dig(:attribute) || :end_date
22
+ end
23
+
24
+ def start_options
25
+ default_start_options.merge(@start || {})
26
+ end
27
+
28
+ def end_options
29
+ default_end_options.merge(@end || {})
30
+ end
31
+
32
+ def input_options
33
+ keys = attributes - %i[append attribute end float form input_group label prepend start validate wrapper]
34
+ options = to_h.slice(*keys)
35
+ default_input_options.merge(options)
36
+ end
37
+
38
+ def input_group_options
39
+ default_input_group_options
40
+ .merge(label_input_group_options)
41
+ .merge(@input_group || {})
42
+ end
43
+
44
+ def wrapper_options
45
+ default_wrapper_options.merge({
46
+ class: ["mb-3", ("form-floating" if float)],
47
+ data: {
48
+ controller: "flatpickr date-range"
49
+ }
50
+ }).merge(@wrapper || {})
51
+ end
52
+
53
+ private
54
+
55
+ def default_options
56
+ {
57
+ name: nil
58
+ }
59
+ end
60
+
61
+ def default_start_options
62
+ {
63
+ data: {
64
+ 'date-range-target': "startDateInput"
65
+ }
66
+ }
67
+ end
68
+
69
+ def default_end_options
70
+ {
71
+ data: {
72
+ 'date-range-target': "endDateInput"
73
+ }
74
+ }
75
+ end
76
+
77
+ def default_input_options
78
+ {
79
+ aria: {describedby: validation_id},
80
+ class: [form_control_class, validation_class],
81
+ placeholder: placeholder,
82
+ name: nil,
83
+ data: {
84
+ "flatpickr-target": "input",
85
+ action: "change->date-range#update",
86
+ flatpickr: {
87
+ mode: "range",
88
+ defaultDate: [
89
+ form.object&.send(start_attribute)&.strftime("%d/%m/%Y"),
90
+ form.object&.send(end_attribute)&.strftime("%d/%m/%Y")
91
+ ]
92
+ }
93
+ }
94
+ }
95
+ end
96
+
97
+ def form_control_class
98
+ plaintext ? "form-control-plaintext" : "form-control"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,37 @@
1
+ module Headmin
2
+ module Form
3
+ class FlatpickrView < ViewModel
4
+ def options
5
+ keys = attributes - %i[data wrapper]
6
+ options = to_h.slice(*keys)
7
+ default_options.merge(options)
8
+ end
9
+
10
+ private
11
+
12
+ def default_options
13
+ {
14
+ data: default_data.merge(data || {}),
15
+ wrapper: default_wrapper_options.merge(wrapper || {})
16
+ }
17
+ end
18
+
19
+ def default_data
20
+ {
21
+ "flatpickr-target": "input",
22
+ flatpickr: {
23
+ defaultDate: form.object&.send(attribute)&.strftime("%d/%m/%Y")
24
+ }
25
+ }
26
+ end
27
+
28
+ def default_wrapper_options
29
+ {
30
+ data: {
31
+ controller: "flatpickr"
32
+ }
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ module Headmin
2
+ module Form
3
+ class HiddenView < ViewModel
4
+ def input_options
5
+ keys = attributes - %i[attribute form]
6
+ to_h.slice(*keys)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module Headmin
2
+ module Form
3
+ class HintView < ViewModel
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ module Headmin
2
+ module Form
3
+ class InputGroupView < ViewModel
4
+ def options
5
+ keys = attributes - %i[bypass append prepend]
6
+ options = to_h.slice(*keys)
7
+ default_options.merge(options)
8
+ end
9
+
10
+ private
11
+
12
+ def default_options
13
+ {
14
+ class: ["input-group"]
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Headmin
2
+ module Form
3
+ class LabelView < ViewModel
4
+ def form
5
+ @form.object_id
6
+ end
7
+
8
+ def options
9
+ keys = attributes - %i[attribute form text]
10
+ options = to_h.slice(*keys)
11
+ default_options.merge(options)
12
+ end
13
+
14
+ private
15
+
16
+ def default_options
17
+ {
18
+ class: "form-label",
19
+ required: required
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ module Headmin
2
+ module Form
3
+ class NumberView < ViewModel
4
+ include Headmin::Form::Hintable
5
+ include Headmin::Form::InputGroupable
6
+ include Headmin::Form::Labelable
7
+ include Headmin::Form::Listable
8
+ include Headmin::Form::Placeholderable
9
+ include Headmin::Form::Validatable
10
+ include Headmin::Form::Wrappable
11
+
12
+ def input_options
13
+ keys = attributes - %i[append attribute float form input_group label prepend validate wrapper]
14
+ options = to_h.slice(*keys)
15
+ default_input_options.merge(options)
16
+ end
17
+
18
+ def input_group_options
19
+ default_input_group_options
20
+ .merge(label_input_group_options)
21
+ .merge(@input_group || {})
22
+ end
23
+
24
+ def wrapper_options
25
+ default_wrapper_options.merge({
26
+ class: ["mb-3", float_class]
27
+ }).merge(@wrapper || {})
28
+ end
29
+
30
+ private
31
+
32
+ def float_class
33
+ "form-floating" if float
34
+ end
35
+
36
+ def default_input_options
37
+ {
38
+ aria: {describedby: validation_id},
39
+ class: [form_control_class, validation_class],
40
+ placeholder: placeholder
41
+ }
42
+ end
43
+
44
+ def form_control_class
45
+ plaintext ? "form-control-plaintext" : "form-control"
46
+ end
47
+ end
48
+ end
49
+ end