glimmer-dsl-web 0.6.1 → 0.6.2

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.
@@ -0,0 +1,349 @@
1
+ # Copyright (c) 2023-2024 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-web'
23
+
24
+ unless Object.const_defined?(:Address)
25
+ Address = Struct.new(:full_name, :street, :street2, :city, :state, :zip_code, :billing_and_shipping, keyword_init: true) do
26
+ STATES = {
27
+ "AK"=>"Alaska", "AL"=>"Alabama", "AR"=>"Arkansas", "AS"=>"American Samoa", "AZ"=>"Arizona",
28
+ "CA"=>"California", "CO"=>"Colorado", "CT"=>"Connecticut", "DC"=>"District of Columbia", "DE"=>"Delaware",
29
+ "FL"=>"Florida", "GA"=>"Georgia", "GU"=>"Guam", "HI"=>"Hawaii", "IA"=>"Iowa", "ID"=>"Idaho", "IL"=>"Illinois",
30
+ "IN"=>"Indiana", "KS"=>"Kansas", "KY"=>"Kentucky", "LA"=>"Louisiana", "MA"=>"Massachusetts", "MD"=>"Maryland",
31
+ "ME"=>"Maine", "MI"=>"Michigan", "MN"=>"Minnesota", "MO"=>"Missouri", "MS"=>"Mississippi", "MT"=>"Montana",
32
+ "NC"=>"North Carolina", "ND"=>"North Dakota", "NE"=>"Nebraska", "NH"=>"New Hampshire", "NJ"=>"New Jersey",
33
+ "NM"=>"New Mexico", "NV"=>"Nevada", "NY"=>"New York", "OH"=>"Ohio", "OK"=>"Oklahoma", "OR"=>"Oregon",
34
+ "PA"=>"Pennsylvania", "PR"=>"Puerto Rico", "RI"=>"Rhode Island", "SC"=>"South Carolina", "SD"=>"South Dakota",
35
+ "TN"=>"Tennessee", "TX"=>"Texas", "UT"=>"Utah", "VA"=>"Virginia", "VI"=>"Virgin Islands", "VT"=>"Vermont",
36
+ "WA"=>"Washington", "WI"=>"Wisconsin", "WV"=>"West Virginia", "WY"=>"Wyoming"
37
+ }
38
+
39
+ def state_code
40
+ STATES.invert[state]
41
+ end
42
+
43
+ def state_code=(value)
44
+ self.state = STATES[value]
45
+ end
46
+
47
+ def summary
48
+ string_attributes = to_h.except(:billing_and_shipping)
49
+ summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
50
+ summary += " (Billing & Shipping)" if billing_and_shipping
51
+ summary
52
+ end
53
+ end
54
+ end
55
+
56
+ unless Object.const_defined?(:AddressForm)
57
+ # AddressForm Glimmer Web Component (View component)
58
+ #
59
+ # Including Glimmer::Web::Component makes this class a View component and automatically
60
+ # generates a new Glimmer HTML DSL keyword that matches the lowercase underscored version
61
+ # of the name of the class. AddressForm generates address_form keyword, which can be used
62
+ # elsewhere in Glimmer HTML DSL code as done inside HelloComponentListenersDefaultSlot below.
63
+ class AddressForm
64
+ include Glimmer::Web::Component
65
+
66
+ option :address
67
+
68
+ markup {
69
+ div {
70
+ div(style: {display: :grid, grid_auto_columns: '80px 260px'}) { |address_div|
71
+ label('Full Name: ', for: 'full-name-field')
72
+ input(id: 'full-name-field') {
73
+ value <=> [address, :full_name]
74
+ }
75
+
76
+ label('Street: ', for: 'street-field')
77
+ input(id: 'street-field') {
78
+ value <=> [address, :street]
79
+ }
80
+
81
+ label('Street 2: ', for: 'street2-field')
82
+ textarea(id: 'street2-field') {
83
+ value <=> [address, :street2]
84
+ }
85
+
86
+ label('City: ', for: 'city-field')
87
+ input(id: 'city-field') {
88
+ value <=> [address, :city]
89
+ }
90
+
91
+ label('State: ', for: 'state-field')
92
+ select(id: 'state-field') {
93
+ Address::STATES.each do |state_code, state|
94
+ option(value: state_code) { state }
95
+ end
96
+
97
+ value <=> [address, :state_code]
98
+ }
99
+
100
+ label('Zip Code: ', for: 'zip-code-field')
101
+ input(id: 'zip-code-field', type: 'number', min: '0', max: '99999') {
102
+ value <=> [address, :zip_code,
103
+ on_write: :to_s,
104
+ ]
105
+ }
106
+
107
+ style {
108
+ r("#{address_div.selector} *") {
109
+ margin '5px'
110
+ }
111
+ r("#{address_div.selector} input, #{address_div.selector} select") {
112
+ grid_column '2'
113
+ }
114
+ }
115
+ }
116
+
117
+ div(style: {margin: 5}) {
118
+ inner_text <= [address, :summary,
119
+ computed_by: address.members + ['state_code'],
120
+ ]
121
+ }
122
+ }
123
+ }
124
+ end
125
+ end
126
+
127
+ unless Object.const_defined?(:AccordionSection2)
128
+ # Note: this is similar to AccordionSection in HelloComponentSlots but specifies default_slot for simpler consumption
129
+ class AccordionSection2
130
+ class Presenter
131
+ attr_accessor :collapsed, :instant_transition
132
+
133
+ def toggle_collapsed(instant: false)
134
+ self.instant_transition = instant
135
+ self.collapsed = !collapsed
136
+ end
137
+
138
+ def expand(instant: false)
139
+ self.instant_transition = instant
140
+ self.collapsed = false
141
+ end
142
+
143
+ def collapse(instant: false)
144
+ self.instant_transition = instant
145
+ self.collapsed = true
146
+ end
147
+ end
148
+
149
+ include Glimmer::Web::Component
150
+
151
+ events :expanded, :collapsed
152
+
153
+ default_slot :section_content # automatically insert content in this element slot inside markup
154
+
155
+ option :title
156
+
157
+ attr_reader :presenter
158
+
159
+ before_render do
160
+ @presenter = Presenter.new
161
+ end
162
+
163
+ markup {
164
+ section { # represents the :markup_root_slot to allow inserting content here instead of in default_slot
165
+ # Unidirectionally data-bind the class inclusion of 'collapsed' to the @presenter.collapsed boolean attribute,
166
+ # meaning if @presenter.collapsed changes to true, the CSS class 'collapsed' is included on the element,
167
+ # and if it changes to false, the CSS class 'collapsed' is removed from the element.
168
+ class_name(:collapsed) <= [@presenter, :collapsed]
169
+ class_name(:instant_transition) <= [@presenter, :instant_transition]
170
+
171
+ header(title, class: 'accordion-section-title') {
172
+ onclick do |event|
173
+ @presenter.toggle_collapsed
174
+ if @presenter.collapsed
175
+ notify_listeners(:collapsed)
176
+ else
177
+ notify_listeners(:expanded)
178
+ end
179
+ end
180
+ }
181
+
182
+ div(slot: :section_content, class: 'accordion-section-content')
183
+ }
184
+ }
185
+
186
+ style {
187
+ r('.accordion-section-title') {
188
+ font_size 2.em
189
+ font_weight :bold
190
+ cursor :pointer
191
+ padding_left 20
192
+ position :relative
193
+ margin_block_start 0.33.em
194
+ margin_block_end 0.33.em
195
+ }
196
+
197
+ r('.accordion-section-title::before') {
198
+ content '"▼"'
199
+ position :absolute
200
+ font_size 0.5.em
201
+ top 10
202
+ left 0
203
+ }
204
+
205
+ r('.accordion-section-content') {
206
+ height 246
207
+ overflow :hidden
208
+ transition 'height 0.5s linear'
209
+ }
210
+
211
+ r("#{component_element_selector}.instant_transition .accordion-section-content") {
212
+ transition 'initial'
213
+ }
214
+
215
+ r("#{component_element_selector}.collapsed .accordion-section-title::before") {
216
+ content '"►"'
217
+ }
218
+
219
+ r("#{component_element_selector}.collapsed .accordion-section-content") {
220
+ height 0
221
+ }
222
+ }
223
+ end
224
+ end
225
+
226
+ unless Object.const_defined?(:Accordion)
227
+ class Accordion
228
+ include Glimmer::Web::Component
229
+
230
+ events :accordion_section_expanded, :accordion_section_collapsed
231
+
232
+ markup {
233
+ # given that no slots are specified, nesting content under the accordion component
234
+ # in consumer code adds content directly inside the markup root div.
235
+ div { |accordion| # represents the :markup_root_slot (top-level element)
236
+ # on render, all accordion sections would have been added by consumers already, so we can
237
+ # attach listeners to all of them by re-opening their content with `.content { ... }` block
238
+ on_render do
239
+ accordion_section_elements = accordion.children
240
+ accordion_sections = accordion_section_elements.map(&:component)
241
+ accordion_sections.each_with_index do |accordion_section, index|
242
+ accordion_section_number = index + 1
243
+
244
+ # ensure only the first section is expanded
245
+ accordion_section.presenter.collapse(instant: true) if accordion_section_number != 1
246
+
247
+ accordion_section.content { # re-open content and add component custom event listeners
248
+ on_expanded do
249
+ other_accordion_sections = accordion_sections.reject {|other_accordion_section| other_accordion_section == accordion_section }
250
+ other_accordion_sections.each { |other_accordion_section| other_accordion_section.presenter.collapse }
251
+ notify_listeners(:accordion_section_expanded, accordion_section_number)
252
+ end
253
+
254
+ on_collapsed do
255
+ notify_listeners(:accordion_section_collapsed, accordion_section_number)
256
+ end
257
+ }
258
+ end
259
+ end
260
+ }
261
+ }
262
+ end
263
+ end
264
+
265
+ unless Object.const_defined?(:HelloComponentListenersDefaultSlot)
266
+ # HelloComponentListenersDefaultSlot Glimmer Web Component (View component)
267
+ #
268
+ # This View component represents the main page being rendered,
269
+ # as done by its `render` class method below
270
+ #
271
+ # Note: this is a simpler version of HelloComponentSlots as it leverages the default slot feature
272
+ class HelloComponentListenersDefaultSlot
273
+ class Presenter
274
+ attr_accessor :status_message
275
+
276
+ def initialize
277
+ @status_message = "Accordion section 1 is expanded!"
278
+ end
279
+ end
280
+
281
+ include Glimmer::Web::Component
282
+
283
+ before_render do
284
+ @presenter = Presenter.new
285
+ @shipping_address = Address.new(
286
+ full_name: 'Johnny Doe',
287
+ street: '3922 Park Ave',
288
+ street2: 'PO BOX 8382',
289
+ city: 'San Diego',
290
+ state: 'California',
291
+ zip_code: '91913',
292
+ )
293
+ @billing_address = Address.new(
294
+ full_name: 'John C Doe',
295
+ street: '123 Main St',
296
+ street2: 'Apartment 3C',
297
+ city: 'San Diego',
298
+ state: 'California',
299
+ zip_code: '91911',
300
+ )
301
+ @emergency_address = Address.new(
302
+ full_name: 'Mary Doe',
303
+ street: '2038 Ipswitch St',
304
+ street2: 'Suite 300',
305
+ city: 'San Diego',
306
+ state: 'California',
307
+ zip_code: '91912',
308
+ )
309
+ end
310
+
311
+ markup {
312
+ div {
313
+ h1(style: {font_style: :italic}) {
314
+ inner_html <= [@presenter, :status_message]
315
+ }
316
+
317
+ accordion {
318
+ # any content nested under component directly is added to its markup_root_slot element if no default_slot is specified
319
+ accordion_section2(title: 'Shipping Address') {
320
+ address_form(address: @shipping_address) # automatically inserts content in default_slot :section_content
321
+ }
322
+
323
+ accordion_section2(title: 'Billing Address') {
324
+ address_form(address: @billing_address) # automatically inserts content in default_slot :section_content
325
+ }
326
+
327
+ accordion_section2(title: 'Emergency Address') {
328
+ address_form(address: @emergency_address) # automatically inserts content in default_slot :section_content
329
+ }
330
+
331
+ # on_accordion_section_expanded listener matches event :accordion_section_expanded declared in Accordion component
332
+ on_accordion_section_expanded { |accordion_section_number|
333
+ @presenter.status_message = "Accordion section #{accordion_section_number} is expanded!"
334
+ }
335
+
336
+ on_accordion_section_collapsed { |accordion_section_number|
337
+ @presenter.status_message = "Accordion section #{accordion_section_number} is collapsed!"
338
+ }
339
+ }
340
+ }
341
+ }
342
+ end
343
+ end
344
+
345
+ Document.ready? do
346
+ # renders a top-level (root) HelloComponentListenersDefaultSlot component
347
+ # Note: this is a simpler version of hello_component_slots.rb as it leverages the default slot feature
348
+ HelloComponentListenersDefaultSlot.render
349
+ end
@@ -21,75 +21,35 @@
21
21
 
