glimmer-dsl-web 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d0e231339d0d3cd0a330fce53e852109df1b4b7b306194cff98e8e2eecbbd39
4
- data.tar.gz: 384766d64c13a9724402021ea1ce47fae393bf66ccb4c56011a6e14e4c3fdefd
3
+ metadata.gz: 2615511253319f0227b782825764b4b009c0a3d4072b366d7409a3255f653d47
4
+ data.tar.gz: 0d09f5a38cd26cd6f8edad82aab884b89178ffa79043e5e7dc88fbd19f2e5958
5
5
  SHA512:
6
- metadata.gz: 1d127d5d4b7eed73f60940b8c669593fcace051c6eccd6a5e80bc9d759aedecec922ba2b701341b9fc043781d7d2e4d0e371cc967dd782f4c3ed228d7b68c748
7
- data.tar.gz: 9bb14fe78d3d4d6b7709429132c7b00bedb12d1183adcead609f88545b199174e7dda788241e41db63732551650064d77ec8794d3360c9c08c4c3719397a02a7
6
+ metadata.gz: 54ce5174ba09451931424f9c7d30b4abc7aebfd8486ecb6fe0863ece4a4747c908c9445753cc68e535bfb90835d1ad1951fde8f31f9fe2e90f34980754b4ecbf
7
+ data.tar.gz: d654378ed6fa4c7d05322c09054a44039d83ef2d4dcecc048963b2dc31c723a68c679072f71da2a1984ba94cd4630a382d363928ca57315ca673ae33dfe62d59
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.7
4
+
5
+ - Support input[type=number] value data-binding as a Ruby Numeric object (Integer or Float)
6
+ - Support input[type=range] value data-binding as a Ruby Numeric object (Integer or Float)
7
+ - Support input[type=datetime-local] value data-binding as a Ruby Time object
8
+ - Support input[type=date] value data-binding as a Ruby Date object
9
+ - Support input[type=time] value data-binding as a Ruby Time object
10
+ - Update Hello, Data-Binding! Sample to include a checkbox
11
+ - New Hello, Input (Date/Time)! Sample: `require 'glimmer-dsl-web/samples/hello/hello_input'`
12
+
3
13
  ## 0.0.6
4
14
 
5
15
  - Support attribute unidirectional/bidirectional data-binding
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2023 Andy Maleh
1
+ Copyright (c) 2023-2024 Andy Maleh
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,9 +1,9 @@
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.0.6 (Early Alpha)
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.0.7 (Early Alpha)
2
2
  ## Ruby in the Browser Web GUI Frontend Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-web.svg)](http://badge.fury.io/rb/glimmer-dsl-web)
