glimmer-dsl-web 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -2
- data/README.md +10 -6
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +3 -3
- data/lib/glimmer/web/element_proxy.rb +12 -8
- data/lib/glimmer-dsl-web/samples/hello/hello_style.rb +61 -33
- data/lib/glimmer-dsl-web/samples/regular/todo_mvc/views/new_todo_input.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a248314a1dcc33c038a9d2f542dce35d31d7d5702435a1c8db5b13b75068470
|
4
|
+
data.tar.gz: 8d83a134edc023c5ec2debe421a7f45e11887671b918ba75532574bf3019525a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64e47e6380713ca42182644f9b20b0f4137deaf951707413d49f3909346be470e66426f09aa5f3a67656808b3bfb3e07bc00ee27a8c54167ec3cbb80f254972e
|
7
|
+
data.tar.gz: d55f560a40cb259fa0b28ee82be1cb066efe26aa4d44f749ec05bcb97ba1f5ff735a44a252100fa8565a8338aa9b53bab0f77c6719e12061f40d40e18b1abb04
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.4.1
|
4
|
+
|
5
|
+
- Enhance Hello, Style! sample to allow setting styled button background color
|
6
|
+
- Fixed issue with `Glimmer::Web::Component::component_element_class` not working in components when programmatically changing the component markup root CSS class
|
7
|
+
|
3
8
|
## 0.4.0
|
4
9
|
|
5
|
-
- Support `style {}` block in `Glimmer::Web::Component` that would automatically add style in one place for all
|
10
|
+
- Support `style {}` block in `Glimmer::Web::Component` that would automatically add style in one place for all component instances
|
11
|
+
- Support `Glimmer::Web::Component::component_element_class` to return CSS class automatically generated for a component based on its name (e.g. `StyledButton` gets `styled-button` CSS class)
|
12
|
+
- Hello, Style! Sample: `require 'glimmer-dsl-web/samples/hello/hello_style'`
|
6
13
|
- Upgrade to Glimmer DSL for CSS 1.5.0
|
7
14
|
- Remove support for including multiple `before_render` and `after_render` blocks in a component as it is not needed and can be confusing
|
8
|
-
- Hello, Style! Sample: `require 'glimmer-dsl-web/samples/hello/hello_style'`
|
9
15
|
- Optimize performance of Todo MVC by not adding an edit input field to every todo, yet adding it only upon editing a todo.
|
10
16
|
- Fix issue with `ElementProxy#add_css_class` and `ElementProxy#remove_css_class` crashing if called before rendering an element
|
11
17
|
- Fix issue with Hello, Observer (Data-Binding)! crashing if run after Hello, Observer! due to both samples sharing the same class by mistake
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.4.
|
2
|
-
## Ruby
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.4.1 (Beta)
|
2
|
+
## Ruby-in-the-Browser Web Frontend Framework
|
3
3
|
### Finally, Ruby Developer Productivity, Happiness, and Fun in the Frontend!!!
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-web.svg)](http://badge.fury.io/rb/glimmer-dsl-web)
|
5
5
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
**(Talk Videos: [Intro to Ruby in the Browser](https://youtu.be/4AdcfbI6A4c?si=MmxOrkhIXTDHQoYi) & [Frontend Ruby with Glimmer DSL for Web](https://youtu.be/rIZ-ILUv9ME?si=raygUXVPd_7ypWuE))**
|
10
10
|
|
11
|
-
[![Todo MVC](/images/glimmer-dsl-web-samples-regular-todo-mvc.gif)](
|
11
|
+
[![Todo MVC](/images/glimmer-dsl-web-samples-regular-todo-mvc.gif)](https://sample-glimmer-dsl-web-rails7-app-black-sound-6793.fly.dev/)
|
12
12
|
|
13
13
|
You can finally have Ruby developer happiness and productivity in the Frontend! No more wasting time splitting your resources across multiple languages, using badly engineered, over-engineered, or premature-optimization-obsessed JavaScript libraries, fighting JavaScript build issues (e.g. webpack), or rewriting Ruby Backend code in Frontend JavaScript. With [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), you can have an exponential jump in development productivity (2x or higher), time-to-release (1/2 or less time), cost (1/2 or cheaper), and maintainability (~50% the code that is simpler and more readable) over JavaScript libraries like React, Angular, Ember, Vue, and Svelte, while being able to reuse Backend Ruby code as is in the Frontend for faster interactions when needed. Also, with Frontend Ruby, companies can cut their hiring budget in half by having Backend Ruby Software Engineers do Frontend Development in Ruby! [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c) finally fulfills every smart highly-productive Rubyist's dream by bringing Ruby productivity fun to Frontend Development, the same productivity fun you had for years and decades in Backend Development.
|
14
14
|
|
@@ -1391,7 +1391,7 @@ rails new glimmer_app_server
|
|
1391
1391
|
Add the following to `Gemfile`:
|
1392
1392
|
|
1393
1393
|
```
|
1394
|
-
gem 'glimmer-dsl-web', '~> 0.4.
|
1394
|
+
gem 'glimmer-dsl-web', '~> 0.4.1'
|
1395
1395
|
```
|
1396
1396
|
|
1397
1397
|
Run:
|
@@ -1620,7 +1620,7 @@ Disable the `webpacker` gem line in `Gemfile`:
|
|
1620
1620
|
Add the following to `Gemfile`:
|
1621
1621
|
|
1622
1622
|
```ruby
|
1623
|
-
gem 'glimmer-dsl-web', '~> 0.4.
|
1623
|
+
gem 'glimmer-dsl-web', '~> 0.4.1'
|
1624
1624
|
```
|
1625
1625
|
|
1626
1626
|
Run:
|
@@ -1881,7 +1881,11 @@ This external Sample Selector app is built using Rails and Glimmer DSL for Web,
|
|
1881
1881
|
|
1882
1882
|
https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app
|
1883
1883
|
|
1884
|
-
|
1884
|
+
A deployed version of the Sample Selector app can be accessed over here:
|
1885
|
+
|
1886
|
+
https://sample-glimmer-dsl-web-rails7-app-black-sound-6793.fly.dev/
|
1887
|
+
|
1888
|
+
[![Sample Selector](https://raw.githubusercontent.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app/master/sample-glimmer-dsl-web-rails7-app.png)](https://sample-glimmer-dsl-web-rails7-app-black-sound-6793.fly.dev/)
|
1885
1889
|
|
1886
1890
|
### Hello Samples
|
1887
1891
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.1
|
data/glimmer-dsl-web.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-web 0.4.
|
5
|
+
# stub: glimmer-dsl-web 0.4.1 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
9
|
-
s.version = "0.4.
|
9
|
+
s.version = "0.4.1"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "2024-07-
|
14
|
+
s.date = "2024-07-27"
|
15
15
|
s.description = "Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework) enables building Web Frontends using Ruby in the Browser, as per Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend framework in existence. The framework follows the Ruby way (with DSLs and TIMTOWTDI) and the Rails way (Convention over Configuration) in building Isomorphic Ruby on Rails Applications. It provides a Ruby HTML DSL, which uniquely enables writing both structure code and logic code in one language. It supports both Unidirectional (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via Content Data-Binding. Modular design is supported with Glimmer Web Components. And, a Ruby CSS DSL is supported with the included Glimmer DSL for CSS. Many samples are demonstrated in the Rails sample app (there is a very minimal Standalone [No Rails] sample app too). You can finally live in pure Rubyland on the Web in both the frontend and backend with Glimmer DSL for Web! This gem relies on Opal Ruby.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -372,12 +372,7 @@ module Glimmer
|
|
372
372
|
end
|
373
373
|
|
374
374
|
def html_options
|
375
|
-
|
376
|
-
if component
|
377
|
-
framework_css_classes.prepend(component.class.component_element_class)
|
378
|
-
framework_css_classes.prepend(component.class.component_shortcut_element_class) if component.class.component_shortcut_element_class != component.class.component_element_class
|
379
|
-
end
|
380
|
-
body_class = (framework_css_classes + css_classes.to_a).join(' ')
|
375
|
+
body_class = (base_css_classes + css_classes.to_a).uniq.compact.join(' ')
|
381
376
|
html_options = options.dup
|
382
377
|
GLIMMER_ATTRIBUTES.each do |attribute|
|
383
378
|
next unless html_options.include?(attribute)
|
@@ -416,8 +411,8 @@ module Glimmer
|
|
416
411
|
|
417
412
|
def class_name=(value)
|
418
413
|
if rendered?
|
419
|
-
|
420
|
-
new_class_name =
|
414
|
+
values = value.is_a?(Array) ? value : [value.to_s]
|
415
|
+
new_class_name = (base_css_classes + values).uniq.compact.join(' ')
|
421
416
|
dom_element.prop('className', new_class_name)
|
422
417
|
else
|
423
418
|
enqueue_post_render_method_call('class_name=', value)
|
@@ -831,6 +826,15 @@ module Glimmer
|
|
831
826
|
|
832
827
|
private
|
833
828
|
|
829
|
+
def base_css_classes
|
830
|
+
framework_css_classes = [name, element_id]
|
831
|
+
if component
|
832
|
+
framework_css_classes.prepend(component.class.component_element_class)
|
833
|
+
framework_css_classes.prepend(component.class.component_shortcut_element_class) if component.class.component_shortcut_element_class != component.class.component_element_class
|
834
|
+
end
|
835
|
+
framework_css_classes
|
836
|
+
end
|
837
|
+
|
834
838
|
def valid_js_date_string?(string)
|
835
839
|
[REGEX_FORMAT_DATETIME, REGEX_FORMAT_DATE, REGEX_FORMAT_TIME].any? do |format|
|
836
840
|
string.match(format)
|
@@ -22,6 +22,7 @@
|
|
22
22
|
require 'glimmer-dsl-web'
|
23
23
|
|
24
24
|
class ButtonModel
|
25
|
+
BUTTON_STYLE_ATTRIBUTES = [:width, :height, :font_size, :background_color]
|
25
26
|
WIDTH_MIN = 160
|
26
27
|
WIDTH_MAX = 960
|
27
28
|
HEIGHT_MIN = 100
|
@@ -29,13 +30,14 @@ class ButtonModel
|
|
29
30
|
FONT_SIZE_MIN = 40
|
30
31
|
FONT_SIZE_MAX = 200
|
31
32
|
|
32
|
-
attr_accessor :text, :pushed,
|
33
|
+
attr_accessor :text, :pushed, *BUTTON_STYLE_ATTRIBUTES
|
33
34
|
|
34
35
|
def initialize
|
35
36
|
@text = 'Push'
|
36
37
|
@width = WIDTH_MIN
|
37
38
|
@height = HEIGHT_MIN
|
38
39
|
@font_size = FONT_SIZE_MIN
|
40
|
+
@background_color = '#add8e6'
|
39
41
|
end
|
40
42
|
|
41
43
|
def push
|
@@ -61,6 +63,16 @@ class ButtonModel
|
|
61
63
|
self.width = @font_size*4 if @height < @font_size*4
|
62
64
|
self.height = @font_size*2.5 if @height < @font_size*2.5
|
63
65
|
end
|
66
|
+
|
67
|
+
def border_color
|
68
|
+
red = background_color[1..2].hex
|
69
|
+
green = background_color[3..4].hex
|
70
|
+
blue = background_color[5..6].hex
|
71
|
+
new_red = red - 10
|
72
|
+
new_green = green - 10
|
73
|
+
new_blue = blue - 10
|
74
|
+
"##{new_red.to_s(16)}#{new_green.to_s(16)}#{new_blue.to_s(16)}"
|
75
|
+
end
|
64
76
|
end
|
65
77
|
|
66
78
|
class StyledButton
|
@@ -76,17 +88,11 @@ class StyledButton
|
|
76
88
|
on_read: ->(pushed) { pushed ? 'pushed' : 'pulled' }
|
77
89
|
]
|
78
90
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
on_read: method(:button_style_value) # convert value on read before storing in style
|
85
|
-
]
|
86
|
-
|
87
|
-
style <= [ button_model, :font_size,
|
88
|
-
on_read: method(:button_style_value) # convert value on read before storing in style
|
89
|
-
]
|
91
|
+
ButtonModel::BUTTON_STYLE_ATTRIBUTES.each do |attribute|
|
92
|
+
style <= [ button_model, attribute,
|
93
|
+
on_read: method(:button_style_value) # convert value on read before storing in style
|
94
|
+
]
|
95
|
+
end
|
90
96
|
|
91
97
|
onclick do
|
92
98
|
button_model.push
|
@@ -94,30 +100,30 @@ class StyledButton
|
|
94
100
|
}
|
95
101
|
}
|
96
102
|
|
97
|
-
style {
|
98
|
-
|
103
|
+
style {"
|
104
|
+
.#{component_element_class} {
|
99
105
|
font-family: Courrier New, Courrier;
|
100
106
|
border-radius: 5px;
|
101
107
|
border-width: 17px;
|
102
|
-
border-color: #ACC7D5;
|
103
|
-
background-color: #ADD8E6;
|
104
108
|
margin: 5px;
|
105
109
|
}
|
106
110
|
|
107
|
-
|
111
|
+
.#{component_element_class}.pulled {
|
108
112
|
border-style: outset;
|
109
113
|
}
|
110
114
|
|
111
|
-
|
115
|
+
.#{component_element_class}.pushed {
|
112
116
|
border-style: inset;
|
113
117
|
}
|
114
|
-
|
118
|
+
"}
|
115
119
|
|
116
120
|
def button_style_value
|
117
121
|
"
|
118
122
|
width: #{button_model.width}px;
|
119
123
|
height: #{button_model.height}px;
|
120
124
|
font-size: #{button_model.font_size}px;
|
125
|
+
background-color: #{button_model.background_color};
|
126
|
+
border-color: #{button_model.border_color};
|
121
127
|
"
|
122
128
|
end
|
123
129
|
end
|
@@ -137,6 +143,19 @@ class StyledButtonRangeInput
|
|
137
143
|
}
|
138
144
|
end
|
139
145
|
|
146
|
+
class StyledButtonColorInput
|
147
|
+
include Glimmer::Web::Component
|
148
|
+
|
149
|
+
option :button_model
|
150
|
+
option :property
|
151
|
+
|
152
|
+
markup {
|
153
|
+
input(type: 'color') {
|
154
|
+
value <=> [button_model, property]
|
155
|
+
}
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
140
159
|
class HelloStyle
|
141
160
|
include Glimmer::Web::Component
|
142
161
|
|
@@ -145,32 +164,41 @@ class HelloStyle
|
|
145
164
|
end
|
146
165
|
|
147
166
|
markup {
|
148
|
-
div
|
149
|
-
div(class: 'form
|
150
|
-
label('Styled Button Width:', for: 'styled-button-width-input')
|
167
|
+
div {
|
168
|
+
div(class: 'styled-button-form') {
|
169
|
+
label('Styled Button Width:', class: 'property-label', for: 'styled-button-width-input')
|
151
170
|
styled_button_range_input(button_model: @button_model, property: :width, property_min: ButtonModel::WIDTH_MIN, property_max: ButtonModel::WIDTH_MAX, id: 'styled-button-width-input')
|
152
|
-
|
153
|
-
|
154
|
-
label('Styled Button Height:', for: 'styled-button-height-input')
|
171
|
+
|
172
|
+
label('Styled Button Height:', class: 'property-label', for: 'styled-button-height-input')
|
155
173
|
styled_button_range_input(button_model: @button_model, property: :height, property_min: ButtonModel::HEIGHT_MIN, property_max: ButtonModel::HEIGHT_MAX, id: 'styled-button-height-input')
|
156
|
-
|
157
|
-
|
158
|
-
label('Styled Button Font Size:', for: 'styled-button-font-size-input')
|
174
|
+
|
175
|
+
label('Styled Button Font Size:', class: 'property-label', for: 'styled-button-font-size-input')
|
159
176
|
styled_button_range_input(button_model: @button_model, property: :font_size, property_min: ButtonModel::FONT_SIZE_MIN, property_max: ButtonModel::FONT_SIZE_MAX, id: 'styled-button-font-size-input')
|
177
|
+
|
178
|
+
label('Styled Button Background Color:', for: 'styled-button-background-color-input')
|
179
|
+
styled_button_color_input(button_model: @button_model, property: :background_color, id: 'styled-button-background-color-input')
|
160
180
|
}
|
181
|
+
|
161
182
|
styled_button(button_model: @button_model)
|
162
183
|
}
|
163
184
|
}
|
164
185
|
|
165
|
-
style {
|
166
|
-
.
|
186
|
+
style {"
|
187
|
+
.styled-button-form {
|
167
188
|
padding: 20px;
|
189
|
+
display: inline-grid;
|
190
|
+
grid-template-columns: auto auto;
|
191
|
+
}
|
192
|
+
|
193
|
+
.styled-button-form label, input {
|
194
|
+
display: block;
|
195
|
+
margin: 5px 5px 5px 0;
|
168
196
|
}
|
169
197
|
|
170
|
-
|
171
|
-
|
198
|
+
.#{component_element_class} .styled-button {
|
199
|
+
display: block;
|
172
200
|
}
|
173
|
-
|
201
|
+
"}
|
174
202
|
end
|
175
203
|
|
176
204
|
Document.ready? do
|
@@ -3,7 +3,7 @@ require_relative 'todo_input'
|
|
3
3
|
class NewTodoInput < TodoInput
|
4
4
|
option :presenter
|
5
5
|
|
6
|
-
markup { # evaluated against instance as a smart
|
6
|
+
markup { # evaluated against instance as a smart convention
|
7
7
|
input(placeholder: "What needs to be done?", autofocus: "") {
|
8
8
|
value <=> [presenter.new_todo, :task]
|
9
9
|
|
@@ -13,10 +13,10 @@ class NewTodoInput < TodoInput
|
|
13
13
|
}
|
14
14
|
}
|
15
15
|
|
16
|
-
style { # evaluated against class as a smart
|
16
|
+
style { # evaluated against class as a smart convention (common to all instances)
|
17
17
|
todo_input_styles
|
18
18
|
|
19
|
-
rule(".#{component_element_class}") { #
|
19
|
+
rule(".#{component_element_class}") { # NewTodoInput has component_element_class as 'new-todo-input'
|
20
20
|
padding '16px 16px 16px 60px'
|
21
21
|
height '65px'
|
22
22
|
border 'none'
|
@@ -24,7 +24,7 @@ class NewTodoInput < TodoInput
|
|
24
24
|
box_shadow 'inset 0 -2px 1px rgba(0,0,0,0.03)'
|
25
25
|
}
|
26
26
|
|
27
|
-
rule(".#{component_element_class}::placeholder") {
|
27
|
+
rule(".#{component_element_class}::placeholder") {
|
28
28
|
font_style 'italic'
|
29
29
|
font_weight '400'
|
30
30
|
color 'rgba(0, 0, 0, 0.4)'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|