22
22
  require 'glimmer-dsl-web'
23
23
 
24
- Address = Struct.new(:full_name, :street, :street2, :city, :state, :zip_code, keyword_init: true) do
25
- STATES = {
26
- "AK"=>"Alaska",
27
- "AL"=>"Alabama",
28
- "AR"=>"Arkansas",
29
- "AS"=>"American Samoa",
30
- "AZ"=>"Arizona",
31
- "CA"=>"California",
32
- "CO"=>"Colorado",
33
- "CT"=>"Connecticut",
34
- "DC"=>"District of Columbia",
35
- "DE"=>"Delaware",
36
- "FL"=>"Florida",
37
- "GA"=>"Georgia",
38
- "GU"=>"Guam",
39
- "HI"=>"Hawaii",
40
- "IA"=>"Iowa",
41
- "ID"=>"Idaho",
42
- "IL"=>"Illinois",
43
- "IN"=>"Indiana",
44
- "KS"=>"Kansas",
45
- "KY"=>"Kentucky",
46
- "LA"=>"Louisiana",
47
- "MA"=>"Massachusetts",
48
- "MD"=>"Maryland",
49
- "ME"=>"Maine",
50
- "MI"=>"Michigan",
51
- "MN"=>"Minnesota",
52
- "MO"=>"Missouri",
53
- "MS"=>"Mississippi",
54
- "MT"=>"Montana",
55
- "NC"=>"North Carolina",
56
- "ND"=>"North Dakota",
57
- "NE"=>"Nebraska",
58
- "NH"=>"New Hampshire",
59
- "NJ"=>"New Jersey",
60
- "NM"=>"New Mexico",
61
- "NV"=>"Nevada",
62
- "NY"=>"New York",
63
- "OH"=>"Ohio",
64
- "OK"=>"Oklahoma",
65
- "OR"=>"Oregon",
66
- "PA"=>"Pennsylvania",
67
- "PR"=>"Puerto Rico",
68
- "RI"=>"Rhode Island",
69
- "SC"=>"South Carolina",
70
- "SD"=>"South Dakota",
71
- "TN"=>"Tennessee",
72
- "TX"=>"Texas",
73
- "UT"=>"Utah",
74
- "VA"=>"Virginia",
75
- "VI"=>"Virgin Islands",
76
- "VT"=>"Vermont",
77
- "WA"=>"Washington",
78
- "WI"=>"Wisconsin",
79
- "WV"=>"West Virginia",
80
- "WY"=>"Wyoming"
81
- }
82
-
83
- def state_code
84
- STATES.invert[state]
85
- end
24
+ unless Object.const_defined?(:Address)
25
+ Address = Struct.new(:full_name, :street, :street2, :city, :state, :zip_code, :billing_and_shipping, keyword_init: true) do
26
+ STATES = {
27
+ "AK"=>"Alaska", "AL"=>"Alabama", "AR"=>"Arkansas", "AS"=>"American Samoa", "AZ"=>"Arizona",
28
+ "CA"=>"California", "CO"=>"Colorado", "CT"=>"Connecticut", "DC"=>"District of Columbia", "DE"=>"Delaware",
29
+ "FL"=>"Florida", "GA"=>"Georgia", "GU"=>"Guam", "HI"=>"Hawaii", "IA"=>"Iowa", "ID"=>"Idaho", "IL"=>"Illinois",
30
+ "IN"=>"Indiana", "KS"=>"Kansas", "KY"=>"Kentucky", "LA"=>"Louisiana", "MA"=>"Massachusetts", "MD"=>"Maryland",
31
+ "ME"=>"Maine", "MI"=>"Michigan", "MN"=>"Minnesota", "MO"=>"Missouri", "MS"=>"Mississippi", "MT"=>"Montana",
32
+ "NC"=>"North Carolina", "ND"=>"North Dakota", "NE"=>"Nebraska", "NH"=>"New Hampshire", "NJ"=>"New Jersey",
33
+ "NM"=>"New Mexico", "NV"=>"Nevada", "NY"=>"New York", "OH"=>"Ohio", "OK"=>"Oklahoma", "OR"=>"Oregon",
34
+ "PA"=>"Pennsylvania", "PR"=>"Puerto Rico", "RI"=>"Rhode Island", "SC"=>"South Carolina", "SD"=>"South Dakota",
35
+ "TN"=>"Tennessee", "TX"=>"Texas", "UT"=>"Utah", "VA"=>"Virginia", "VI"=>"Virgin Islands", "VT"=>"Vermont",
36
+ "WA"=>"Washington", "WI"=>"Wisconsin", "WV"=>"West Virginia", "WY"=>"Wyoming"
37
+ }
38
+
39
+ def state_code
40
+ STATES.invert[state]
41
+ end
42
+
43
+ def state_code=(value)
44
+ self.state = STATES[value]
45
+ end
86
46
 
