glimmer-dsl-web 0.4.2 → 0.4.3

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.
@@ -83,9 +83,8 @@ class StyledButton
83
83
  button {
84
84
  inner_text <= [button_model, :text, computed_by: :pushed]
85
85
 
86
- class_name <= [button_model, :pushed,
87
- on_read: ->(pushed) { pushed ? 'pushed' : 'pulled' }
88
- ]
86
+ class_name(:pushed) <= [button_model, :pushed]
87
+ class_name(:pulled) <= [button_model, :pushed, on_read: :!]
89
88
 
90
89
  style(:width) <= [button_model, :width, on_read: :px]
91
90
  style(:height) <= [button_model, :height, on_read: :px]
@@ -99,22 +98,22 @@ class StyledButton
99
98
  }
100
99
  }
101
100
 
102
- style {"
103
- .#{component_element_class} {
104
- font-family: Courrier New, Courrier;
105
- border-radius: 5px;
106
- border-width: 17px;
107
- margin: 5px;
101
+ style {
102
+ r(component_element_selector) {
103
+ font_family 'Courrier New, Courrier'
104
+ border_radius 5
105
+ border_width 17
106
+ margin 5
108
107
  }
109
108
 
110
- .#{component_element_class}.pulled {
111
- border-style: outset;
109
+ r("#{component_element_selector}.pulled") {
110
+ border_style :outset
112
111
  }
113
112
 
114
- .#{component_element_class}.pushed {
115
- border-style: inset;
113
+ r("#{component_element_selector}.pushed") {
114
+ border_style :inset
116
115
  }
117
- "}
116
+ }
118
117
  end
119
118
 
120
119
  class StyledButtonRangeInput
@@ -172,22 +171,22 @@ class HelloStyle
172
171
  }
173
172
  }
174
173
 
