formular 0.2.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +29 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +105 -0
  8. data/Rakefile +12 -0
  9. data/formular.gemspec +33 -0
  10. data/lib/formular.rb +8 -0
  11. data/lib/formular/attributes.rb +45 -0
  12. data/lib/formular/builder.rb +52 -0
  13. data/lib/formular/builders/basic.rb +64 -0
  14. data/lib/formular/builders/bootstrap3.rb +28 -0
  15. data/lib/formular/builders/bootstrap3_horizontal.rb +32 -0
  16. data/lib/formular/builders/bootstrap3_inline.rb +10 -0
  17. data/lib/formular/builders/bootstrap4.rb +36 -0
  18. data/lib/formular/builders/bootstrap4_horizontal.rb +39 -0
  19. data/lib/formular/builders/bootstrap4_inline.rb +15 -0
  20. data/lib/formular/builders/foundation6.rb +28 -0
  21. data/lib/formular/element.rb +135 -0
  22. data/lib/formular/element/bootstrap3.rb +70 -0
  23. data/lib/formular/element/bootstrap3/checkable_control.rb +105 -0
  24. data/lib/formular/element/bootstrap3/column_control.rb +45 -0
  25. data/lib/formular/element/bootstrap3/horizontal.rb +146 -0
  26. data/lib/formular/element/bootstrap3/input_group.rb +83 -0
  27. data/lib/formular/element/bootstrap4.rb +49 -0
  28. data/lib/formular/element/bootstrap4/checkable_control.rb +94 -0
  29. data/lib/formular/element/bootstrap4/custom_control.rb +120 -0
  30. data/lib/formular/element/bootstrap4/horizontal.rb +87 -0
  31. data/lib/formular/element/foundation6.rb +69 -0
  32. data/lib/formular/element/foundation6/checkable_control.rb +72 -0
  33. data/lib/formular/element/foundation6/input_group.rb +88 -0
  34. data/lib/formular/element/foundation6/wrapped_control.rb +21 -0
  35. data/lib/formular/element/module.rb +35 -0
  36. data/lib/formular/element/modules/checkable.rb +96 -0
  37. data/lib/formular/element/modules/collection.rb +17 -0
  38. data/lib/formular/element/modules/container.rb +60 -0
  39. data/lib/formular/element/modules/control.rb +42 -0
  40. data/lib/formular/element/modules/error.rb +48 -0
  41. data/lib/formular/element/modules/hint.rb +36 -0
  42. data/lib/formular/element/modules/label.rb +30 -0
  43. data/lib/formular/element/modules/wrapped_control.rb +73 -0
  44. data/lib/formular/elements.rb +295 -0
  45. data/lib/formular/helper.rb +53 -0
  46. data/lib/formular/html_block.rb +70 -0
  47. data/lib/formular/path.rb +30 -0
  48. data/lib/formular/version.rb +3 -0
  49. metadata +247 -0
@@ -0,0 +1,45 @@
1
+ require 'formular/element/module'
2
+
3
+ module Formular
4
+ class Element
5
+ module Bootstrap3
6
+ # this module simplifies the process of
7
+ # creating inline column controls
8
+ # you will need to manually wrap your element in a row
9
+ module ColumnControl
10
+ include Formular::Element::Module
11
+
12
+ add_option_keys :inline_col_class, :stacked_col_class
13
+ set_default :wrapper_options, :inline_wrapper_class, if: :inline_column?
14
+
15
+ def inline_wrapper_class
16
+ { class: options[:inline_col_class] }
17
+ end
18
+
19
+ def inline_column?
20
+ options[:inline_col_class]
21
+ end
22
+
23
+ def stacked_column?
24
+ options[:stacked_col_class]
25
+ end
26
+
27
+ rename_html_context(:default, :no_cols)
28
+
29
+ html(:stacked_column) do |element|
30
+ element.builder.row {
31
+ element.builder.div(
32
+ class: element.options[:stacked_col_class],
33
+ content: element.to_html(context: :no_cols)
34
+ )
35
+ }
36
+ end
37
+
38
+ html do |element|
39
+ context = element.stacked_column? ? :stacked_column : :no_cols
40
+ element.to_html(context: context)
41
+ end
42
+ end # module ColumnControl
43
+ end # module Bootstrap3
44
+ end # class Element
45
+ end # module Formular
@@ -0,0 +1,146 @@
1
+ require 'formular/element'
2
+ require 'formular/elements'
3
+ require 'formular/element/module'
4
+ require 'formular/element/bootstrap3'
5
+ require 'formular/element/bootstrap3/checkable_control'
6
+ module Formular
7
+ class Element
8
+ module Bootstrap3
9
+ module Horizontal
10
+ module WrappedControl
11
+ include Formular::Element::Module
12
+
13
+ html(:label_column) do |input|
14
+ input.label
15
+ end
16
+
17
+ html(:input_column) do |input|
18
+ concat input.to_html(context: :default)
19
+ concat input.hint
20
+ concat input.error
21
+ end
22
+
23
+ html(:wrapped) do |input|
24
+ input.wrapper do |wrapper|
25
+ concat input.to_html(context: :label_column)
26
+ concat wrapper.input_column_wrapper(
27
+ class: input.column_class,
28
+ content: input.to_html(context: :input_column)
29
+ )
30
+ end
31
+ end
32
+
33
+ module InstanceMethods
34
+ def column_class
35
+ has_label? ? [] : builder.class.column_classes[:left_offset]
36
+ end
37
+ end
38
+ end # module WrappedControl
39
+
40
+ module WrappedCheckableControl
41
+ include Formular::Element::Module
42
+ include WrappedControl
43
+
44
+ html(:label_column) do |input|
45
+ input.group_label
46
+ end
47
+
48
+ html(:input_column) do |input|
49
+ concat input.hidden_tag
50
+ concat input.to_html(context: :collection)
51
+ concat input.hint
52
+ concat input.error
53
+ end
54
+
55
+ module InstanceMethods
56
+ def column_class
57
+ has_group_label? ? [] : builder.class.column_classes[:left_offset]
58
+ end
59
+ end
60
+ end # module WrappedCheckableControl
61
+
62
+ class InputColumnWrapper < Formular::Element::Div
63
+ set_default :class, :column_class
64
+
65
+ def column_class
66
+ builder.class.column_classes[:right_column]
67
+ end
68
+ end # class InputColumnWrapper
69
+
70
+ class Label < Formular::Element::Bootstrap3::Label
71
+ set_default :class, :column_class
72
+
73
+ def column_class
74
+ builder.class.column_classes[:left_column] + ['control-label']
75
+ end
76
+ end # class Label
77
+
78
+ class Form < Formular::Element::Form
79
+ set_default :class, ['form-horizontal']
80
+ end # class Form
81
+
82
+ class Select < Formular::Element::Bootstrap3::Select
83
+ include WrappedControl
84
+ end # class Select
85
+
86
+ class Textarea < Formular::Element::Bootstrap3::Textarea
87
+ include WrappedControl
88
+ end # class Textarea
89
+
90
+ class Input < Formular::Element::Bootstrap3::Input
91
+ include WrappedControl
92
+ end # class Input
93
+
94
+ class InputGroup < Formular::Element::Bootstrap3::InputGroup
95
+ include WrappedControl
96
+
97
+ html(:start) do |input|
98
+ wrapper = input.wrapper
99
+ concat wrapper.start
100
+ concat input.to_html(context: :label_column)
101
+ concat wrapper.input_column_wrapper(class: input.column_class).start
102
+ concat Formular::Element::Bootstrap3::InputGroup::Wrapper.().start
103
+ end
104
+
105
+ html(:end) do |input|
106
+ wrapper = input.wrapper
107
+ concat Formular::Element::Bootstrap3::InputGroup::Wrapper.().end
108
+ concat wrapper.input_column_wrapper.end
109
+ concat wrapper.end
110
+ end
111
+ end # class InputGroup
112
+
113
+ class Submit < Formular::Element::Bootstrap3::Submit
114
+ self.html_context = :wrapped
115
+
116
+ html(:wrapped) do |input|
117
+ input.wrapper do |wrapper|
118
+ wrapper.input_column_wrapper(
119
+ class: input.builder.class.column_classes[:left_offset],
120
+ content: input.to_html(context: :default)
121
+ )
122
+ end
123
+ end
124
+ end # class Submit
125
+
126
+ class Checkbox < Formular::Element::Bootstrap3::Checkbox
127
+ include Formular::Element::Bootstrap3::CheckableControl::StackedCheckable
128
+ include WrappedCheckableControl
129
+ end # class Checkbox
130
+
131
+ class Radio < Formular::Element::Bootstrap3::Radio
132
+ include Formular::Element::Bootstrap3::CheckableControl::StackedCheckable
133
+ include WrappedCheckableControl
134
+ end # class Radio
135
+
136
+ class InlineCheckbox < Formular::Element::Bootstrap3::InlineCheckbox
137
+ include WrappedCheckableControl
138
+ end # class InlineCheckbox
139
+
140
+ class InlineRadio < Formular::Element::Bootstrap3::InlineRadio
141
+ include WrappedCheckableControl
142
+ end # class InlineRadio
143
+ end # module Horizontal
144
+ end # module Bootstrap3
145
+ end # class Element
146
+ end # module Formular
@@ -0,0 +1,83 @@
1
+ require 'formular/elements'
2
+ require 'formular/element/modules/container'
3
+ require 'formular/element/modules/wrapped_control'
4
+
5
+ module Formular
6
+ class Element
7
+ module Bootstrap3
8
+ class InputGroup < Formular::Element::Input
9
+ include Formular::Element::Modules::WrappedControl
10
+ include Formular::Element::Modules::Container
11
+ include Formular::Element::Bootstrap3::ColumnControl
12
+
13
+ class Wrapper < Formular::Element::Div
14
+ set_default :class, ['input-group']
15
+ end # class Wrapper
16
+
17
+ class Addon < Formular::Element::Span
18
+ set_default :class, ['input-group-addon']
19
+ end # class Addon
20
+
21
+ class Btn < Formular::Element::Span
22
+ set_default :class, ['input-group-btn']
23
+ end # class Btn
24
+
25
+ set_default :class, ['form-control']
26
+
27
+ add_option_keys :left_addon, :right_addon, :left_btn, :right_btn
28
+
29
+ html(:raw_input) { closed_start_tag }
30
+
31
+ html(:no_cols) do |input|
32
+ content = if input.has_content?
33
+ input.content
34
+ else
35
+ input.to_html(context: :with_options)
36
+ end
37
+ Wrapper.(content: content)
38
+ end
39
+
40
+ html(:start) do |input|
41
+ concat input.wrapper.start
42
+ concat input.label
43
+ concat Wrapper.().start
44
+ end
45
+
46
+ html(:end) do |input|
47
+ concat Wrapper.().end
48
+ concat input.hint
49
+ concat input.error
50
+ concat input.wrapper.end
51
+ end
52
+
53
+ def group_addon(content = nil, option_key: nil)
54
+ return '' unless content || option_key
55
+ addon_content = content || options[option_key]
56
+ return '' unless addon_content
57
+
58
+ Addon.(content: addon_content)
59
+ end
60
+
61
+ def group_btn(content = nil, option_key: nil)
62
+ return '' unless content || option_key
63
+ addon_content = content || options[option_key]
64
+ return '' unless addon_content
65
+
66
+ Btn.(content: addon_content)
67
+ end
68
+
69
+ def control
70
+ to_html(context: :raw_input)
71
+ end
72
+
73
+ html(:with_options) do |input|
74
+ concat input.group_addon(option_key: :left_addon)
75
+ concat input.group_btn(option_key: :left_btn)
76
+ concat input.control
77
+ concat input.group_addon(option_key: :right_addon)
78
+ concat input.group_btn(option_key: :right_btn)
79
+ end
80
+ end # class InputGroup
81
+ end # module Bootstrap3
82
+ end # class Element
83
+ end # module Formular
@@ -0,0 +1,49 @@
1
+ require 'formular/element'
2
+ require 'formular/elements'
3
+ require 'formular/element/modules/wrapped_control'
4
+ require 'formular/element/module'
5
+ require 'formular/element/bootstrap4/checkable_control'
6
+ require 'formular/element/bootstrap4/custom_control'
7
+ require 'formular/element/bootstrap3/column_control'
8
+
9
+ module Formular
10
+ class Element
11
+ module Bootstrap4
12
+ include CheckableControl
13
+ include CustomControl
14
+
15
+ class Submit < Formular::Element::Button
16
+ set_default :class, ['btn', 'btn-secondary']
17
+ set_default :type, 'submit'
18
+ end # class Submit
19
+
20
+ class Error < Formular::Element::Error
21
+ tag :span
22
+ set_default :class, ['form-control-feedback']
23
+ end # class Error
24
+
25
+ class Hint < Formular::Element::Small
26
+ set_default :class, ['text-muted']
27
+ end # class Hint
28
+
29
+ class Input < Formular::Element::Input
30
+ include Formular::Element::Modules::WrappedControl
31
+ include Formular::Element::Bootstrap3::ColumnControl
32
+
33
+ set_default :class, :input_class
34
+
35
+ def input_class
36
+ attributes[:type].to_s == 'file' ? %(form-control-file) : %(form-control)
37
+ end
38
+ end # class Input
39
+
40
+ class Wrapper < Formular::Element::Fieldset
41
+ set_default :class, ['form-group']
42
+ end # class Wrapper
43
+
44
+ class ErrorWrapper < Formular::Element::Fieldset
45
+ set_default :class, ['form-group', 'has-danger']
46
+ end # class Wrapper
47
+ end # module Bootstrap3
48
+ end # class Element
49
+ end # module Formular
@@ -0,0 +1,94 @@
1
+ require 'formular/elements'
2
+ require 'formular/element/modules/wrapped_control'
3
+ require 'formular/element/module'
4
+
5
+ module Formular
6
+ class Element
7
+ module Bootstrap4
8
+ module CheckableControl
9
+ class Checkbox < Formular::Element::Checkbox
10
+ include Formular::Element::Modules::WrappedControl
11
+ set_default :class, ['form-check-input']
12
+ set_default :value, '1' # instead of reader value
13
+
14
+ html { closed_start_tag }
15
+ end # class Checkbox
16
+
17
+ class Radio < Formular::Element::Radio
18
+ include Formular::Element::Modules::WrappedControl
19
+ set_default :class, ['form-check-input']
20
+
21
+ def hidden_tag
22
+ ''
23
+ end
24
+ end # class Radio
25
+
26
+ module InlineCheckable
27
+ include Formular::Element::Module
28
+
29
+ set_default :control_label_options, { class: ['form-check-inline'] }
30
+
31
+ html(:wrapped) do |input|
32
+ input.wrapper do
33
+ concat input.group_label
34
+ concat input.hidden_tag unless input.collection?
35
+ if input.has_group_label?
36
+ concat Formular::Element::Div.(content: input.to_html(context: :collection))
37
+ else
38
+ concat input.to_html(context: :collection)
39
+ end
40
+ concat input.hidden_tag if input.collection?
41
+ concat input.hint
42
+ concat input.error
43
+ end
44
+ end
45
+ end # class InlineCheckable
46
+
47
+ class InlineRadio < Radio
48
+ include InlineCheckable
49
+ end # class InlineRadio
50
+
51
+ class InlineCheckbox < Checkbox
52
+ include InlineCheckable
53
+ end # class InlineCheckbox
54
+
55
+ module StackedCheckable
56
+ include Formular::Element::Module
57
+
58
+ html(:wrapped) do |input|
59
+ input.wrapper do
60
+ concat input.group_label
61
+ concat input.hidden_tag unless input.collection?
62
+ concat input.to_html(context: :collection)
63
+ concat input.hidden_tag if input.collection?
64
+ concat input.hint
65
+ concat input.error
66
+ end
67
+ end
68
+
69
+ html(:collection) do |input|
70
+ input.collection.map { |control|
71
+ control.inner_wrapper { control.to_html(context: :checkable_label) }
72
+ }.join('')
73
+ end
74
+
75
+ set_default :control_label_options, { class: ['form-check-label'] }
76
+
77
+ module InstanceMethods
78
+ def inner_wrapper(&block)
79
+ Formular::Element::Div.(class: ['form-check'], &block).to_s
80
+ end
81
+ end
82
+ end # module StackedCheckable
83
+
84
+ class StackedCheckbox < Checkbox
85
+ include StackedCheckable
86
+ end # class Checkbox
87
+
88
+ class StackedRadio < Radio
89
+ include StackedCheckable
90
+ end # class StackedRadio
91
+ end # module CheckableControl
92
+ end # module Bootstrap4
93
+ end # class Element
94
+ end # module Formular
@@ -0,0 +1,120 @@
1
+ require 'formular/elements'
2
+ require 'formular/element/modules/wrapped_control'
3
+ require 'formular/element/bootstrap4'
4
+ require 'formular/element/bootstrap3'
5
+ require 'formular/element/module'
6
+
7
+ module Formular
8
+ class Element
9
+ module Bootstrap4
10
+ module CustomControl
11
+ module CustomCheckable
12
+ include Formular::Element::Module
13
+ include Formular::Element::Modules::WrappedControl
14
+ set_default :class, ['custom-control-input']
15
+
16
+ html(:checkable_label) do |input|
17
+ Formular::Element::Label.(input.label_options) do
18
+ concat input.to_html(context: :default)
19
+ concat Formular::Element::Span.(class: ['custom-control-indicator'])
20
+ if input.has_label?
21
+ concat Formular::Element::Span.(class: ['custom-control-description'], content: input.label_text)
22
+ end
23
+ end
24
+ end
25
+
26
+ html(:wrapped) do |input|
27
+ input.wrapper do
28
+ concat input.group_label
29
+ concat input.hidden_tag unless input.collection?
30
+ concat input.to_html(context: :collection)
31
+ concat input.hidden_tag if input.collection?
32
+ concat input.hint
33
+ concat input.error
34
+ end
35
+ end
36
+ end # module CustomCheckbable
37
+
38
+ module CustomStackable
39
+ include Formular::Element::Module
40
+
41
+ html(:collection) do |input|
42
+ collection_html = input.collection.map { |item|
43
+ item.to_html(context: :checkable_label)
44
+ }.join
45
+
46
+ Formular::Element::Div.(
47
+ class: ['custom-controls-stacked'],
48
+ content: collection_html
49
+ )
50
+ end
51
+ end # module CustomStackable
52
+
53
+ module Inline
54
+ class CustomCheckbox < Formular::Element::Checkbox
55
+ include CustomCheckable
56
+
57
+ html { closed_start_tag }
58
+
59
+ set_default :control_label_options, { class: ['custom-control custom-checkbox'] }
60
+ set_default :value, '1' # instead of reader value
61
+ end # class Checkbox
62
+
63
+ class CustomRadio < Formular::Element::Radio
64
+ include CustomCheckable
65
+ set_default :control_label_options, { class: ['custom-control custom-radio'] }
66
+
67
+ def hidden_tag
68
+ ''
69
+ end
70
+ end # class Radio
71
+
72
+ class CustomSelect < Formular::Element::Bootstrap3::Select
73
+ set_default :class, ['custom-select']
74
+ end # class CustomSelect
75
+
76
+ class CustomFile < Formular::Element::Input
77
+ include Formular::Element::Modules::WrappedControl
78
+ include Formular::Element::Bootstrap3::ColumnControl
79
+
80
+ set_default :class, ['custom-file-input']
81
+ set_default :type, 'file'
82
+
83
+ rename_html_context(:default, :control)
84
+
85
+ html do |input|
86
+ Formular::Element::Label.(class: ['custom-file']) do
87
+ concat input.to_html(context: :control)
88
+ concat Formular::Element::Span.(class: ['custom-file-control'])
89
+ end
90
+ end
91
+ end #class CustomFile
92
+ end # module Inline
93
+
94
+ class CustomSelect < Inline::CustomSelect
95
+ rename_html_context(:default, :input)
96
+
97
+ html do |input|
98
+ Formular::Element::Div.(content: input.to_html(context: :input))
99
+ end
100
+ end # class Select
101
+
102
+ class CustomFile < Inline::CustomFile
103
+ rename_html_context(:default, :input)
104
+
105
+ html do |input|
106
+ Formular::Element::Div.(content: input.to_html(context: :input))
107
+ end
108
+ end # class File
109
+
110
+ class CustomStackedRadio < Inline::CustomRadio
111
+ include CustomStackable
112
+ end # class StackedRadio
113
+
114
+ class CustomStackedCheckbox < Inline::CustomCheckbox
115
+ include CustomStackable
116
+ end # class StackedCheckbox
117
+ end # module CustomControl
118
+ end # module Bootstrap4
119
+ end # class Element
120
+ end # module Formular