87
- def state_code=(value)
88
- self.state = STATES[value]
89
- end
90
-
91
- def summary
92
- to_h.values.map(&:to_s).reject(&:empty?).join(', ')
47
+ def summary
48
+ string_attributes = to_h.except(:billing_and_shipping)
49
+ summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
50
+ summary += " (Billing & Shipping)" if billing_and_shipping
51
+ summary
52
+ end
93
53
  end
94
54
  end
95
55
 
@@ -21,7 +21,8 @@
21
21
 
22
22
  require 'glimmer-dsl-web'
23
23
 
24
- class Address
24
+ # Note: named Address2 to avoid conflicting with other samples if loaded together
25
+ class Address2
25
26
  attr_accessor :text
26
27
  attr_reader :name, :street, :city, :state, :zip
27
28
 
@@ -78,7 +79,7 @@ class User
78
79
  def update_addresses
79
80
  address_count_change = address_count - addresses.size
80
81
  if address_count_change > 0
81
- address_count_change.times { addresses << Address.new }
82
+ address_count_change.times { addresses << Address2.new }
82
83
  else
83
84
  address_count_change.abs.times { addresses.pop }
84
85
  end
@@ -21,78 +21,35 @@
21
21
 
22
22
  require 'glimmer-dsl-web'
23
23
 