175
- style {"
176
- .styled-button-form {
177
- padding: 20px;
178
- display: inline-grid;
179
- grid-template-columns: auto auto;
174
+ style {
175
+ r('.styled-button-form') {
176
+ padding 20
177
+ display 'inline-grid'
178
+ grid_template_columns 'auto auto'
180
179
  }
181
180
 
182
- .styled-button-form label, input {
183
- display: block;
184
- margin: 5px 5px 5px 0;
181
+ r('.styled-button-form label, input') {
182
+ display :block
183
+ margin '5px 5px 5px 0'
185
184
  }
186
185
 
187
- .#{component_element_class} .styled-button {
188
- display: block;
186
+ r("#{component_element_selector} .styled-button") {
187
+ display :block
189
188
  }
190
- "}
189
+ }
191
190
  end
192
191
 
193
192
  Document.ready? do
@@ -6,11 +6,16 @@ class EditTodoInput < TodoInput
6
6
 
7
7
  markup { # evaluated against instance as a smart default convention
8
8
  input { |edit_input|
9
- style <= [ todo, :editing,
10
- on_read: ->(editing) { editing ? '' : 'display: none;' },
11
- after_read: -> { edit_input.focus if todo.editing? }
12
- ]
9
+ # Data-bind inclusion of `li` `class` `editing` unidirectionally to todo editing attribute,
10
+ # meaning inclusion of editing class is determined by todo editing boolean attribute.
11
+ # `after_read` hook will have `input` grab keyboard focus when editing todo.
12
+ class_name(:editing) <= [ todo, :editing,
13
+ after_read: -> { edit_input.focus if todo.editing? }
14
+ ]
13
15
 
16
+ # Data-bind `input` `value` property bidirectionally to `todo` `task` attribute
17
+ # meaning make any changes to the `todo` `task` attribute value automatically update the `input` `value` property
18
+ # and any changes to the `input` `value` property by the user automatically update the `todo` `task` attribute value.
14
19
  value <=> [todo, :task]
15
20
 
16
21
  onkeyup do |event|
@@ -31,17 +36,21 @@ class EditTodoInput < TodoInput
31
36
  style { # evaluated against class as a smart default convention (common to all instances)
32
37
  todo_input_styles
33
38
 
34
- rule("*:has(> .#{component_element_class})") {
35
- position 'relative'
39
+ r("*:has(> #{component_element_selector})") {
40
+ position :relative
36
41
  }
37
42
 
38
- rule(".#{component_element_class}") {
39
- position 'absolute'
40
- display 'block'
43
+ r(component_element_selector) {
44
+ position :absolute
45
+ display :none
41
46
  width 'calc(100% - 43px)'
42
47
  padding '12px 16px'
43
48
  margin '0 0 0 43px'
44
- top '0'
49
+ top 0
50
+ }
51
+
52
+ r("#{component_element_selector}.editing") {
53
+ display :block
45
54
  }
46
55
  }
47
56
  end
@@ -14,16 +14,16 @@ class NewTodoForm
14
14
  }
15
15
 
16
16
  style {
17
- rule('.header h1') {
17
+ r('.header h1') {
18
18
  color '#b83f45'
19
- font_size '80px'
19
+ font_size 80
20
20
  font_weight '200'
21
- position 'absolute'
22
- text_align 'center'
23
- _webkit_text_rendering 'optimizeLegibility'
24
- _moz_text_rendering 'optimizeLegibility'
25
- text_rendering 'optimizeLegibility'
26
- top '-140px'
21
+ position :absolute
22
+ text_align :center
23
+ _webkit_text_rendering :optimizeLegibility
24
+ _moz_text_rendering :optimizeLegibility
25
+ text_rendering :optimizeLegibility
26
+ top -140
27
27
  width '100%'
28
28
  }
29
29
  }
@@ -5,6 +5,9 @@ class NewTodoInput < TodoInput
5
5
 
6
6
  markup { # evaluated against instance as a smart convention
7
7
  input(placeholder: "What needs to be done?", autofocus: "") {
8
+ # Data-bind `input` `value` property bidirectionally to `presenter.new_todo` `task` attribute
9
+ # meaning make any changes to the new todo task automatically update the input value
10
+ # and any changes to the input value by the user automatically update the new todo task value
8
11
  value <=> [presenter.new_todo, :task]
9
12
 
10
13
  onkeyup do |event|
@@ -16,16 +19,16 @@ class NewTodoInput < TodoInput
16
19
  style { # evaluated against class as a smart convention (common to all instances)
17
20
  todo_input_styles
18
21
 
19
- rule(".#{component_element_class}") { # NewTodoInput has component_element_class as 'new-todo-input'
22
+ r(component_element_selector) { # NewTodoInput has component_element_class as 'new-todo-input'
20
23
  padding '16px 16px 16px 60px'
21
- height '65px'
22
- border 'none'
24
+ height 65
25
+ border :none
23
26
  background 'rgba(0, 0, 0, 0.003)'
24
27
  box_shadow 'inset 0 -2px 1px rgba(0,0,0,0.03)'
25
28
  }
26
29
 
27
- rule(".#{component_element_class}::placeholder") {
28
- font_style 'italic'
30
+ r("#{component_element_selector}::placeholder") {
31
+ font_style :italic
29
32
  font_weight '400'
30
33
  color 'rgba(0, 0, 0, 0.4)'
31
34
  }
@@ -4,16 +4,21 @@ class TodoFilters
4
4
  option :presenter
5
5
 
6
6
  markup {
7
- footer(class: 'todo-filters') {
8
- style <= [ presenter, :todos,
9
- on_read: ->(todos) { todos.empty? ? 'display: none;' : '' }
10
- ]
7
+ footer {
8
+ # Data-bind `footer` `style` `display` unidirectionally to presenter todos,
9
+ # and on read, convert todos based on whether they are empty to 'none' or 'block'
10
+ style(:display) <= [ presenter, :todos,
11
+ on_read: ->(todos) { todos.empty? ? 'none' : 'block' }
12
+ ]
11
13
 
12
14
  span(class: 'todo-count') {
13
15
  span('.strong') {
16
+ # Data-bind `span` `inner_text` unidirectionally to presenter active_todo_count
14
17
  inner_text <= [presenter, :active_todo_count]
15
18
  }
16
19
  span {
20
+ # Data-bind `span` `inner_text` unidirectionally to presenter active_todo_count,
21
+ # and on read, convert active_todo_count to string that follows count number
17
22
  inner_text <= [presenter, :active_todo_count,
18
23
  on_read: -> (active_todo_count) { " item#{'s' if active_todo_count != 1} left" }
19
24
  ]
@@ -24,9 +29,11 @@ class TodoFilters
24
29
  TodoPresenter::FILTERS.each do |filter|
25
30
  li {
26
31
  a(filter.to_s.capitalize, href: "#/#{filter unless filter == :all}") {
27
- class_name <= [ presenter, :filter,
28
- on_read: -> (presenter_filter) { presenter_filter == filter ? 'selected' : '' }
29
- ]
32
+ # Data-bind inclusion of `a` `class` `selected` unidirectionally to presenter filter attribute,
33
+ # and on read of presenter filter, convert to boolean value of whether selected class is included
34
+ class_name(:selected) <= [ presenter, :filter,
35
+ on_read: -> (presenter_filter) { presenter_filter == filter }
36
+ ]
30
37
 
31
38
  onclick do |event|
32
39
  presenter.filter = filter
@@ -37,9 +44,9 @@ class TodoFilters
37
44
  }
38
45
 
39
46
  button('Clear completed', class: 'clear-completed') {
40
- style <= [ presenter, :can_clear_completed,
41
- on_read: -> (can_clear_completed) { can_clear_completed ? '' : 'display: none;' },
42
- ]
47
+ # Data-bind inclusion of `button` `class` `can-clear-completed` unidirectionally to presenter can_clear_completed attribute,
48
+ # meaning inclusion of can-clear-completed class is determined by presenter can_clear_completed boolean attribute.
49
+ class_name('can-clear-completed') <= [presenter, :can_clear_completed]
43
50
 
44
51
  onclick do |event|
45
52
  presenter.clear_completed
@@ -49,76 +56,82 @@ class TodoFilters
49
56
  }
50
57
 
51
58
  style {
52
- rule('.todo-filters') {
59
+ r(component_element_selector) {
53
60
  border_top '1px solid #e6e6e6'
54
- font_size '15px'
55
- height '20px'
61
+ font_size 15
62
+ height 20
56
63
  padding '10px 15px'
57
- text_align 'center'
64
+ text_align :center
65
+ display :none
58
66
  }
59
67
 
60
- rule('.todo-filters:before') {
61
- bottom '0'
68
+ r("#{component_element_selector}:before") {
69
+ bottom 0
62
70
  box_shadow '0 1px 1px rgba(0,0,0,.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0,0,0,.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0,0,0,.2)'
63
71
  content '""'
64
- height '50px'
65
- left '0'
66
- overflow 'hidden'
67
- position 'absolute'
68
- right '0'
72
+ height 50
73
+ left 0
74
+ overflow :hidden
75
+ position :absolute
76
+ right 0
69
77
  }
70
78
 
71
- rule('.todo-count') {
72
- float 'left'
73
- text_align 'left'
79
+ r('.todo-count') {
80
+ float :left
81
+ text_align :left
74
82
  }
75
83
 
76
- rule('.todo-count .strong') {
84
+ r('.todo-count .strong') {
77
85
  font_weight '300'
78
86
  }
79
87
 
80
- rule('.filters') {
81
- left '0'
82
- list_style 'none'
83
- margin '0'
84
- padding '0'
85
- position 'absolute'
86
- right '0'
88
+ r('.filters') {
89
+ left 0
90
+ list_style :none
91
+ margin 0
92
+ padding 0
93
+ position :absolute
94
+ right 0
87
95
  }
88
96
 
89
- rule('.filters li') {
90
- display 'inline'
97
+ r('.filters li') {
98
+ display :inline
91
99
  }
92
100
 
93
- rule('.filters li a') {
101
+ r('.filters li a') {
94
102
  border '1px solid transparent'
95
- border_radius '3px'
96
- color 'inherit'
97
- margin '3px'
103
+ border_radius 3
104
+ color :inherit
105
+ margin 3
98
106
  padding '3px 7px'
99
- text_decoration 'none'
100
- cursor 'pointer'
107
+ text_decoration :none
108
+ cursor :pointer
101
109
  }
102
110
 
103
- rule('.filters li a.selected') {
111
+ r('.filters li a.selected') {
104
112
  border_color '#ce4646'
105
113
  }
106
114
 
107
- rule('.clear-completed, html .clear-completed:active') {
108
- cursor 'pointer'
109
- float 'right'
110
- line_height '19px'
111
- position 'relative'
112
- text_decoration 'none'
115
+ r('.clear-completed, html .clear-completed:active') {
116
+ cursor :pointer
117
+ float :right
118
+ line_height 19
119
+ position :relative
120
+ text_decoration :none
121
+ display :none
122
+ }
123
+
124
+ r('.clear-completed.can-clear-completed, html .clear-completed.can-clear-completed:active') {
125
+ display :block
113
126
  }
114
127
 
115
128
  media('(max-width: 430px)') {
116
- rule('.todo-filters') {
117
- height '50px'
129
+ r(component_element_selector) {
130
+ height 50
118
131
  }
119
132
 
120
- rule('.filters') {
121
- bottom '10px'
133
+ r('.filters') {
134
+ bottom 10
122
135
  }
123
136
  }
124
137
  }
@@ -4,29 +4,29 @@ class TodoInput
4
4
 
5
5
  class << self
6
6
  def todo_input_styles
7
- rule(".#{component_element_class}") {
8
- position 'relative'
9
- margin '0'
7
+ r(component_element_selector) {
8
+ position :relative
9
+ margin 0
10
10
  width '100%'
11
- font_size '24px'
12
- font_family 'inherit'
13
- font_weight 'inherit'
14
- line_height '1.4em'
15
- color 'inherit'
16
- padding '6px'
11
+ font_size 24
12
+ font_family :inherit
13
+ font_weight :inherit
14
+ line_height 1.4.em
15
+ color :inherit
16
+ padding 6
17
17
  border '1px solid #999'
18
18
  box_shadow 'inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2)'
19
19
  box_sizing 'border-box'
20
- _webkit_font_smoothing 'antialiased'
20
+ _webkit_font_smoothing :antialiased
21
21
  }
22
22
 
23
- rule(".#{component_element_class}::selection") {
24
- background 'red'
23
+ r("#{component_element_selector}::selection") {
24
+ background :red
25
25
  }
26
26
 
27
- rule(".#{component_element_class}:focus") {
27
+ r("#{component_element_selector}:focus") {
28
28
  box_shadow '0 0 2px 2px #cf7d7d'
29
- outline '0'
29
+ outline 0
30
30
  }
31
31
  end
32
32
  end
@@ -15,10 +15,6 @@ class TodoList
15
15
 
16
16
  markup {
17
17
  main(class: 'main') {
18
- style <= [ presenter, :todos,
19
- on_read: ->(todos) { todos.empty? ? 'display: none;' : '' }
20
- ]
21
-
22
18
  div(class: 'toggle-all-container') {
23
19
  input(class: 'toggle-all', type: 'checkbox')
24
20
 
@@ -30,9 +26,9 @@ class TodoList
30
26
  }
31
27
 
32
28
  @todo_ul = ul {
33
- class_name <= [presenter, :filter,
34
- on_read: ->(filter) { "todo-list #{filter}" }
35
- ]
29
+ # class name is data-bound unidirectionally to the presenter filter attribute,
30
+ # meaning it would automatically get set to its value whenever presenter.filter changes
31
+ class_name <= [presenter, :filter]
36
32
 
37
33
  presenter.todos.each do |todo|
38
34
  todo_list_item(presenter:, todo:)
@@ -42,61 +38,61 @@ class TodoList
42
38
  }
43
39
 
44
40
  style {
45
- rule('.main') {
41
+ r('.main') {
46
42
  border_top '1px solid #e6e6e6'
47
- position 'relative'
43
+ position :relative
48
44
  z_index '2'
49
45
  }
50
46
 
51
- rule('.toggle-all') {
52
- border 'none'
47
+ r('.toggle-all') {
48
+ border :none
53
49
  bottom '100%'
54
- height '1px'
55
- opacity '0'
56
- position 'absolute'
50
+ height 1
51
+ opacity 0
52
+ position :absolute
57
53
  right '100%'
58
- width '1px'
54
+ width 1
59
55
  }
60
56
 
61
- rule('.toggle-all+label') {
62
- align_items 'center'
63
- display 'flex'
64
- font_size '0'
65
- height '65px'
66
- justify_content 'center'
67
- left '0'
68
- position 'absolute'
69
- top '-65px'
70
- width '45px'
57
+ r('.toggle-all+label') {
58
+ align_items :center
59
+ display :flex
60
+ font_size 0
61
+ height 65
62
+ justify_content :center
63
+ left 0
64
+ position :absolute
65
+ top -65
66
+ width 45
71
67
  }
72
68
 
73
- rule('.toggle-all+label:before') {
69
+ r('.toggle-all+label:before') {
74
70
  color '#949494'
75
71
  content '"❯"'
76
72
  display 'inline-block'
77
- font_size '22px'
73
+ font_size 22
78
74
  padding '10px 27px'
79
75
  _webkit_transform 'rotate(90deg)'
80
76
  transform 'rotate(90deg)'
81
77
  }
82
78
 
83
- rule('.toggle-all:focus+label, .toggle:focus+label') {
79
+ r('.toggle-all:focus+label, .toggle:focus+label') {
84
80
  box_shadow '0 0 2px 2px #cf7d7d'
85
- outline '0'
81
+ outline 0
86
82
  }
87
83
 
88
- rule('.todo-list') {
89
- list_style 'none'
90
- margin '0'
91
- padding '0'
84
+ r('.todo-list ul') {
85
+ list_style :none
86
+ margin 0
87
+ padding 0
92
88
  }
93
89
 
94
- rule('.todo-list.active li.completed') {
95
- display 'none'
90
+ r('.todo-list ul.active li.completed') {
91
+ display :none
96
92
  }
97
93
 
98
- rule('.todo-list.completed li.active') {
99
- display 'none'
94
+ r('.todo-list ul.completed li.active') {
95
+ display :none
100
96
  }
101
97
  }
102
98
  end