4
4
  [![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)
5
5
 
6
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web enables building Web GUI frontends using [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), as per [Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby](https://youtu.be/knutsgHTrfQ?t=789). It aims at providing the simplest frontend library in existence. The library follows the Ruby way (with [DSLs](https://martinfowler.com/books/dsl.html) and [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI#English)) and the Rails way ([Convention over Configuration](https://rubyonrails.org/doctrine)) while supporting both Unidirectional (One-Way) Data-Binding (using `<=`) and Bidirectional (Two-Way) Data-Binding (using `<=>`). You can finally live in pure Rubyland on the Web in both the frontend and backend with [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web)!
6
+ [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web enables building Web GUI frontends using [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), as per [Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby](https://youtu.be/knutsgHTrfQ?t=789). It aims at providing the simplest, most intuitive, and most straight-forward frontend library in existence. The library follows the Ruby way (with [DSLs](https://martinfowler.com/books/dsl.html) and [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI#English)) and the Rails way ([Convention over Configuration](https://rubyonrails.org/doctrine)) while supporting both Unidirectional (One-Way) Data-Binding (using `<=`) and Bidirectional (Two-Way) Data-Binding (using `<=>`). You can finally live in pure Rubyland on the Web in both the frontend and backend with [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web)!
7
7
 
8
8
  **Hello, World! Sample**
9
9
 
@@ -222,6 +222,8 @@ Screenshot:
222
222
 
223
223
  **Hello, Data-Binding!**
224
224
 
225
+ [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) intuitively supports both Unidirectional (One-Way) Data-Binding via the `<=` operator and Bidirectional (Two-Way) Data-Binding via the `<=>` operator, incredibly simplifying how to sync View properties with Model attributes with the simplest code to reason about.
226
+
225
227
  Glimmer GUI code:
226
228
 
227
229
  ```ruby
@@ -239,7 +241,10 @@ Address = Struct.new(:street, :street2, :city, :state, :zip_code, keyword_init:
239
241
  end
240
242
 
241
243
  def summary
242
- values.map(&:to_s).reject(&:empty?).join(', ')
244
+ string_attributes = to_h.except(:billing_and_shipping)
245
+ summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
246
+ summary += " (Billing & Shipping)" if billing_and_shipping
247
+ summary
243
248
  end
244
249
  end
245
250
 
@@ -248,14 +253,15 @@ end
248
253
  street2: 'Apartment 3C, 2nd door to the right',
249
254
  city: 'San Diego',
250
255
  state: 'California',
251
- zip_code: '91911'
256
+ zip_code: '91911',
257
+ billing_and_shipping: true,
252
258
  )
253
259
 
254
260
  include Glimmer
255
261
 
256
262
  Document.ready? do
257
263
  div {
258
- form(style: 'display: grid; grid-auto-columns: 80px 200px;') { |address_form|
264
+ div(style: 'display: grid; grid-auto-columns: 80px 260px;') { |address_div|
259
265
  label('Street: ', for: 'street-field')
260
266
  input(id: 'street-field') {
261
267
  # Bidirectional Data-Binding with <=> ensures input.value and @address.street
@@ -289,16 +295,25 @@ Document.ready? do
289
295
  # on_write option specifies :to_s method to invoke on value before writing to model attribute
290
296
  # to ensure the numeric zip code value is stored as a String
291
297
  value <=> [@address, :zip_code,
292
- on_write: :to_s
298
+ on_write: :to_s,
293
299
  ]
294
300
  }
295
301
 
302
+ div(style: 'grid-column: 1 / span 2') {
303
+ input(id: 'billing-and-shipping-field', type: 'checkbox') {
304
+ checked <=> [@address, :billing_and_shipping]
305
+ }
306
+ label(for: 'billing-and-shipping-field') {
307
+ 'Use this address for both Billing & Shipping'
308
+ }
309
+ }
310
+
296
311
  style {
297
312
  <<~CSS
298
- .#{address_form.element_id} * {
313
+ #{address_div.selector} * {
299
314
  margin: 5px;
300
315
  }
301
- .#{address_form.element_id} input, .#{address_form.element_id} select {
316
+ #{address_div.selector} input, #{address_div.selector} select {
302
317
  grid-column: 2;
303
318
  }
304
319
  CSS
@@ -306,10 +321,12 @@ Document.ready? do
306
321
  }
307
322
 
308
323
  div(style: 'margin: 5px') {
309
- # Unidirectional Data-Binding is done with <= to ensure @address.summary changes update div.inner_text
310
- # as computed by changes to the address member attributes + state_code address custom attribute
324
+ # Unidirectional Data-Binding is done with <= to ensure @address.summary changes
325
+ # automatically update div.inner_text
326
+ # (computed by changes to address attributes, meaning if street changes,
327
+ # @address.summary is automatically recomputed.)
311
328
  inner_text <= [@address, :summary,
312
- computed_by: @address.members + ['state_code']
329
+ computed_by: @address.members + ['state_code'],
313
330
  ]
314
331
  }
315
332
  }.render
@@ -424,6 +441,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
424
441
  - [Hello, Button!](#hello-button)
425
442
  - [Hello, Form!](#hello-form)
426
443
  - [Hello, Data-Binding!](#hello-data-binding)
444
+ - [Hello, Input (Date/Time)!](#hello-input-datetime)
427
445
  - [Button Counter](#button-counter)
428
446
  - [Glimmer Process](#glimmer-process)
429
447
  - [Help](#help)
@@ -446,7 +464,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
446
464
 
447
465
  ## Setup
448
466
 
449
- (NOTE: Keep in mind this is a very early experimental and incomplete **alpha**. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
467
+ (NOTE: Keep in mind this is an Early Alpha. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
450
468
 
451
469
  The [glimmer-dsl-web](https://rubygems.org/gems/glimmer-dsl-web) gem is a [Rails Engine](https://guides.rubyonrails.org/engines.html) gem that includes assets.
452
470
 
@@ -473,7 +491,7 @@ gem 'opal', '1.4.1'
473
491
  gem 'opal-rails', '2.0.2'
474
492
  gem 'opal-async', '~> 1.4.0'
475
493
  gem 'opal-jquery', '~> 0.4.6'
476
- gem 'glimmer-dsl-web', '~> 0.0.6'
494
+ gem 'glimmer-dsl-web', '~> 0.0.7'
477
495
  gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
478
496
  gem 'glimmer-dsl-css', '~> 1.2.1', require: false
479
497
  ```
@@ -618,7 +636,7 @@ gem 'opal', '1.4.1'
618
636
  gem 'opal-rails', '2.0.2'
619
637
  gem 'opal-async', '~> 1.4.0'
620
638
  gem 'opal-jquery', '~> 0.4.6'
621
- gem 'glimmer-dsl-web', '~> 0.0.6'
639
+ gem 'glimmer-dsl-web', '~> 0.0.7'
622
640
  gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
623
641
  gem 'glimmer-dsl-css', '~> 1.2.1', require: false
624
642
  ```
@@ -1140,7 +1158,10 @@ Address = Struct.new(:street, :street2, :city, :state, :zip_code, keyword_init:
1140
1158
  end
1141
1159
 
1142
1160
  def summary
1143
- values.map(&:to_s).reject(&:empty?).join(', ')
1161
+ string_attributes = to_h.except(:billing_and_shipping)
1162
+ summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
1163
+ summary += " (Billing & Shipping)" if billing_and_shipping
1164
+ summary
1144
1165
  end
1145
1166
  end
1146
1167
 
@@ -1149,14 +1170,15 @@ end
1149
1170
  street2: 'Apartment 3C, 2nd door to the right',
1150
1171
  city: 'San Diego',
1151
1172
  state: 'California',
1152
- zip_code: '91911'
1173
+ zip_code: '91911',
1174
+ billing_and_shipping: true,
1153
1175
  )
1154
1176
 
1155
1177
  include Glimmer
1156
1178
 
1157
1179
  Document.ready? do
1158
1180
  div {
1159
- form(style: 'display: grid; grid-auto-columns: 80px 200px;') { |address_form|
1181
+ div(style: 'display: grid; grid-auto-columns: 80px 260px;') { |address_div|
1160
1182
  label('Street: ', for: 'street-field')
1161
1183
  input(id: 'street-field') {
1162
1184
  # Bidirectional Data-Binding with <=> ensures input.value and @address.street
@@ -1190,16 +1212,25 @@ Document.ready? do
1190
1212
  # on_write option specifies :to_s method to invoke on value before writing to model attribute
1191
1213
  # to ensure the numeric zip code value is stored as a String
1192
1214
  value <=> [@address, :zip_code,
1193
- on_write: :to_s
1215
+ on_write: :to_s,
1194
1216
  ]
1195
1217
  }
1196
1218
 
1219
+ div(style: 'grid-column: 1 / span 2') {
1220
+ input(id: 'billing-and-shipping-field', type: 'checkbox') {
1221
+ checked <=> [@address, :billing_and_shipping]
1222
+ }
1223
+ label(for: 'billing-and-shipping-field') {
1224
+ 'Use this address for both Billing & Shipping'
1225
+ }
1226
+ }
1227
+
1197
1228
  style {
1198
1229
  <<~CSS
1199
- .#{address_form.element_id} * {
1230
+ #{address_div.selector} * {
1200
1231
  margin: 5px;
1201
1232
  }
1202
- .#{address_form.element_id} input, .#{address_form.element_id} select {
1233
+ #{address_div.selector} input, #{address_div.selector} select {
1203
1234
  grid-column: 2;
1204
1235
  }
1205
1236
  CSS
@@ -1207,10 +1238,12 @@ Document.ready? do
1207
1238
  }
1208
1239
 
1209
1240
  div(style: 'margin: 5px') {
1210
- # Unidirectional Data-Binding is done with <= to ensure @address.summary changes update div.inner_text
1211
- # as computed by changes to the address member attributes + state_code address custom attribute
1241
+ # Unidirectional Data-Binding is done with <= to ensure @address.summary changes
1242
+ # automatically update div.inner_text
1243
+ # (computed by changes to address attributes, meaning if street changes,
1244
+ # @address.summary is automatically recomputed.)
1212
1245
  inner_text <= [@address, :summary,
1213
- computed_by: @address.members + ['state_code']
1246
+ computed_by: @address.members + ['state_code'],
1214
1247
  ]
1215
1248
  }
1216
1249
  }.render
@@ -1221,6 +1254,113 @@ Screenshot:
1221
1254
 
1222
1255
  ![Hello, Data-Binding!](/images/glimmer-dsl-web-samples-hello-hello-data-binding.gif)
1223
1256
 
1257
+ #### Hello, Input (Date/Time)!
1258
+
1259
+ Glimmer GUI code:
1260
+
1261
+ ```ruby
1262
+ require 'glimmer-dsl-web'
1263
+
1264
+ class TimePresenter
1265
+ attr_accessor :date_time, :month_string, :week_string
1266
+
1267
+ def initialize
1268
+ @date_time = Time.now
1269
+ end
1270
+
1271
+ def month_string
1272
+ @date_time&.strftime('%Y-%m')
1273
+ end
1274
+
1275
+ def month_string=(value)
1276
+ if value.match(/^\d{4}-\d{2}$/)
1277
+ year, month = value.split('-')
1278
+ self.date_time = Time.new(year, month, date_time.day, date_time.hour, date_time.min)
1279
+ end
1280
+ end
1281
+
1282
+ def week_string
1283
+ return nil if @date_time.nil?
1284
+ year = @date_time.year
1285
+ week = ((@date_time.yday / 7).to_i + 1).to_s.rjust(2, '0')
1286
+ "#{year}-W#{week}"
1287
+ end
1288
+
1289
+ def date_time_string
1290
+ @date_time&.strftime('%Y-%m-%dT%H:%M')
1291
+ end
1292
+
1293
+ def date_time_string=(value)
1294
+ if value.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/)
1295
+ date_time_parts = value.split('T')
1296
+ date_parts = date_time_parts.first.split('-')
1297
+ time_parts = date_time_parts.last.split(':')
1298
+ self.date_time = Time.new(*date_parts, *time_parts)
1299
+ end
1300
+ end
1301
+ end
1302
+
1303
+ @time_presenter = TimePresenter.new
1304
+
1305
+ include Glimmer
1306
+
1307
+ Document.ready? do
1308
+ div {
1309
+ div(style: 'display: grid; grid-auto-columns: 130px 260px;') { |container_div|
1310
+ label('Date Time: ', for: 'date-time-field')
1311
+ input(id: 'date-time-field', type: 'datetime-local') {
1312
+ # Bidirectional Data-Binding with <=> ensures input.value and @time_presenter.date_time
1313
+ # automatically stay in sync when either side changes
1314
+ value <=> [@time_presenter, :date_time]
1315
+ }
1316
+
1317
+ label('Date: ', for: 'date-field')
1318
+ input(id: 'date-field', type: 'date') {
1319
+ value <=> [@time_presenter, :date_time]
1320
+ }
1321
+
1322
+ label('Time: ', for: 'time-field')
1323
+ input(id: 'time-field', type: 'time') {
1324
+ value <=> [@time_presenter, :date_time]
1325
+ }
1326
+
1327
+ label('Month: ', for: 'month-field')
1328
+ input(id: 'month-field', type: 'month') {
1329
+ value <=> [@time_presenter, :month_string, computed_by: :date_time]
1330
+ }
1331
+
1332
+ label('Week: ', for: 'week-field')
1333
+ input(id: 'week-field', type: 'week', disabled: true) {
1334
+ value <=> [@time_presenter, :week_string, computed_by: :date_time]
1335
+ }
1336
+
1337
+ label('Time String: ', for: 'time-string-field')
1338
+ input(id: 'time-string-field', type: 'text') {
1339
+ value <=> [@time_presenter, :date_time_string, computed_by: :date_time]
1340
+ }
1341
+
1342
+ style {
1343
+ <<~CSS
1344
+ #{container_div.selector} * {
1345
+ margin: 5px;
1346
+ }
1347
+ #{container_div.selector} label {
1348
+ grid-column: 1;
1349
+ }
1350
+ #{container_div.selector} input {
1351
+ grid-column: 2;
1352
+ }
1353
+ CSS
1354
+ }
1355
+ }
1356
+ }.render
1357
+ end
1358
+ ```
1359
+
1360
+ Screenshot:
1361
+
1362
+ ![Hello, Input (Date/Time)!](/images/glimmer-dsl-web-samples-hello-hello-input-date-time.gif)
1363
+
1224
1364
  #### Button Counter
1225
1365
 
1226
1366
  **UPCOMING (NOT RELEASED OR SUPPORTED YET)**
@@ -1351,7 +1491,7 @@ These features have been suggested. You might see them in a future version of Gl
1351
1491
 
1352
1492
  [MIT](https://opensource.org/licenses/MIT)
1353
1493
 
1354
- Copyright (c) 2023 - Andy Maleh.
1494
+ Copyright (c) 2023-2024 - Andy Maleh.
1355
1495
  See [LICENSE.txt](LICENSE.txt) for further details.
1356
1496
 
1357
1497
  --
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -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.0.6 ruby lib
5
+ # stub: glimmer-dsl-web 0.0.7 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-web".freeze
9
- s.version = "0.0.6".freeze
9
+ s.version = "0.0.7".freeze
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-01-01"
14
+ s.date = "2024-01-02"
15
15
  s.description = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library) - Enables frontend GUI development with Ruby by adopting a DSL that follows web-like HTML syntax, enabling the transfer of HTML/CSS/JS skills to Ruby frontend development. This library relies on Opal Ruby.".freeze
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  "lib/glimmer-dsl-web/samples/hello/hello_button.rb",
34
34
  "lib/glimmer-dsl-web/samples/hello/hello_data_binding.rb",
35
35
  "lib/glimmer-dsl-web/samples/hello/hello_form.rb",
36
+ "lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb",
36
37
  "lib/glimmer-dsl-web/samples/hello/hello_world.rb",
37
38
  "lib/glimmer-dsl-web/vendor/jquery.js",
38
39
  "lib/glimmer/config/opal_logger.rb",
@@ -51,8 +52,7 @@ Gem::Specification.new do |s|
51
52
  "lib/glimmer/web.rb",
52
53
  "lib/glimmer/web/element_proxy.rb",
53
54
  "lib/glimmer/web/event_proxy.rb",
54
- "lib/glimmer/web/listener_proxy.rb",
55
- "lib/glimmer/web/property_owner.rb"
55
+ "lib/glimmer/web/listener_proxy.rb"
56
56
  ]
57
57
  s.homepage = "http://github.com/AndyObtiva/glimmer-dsl-web".freeze
58
58
  s.licenses = ["MIT".freeze]
@@ -24,7 +24,7 @@ module Glimmer
24
24
  end
25
25
 
26
26
  def call(value)
27
- converted_value = translated_value = @translator.call(value)
27
+ converted_value = translated_value = @translator.call(value, evaluate_property)
28
28
  @element.send("#{@property}=", converted_value) unless evaluate_property == converted_value
29
29
  end
30
30
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 Andy Maleh
1
+ # Copyright (c) 2023-2024 Andy Maleh
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2023 Andy Maleh
1
+ # Copyright (c) 2023-2024 Andy Maleh
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the