24
- Address = Struct.new(:street, :street2, :city, :state, :zip_code, :billing_and_shipping, keyword_init: true) do
25
- STATES = {
26
- "AK"=>"Alaska",
27
- "AL"=>"Alabama",
28
- "AR"=>"Arkansas",
29
- "AS"=>"American Samoa",
30
- "AZ"=>"Arizona",
31
- "CA"=>"California",
32
- "CO"=>"Colorado",
33
- "CT"=>"Connecticut",
34
- "DC"=>"District of Columbia",
35
- "DE"=>"Delaware",
36
- "FL"=>"Florida",
37
- "GA"=>"Georgia",
38
- "GU"=>"Guam",
39
- "HI"=>"Hawaii",
40
- "IA"=>"Iowa",
41
- "ID"=>"Idaho",
42
- "IL"=>"Illinois",
43
- "IN"=>"Indiana",
44
- "KS"=>"Kansas",
45
- "KY"=>"Kentucky",
46
- "LA"=>"Louisiana",
47
- "MA"=>"Massachusetts",
48
- "MD"=>"Maryland",
49
- "ME"=>"Maine",
50
- "MI"=>"Michigan",
51
- "MN"=>"Minnesota",
52
- "MO"=>"Missouri",
53
- "MS"=>"Mississippi",
54
- "MT"=>"Montana",
55
- "NC"=>"North Carolina",
56
- "ND"=>"North Dakota",
57
- "NE"=>"Nebraska",
58
- "NH"=>"New Hampshire",
59
- "NJ"=>"New Jersey",
60
- "NM"=>"New Mexico",
61
- "NV"=>"Nevada",
62
- "NY"=>"New York",
63
- "OH"=>"Ohio",
64
- "OK"=>"Oklahoma",
65
- "OR"=>"Oregon",
66
- "PA"=>"Pennsylvania",
67
- "PR"=>"Puerto Rico",
68
- "RI"=>"Rhode Island",
69
- "SC"=>"South Carolina",
70
- "SD"=>"South Dakota",
71
- "TN"=>"Tennessee",
72
- "TX"=>"Texas",
73
- "UT"=>"Utah",
74
- "VA"=>"Virginia",
75
- "VI"=>"Virgin Islands",
76
- "VT"=>"Vermont",
77
- "WA"=>"Washington",
78
- "WI"=>"Wisconsin",
79
- "WV"=>"West Virginia",
80
- "WY"=>"Wyoming"
81
- }
82
-
83
- def state_code
84
- STATES.invert[state]
85
- end
24
+ unless Object.const_defined?(:Address)
25
+ Address = Struct.new(:full_name, :street, :street2, :city, :state, :zip_code, :billing_and_shipping, keyword_init: true) do
26
+ STATES = {
27
+ "AK"=>"Alaska", "AL"=>"Alabama", "AR"=>"Arkansas", "AS"=>"American Samoa", "AZ"=>"Arizona",
28
+ "CA"=>"California", "CO"=>"Colorado", "CT"=>"Connecticut", "DC"=>"District of Columbia", "DE"=>"Delaware",
29
+ "FL"=>"Florida", "GA"=>"Georgia", "GU"=>"Guam", "HI"=>"Hawaii", "IA"=>"Iowa", "ID"=>"Idaho", "IL"=>"Illinois",
30
+ "IN"=>"Indiana", "KS"=>"Kansas", "KY"=>"Kentucky", "LA"=>"Louisiana", "MA"=>"Massachusetts", "MD"=>"Maryland",
31
+ "ME"=>"Maine", "MI"=>"Michigan", "MN"=>"Minnesota", "MO"=>"Missouri", "MS"=>"Mississippi", "MT"=>"Montana",
32
+ "NC"=>"North Carolina", "ND"=>"North Dakota", "NE"=>"Nebraska", "NH"=>"New Hampshire", "NJ"=>"New Jersey",
33
+ "NM"=>"New Mexico", "NV"=>"Nevada", "NY"=>"New York", "OH"=>"Ohio", "OK"=>"Oklahoma", "OR"=>"Oregon",
34
+ "PA"=>"Pennsylvania", "PR"=>"Puerto Rico", "RI"=>"Rhode Island", "SC"=>"South Carolina", "SD"=>"South Dakota",
35
+ "TN"=>"Tennessee", "TX"=>"Texas", "UT"=>"Utah", "VA"=>"Virginia", "VI"=>"Virgin Islands", "VT"=>"Vermont",
36
+ "WA"=>"Washington", "WI"=>"Wisconsin", "WV"=>"West Virginia", "WY"=>"Wyoming"
37
+ }
38
+
39
+ def state_code
40
+ STATES.invert[state]
41
+ end
42
+
43
+ def state_code=(value)
44
+ self.state = STATES[value]
45
+ end
86
46
 
