Last active
June 26, 2024 19:39
-
-
Save AndyObtiva/b052aef7fc9ec8da80eab76d482ccaec to your computer and use it in GitHub Desktop.
Glimmer DSL for Web - Regular Sample - Todo MVC - Views - TodoListItem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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