formular 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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