glimmer-dsl-web 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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