87
- def state_code=(value)
88
- self.state = STATES[value]
89
- end
90
-
91
- def summary
92
- string_attributes = to_h.except(:billing_and_shipping)
93
- summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
94
- summary += " (Billing & Shipping)" if billing_and_shipping
95
- summary
47
+ def summary
48
+ string_attributes = to_h.except(:billing_and_shipping)
49
+ summary = string_attributes.values.map(&:to_s).reject(&:empty?).join(', ')
50
+ summary += " (Billing & Shipping)" if billing_and_shipping
51
+ summary
52
+ end
96
53
  end
97
54
  end
98
55
 
@@ -48,7 +48,7 @@ class TodoList
48
48
  border :none
49
49
  bottom 100.%
50
50
  height 1
51
- opacity 0
51
+ opacity '0'
52
52
  position :absolute
53
53
  right 100.%
54
54
  width 1
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.6.1
4
+ version: 0.6.2
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-09-02 00:00:00.000000000 Z
11
+ date: 2024-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -268,6 +268,7 @@ files:
268
268
  - lib/glimmer-dsl-web/samples/hello/hello_button.rb
269
269
  - lib/glimmer-dsl-web/samples/hello/hello_component.rb
270
270
  - lib/glimmer-dsl-web/samples/hello/hello_component_listeners.rb
271
+ - lib/glimmer-dsl-web/samples/hello/hello_component_listeners_default_slot.rb
271
272
  - lib/glimmer-dsl-web/samples/hello/hello_component_slots.rb
272
273
  - lib/glimmer-dsl-web/samples/hello/hello_content_data_binding.rb
273
274
  - lib/glimmer-dsl-web/samples/hello/hello_data_binding.rb