Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AndyObtiva/b052aef7fc9ec8da80eab76d482ccaec to your computer and use it in GitHub Desktop.
Save AndyObtiva/b052aef7fc9ec8da80eab76d482ccaec to your computer and use it in GitHub Desktop.
Glimmer DSL for Web - Regular Sample - Todo MVC - Views - TodoListItem
# Source: https://github.com/AndyObtiva/glimmer-dsl-web/blob/master/lib/glimmer-dsl-web/samples/regular/todo_mvc/views/todo_list_item.rb
require_relative 'edit_todo_input'
class TodoListItem
include Glimmer::Web::Component
option :presenter
option :todo
markup {
li {
# It is possible to configure multiple data-bindings as done with class_name below
# Data-bind li class unidirectionally to `todo.completed` using `on_read` converter
# to convert `todo.completed` value and produce final value to update li class with
# using li_class_name method defined below.
class_name <= [ todo, :completed,
on_read: -> (completed) { li_class_name(todo) }
]
# Data-bind li class unidirectionally to `todo.editing` using `on_read` converter
# to convert `todo.editing` value and produce final value to update li class with
# using li_class_name method defined below.
class_name <= [ todo, :editing,
on_read: -> (editing) { li_class_name(todo) }
]
div(class: 'view') {
input(class: 'toggle', type: 'checkbox') {
# Data-bind `input` `checked` property bidirectionally to `todo` `completed` attribute
# meaning make any changes to the `todo` `completed` attribute value automatically update the `input` `checked` property
# and any changes to the `input` `checked` property by the user automatically update the `todo` `completed` attribute value.
# `after_write` hook is invoked after writing a new value to the model attribute (`todo` `completed` attribute)
checked <=> [ todo, :completed,
after_write: -> (_) { presenter.refresh_todos_with_filter if presenter.filter != :all }
]
}
label {
# Data-bind `label` inner HTML unidirectionally to `todo.task` (`String` value),
# meaning make changes to `todo` `task` attribute automatically update `label` inner HTML.
inner_html <= [todo, :task]
ondblclick do |event|
todo.start_editing
end
}
button(class: 'destroy') {
onclick do |event|
presenter.destroy(todo)
end
}
}
edit_todo_input(presenter:, todo:)
if todo == presenter.todos.first
style {
todo_list_item_styles
}
end
}
}
def li_class_name(todo)
classes = []
classes << 'completed' if todo.completed?
classes << 'editing' if todo.editing?
classes.join(' ')
end
def todo_list_item_styles
rule('.todo-list li.completed label') {
color '#949494'
text_decoration 'line-through'
}
rule('.todo-list li') {
border_bottom '1px solid #ededed'
font_size '24px'
position 'relative'
}
rule('.todo-list li .toggle') {
_webkit_appearance 'none'
appearance 'none'
border 'none'
bottom '0'
height 'auto'
margin 'auto 0'
opacity '0'
position 'absolute'
text_align 'center'
top '0'
width '40px'
}
rule('.todo-list li label') {
color '#484848'
display 'block'
font_weight '400'
line_height '1.2'
min_height '40px'
padding '15px 15px 15px 60px'
transition 'color .4s'
word_break 'break-all'
}
rule('.todo-list li .toggle+label') {
background_image 'url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E)'
background_position '0'
background_repeat 'no-repeat'
}
rule('.todo-list li.completed label') {
color '#949494'
text_decoration 'line-through'
}
rule('.todo-list li .toggle:checked+label') {
background_image 'url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E)'
}
rule('.todo-list li.editing') {
border_bottom 'none'
padding '0'
}
rule('.todo-list li.editing input[type=checkbox], .todo-list li.editing label') {
opacity '0'
}
rule('.todo-list li .destroy') {
bottom '0'
color '#949494'
display 'none'
font_size '30px'
height '40px'
margin 'auto 0'
position 'absolute'
right '10px'
top '0'
transition 'color .2s ease-out'
width '40px'
}
rule('.todo-list li:focus .destroy, .todo-list li:hover .destroy') {
display 'block'
}
rule('.todo-list li .destroy:focus, .todo-list li .destroy:hover') {
color '#c18585'
}
rule('.todo-list li .destroy:after') {
content '"×"'
display 'block'
height '100%'
line_height '1.1'
}
media ('screen and (-webkit-min-device-pixel-ratio: 0)') {
rule('.todo-list li .toggle, .toggle-all') {
background 'none'
}
rule('.todo-list li .toggle') {
height '40px'
}
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment