glimmer-dsl-web 0.0.6 → 0.0.7

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.
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