lissio 0.1.0.beta3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/README.md +20 -22
- data/bin/lissio +112 -37
- data/lib/lissio.rb +2 -0
- data/lib/lissio/builder.rb +54 -0
- data/lib/lissio/server.rb +10 -5
- data/lissio.gemspec +3 -6
- data/opal/lissio/adapter/rest.rb +132 -60
- data/opal/lissio/adapter/storage.rb +30 -34
- data/opal/lissio/application.rb +5 -4
- data/opal/lissio/collection.rb +12 -8
- data/opal/lissio/component.rb +151 -38
- data/opal/lissio/component/alert.rb +39 -49
- data/opal/lissio/component/autocomplete.rb +318 -0
- data/opal/lissio/component/container.rb +4 -6
- data/opal/lissio/component/markdown.rb +147 -126
- data/opal/lissio/component/tooltip.rb +136 -148
- data/opal/lissio/model.rb +65 -25
- data/opal/lissio/router.rb +12 -2
- data/opal/lissio/version.rb +1 -1
- metadata +14 -26
@@ -11,7 +11,7 @@ class Tooltip < Lissio::Component
|
|
11
11
|
|
12
12
|
def initialize(*args, &block)
|
13
13
|
if Lissio::Component === args.first
|
14
|
-
|
14
|
+
@parent = args.shift
|
15
15
|
end
|
16
16
|
|
17
17
|
@options = DEFAULTS.merge(args.first)
|
@@ -151,7 +151,6 @@ private
|
|
151
151
|
|
152
152
|
def apply(placement)
|
153
153
|
position = offset(placement)
|
154
|
-
size = element.size
|
155
154
|
|
156
155
|
margin_top = element.style['margin-top'].to_u
|
157
156
|
margin_left = element.style['margin-left'].to_u
|
@@ -171,200 +170,189 @@ private
|
|
171
170
|
end
|
172
171
|
|
173
172
|
css do
|
174
|
-
|
175
|
-
|
176
|
-
z index: 9001
|
173
|
+
position :absolute
|
174
|
+
z index: 9001
|
177
175
|
|
178
|
-
|
179
|
-
|
176
|
+
display :block
|
177
|
+
visibility :visible
|
180
178
|
|
181
|
-
|
182
|
-
|
179
|
+
font size: 12.px
|
180
|
+
line height: 1.4
|
183
181
|
|
184
|
-
|
182
|
+
opacity 0
|
185
183
|
|
186
|
-
|
187
|
-
|
188
|
-
|
184
|
+
rule '&.in' do
|
185
|
+
opacity 0.9
|
186
|
+
end
|
189
187
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
188
|
+
rule '&.top' do
|
189
|
+
margin top: -3.px
|
190
|
+
padding 5.px, 0
|
191
|
+
end
|
194
192
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
193
|
+
rule '&.right' do
|
194
|
+
margin left: 3.px
|
195
|
+
padding 0, 5.px
|
196
|
+
end
|
199
197
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
198
|
+
rule '&.bottom' do
|
199
|
+
margin top: 3.px
|
200
|
+
padding 5.px, 0
|
201
|
+
end
|
204
202
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
203
|
+
rule '&.left' do
|
204
|
+
margin left: -3.px
|
205
|
+
padding 0, 5.px
|
206
|
+
end
|
209
207
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
208
|
+
rule '.tooltip-inner' do
|
209
|
+
max width: 200.px
|
210
|
+
padding 3.px, 8.px
|
211
|
+
color '#fff'
|
214
212
|
|
215
|
-
|
216
|
-
|
213
|
+
text align: :center,
|
214
|
+
decoration: :none
|
217
215
|
|
218
|
-
|
219
|
-
|
220
|
-
|
216
|
+
background color: '#000'
|
217
|
+
border radius: 4.px
|
218
|
+
end
|
221
219
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
220
|
+
rule '.tooltip-arrow' do
|
221
|
+
position :absolute
|
222
|
+
width 0
|
223
|
+
height 0
|
226
224
|
|
227
|
-
|
228
|
-
|
229
|
-
|
225
|
+
border color: :transparent,
|
226
|
+
style: :solid
|
227
|
+
end
|
230
228
|
|
231
|
-
|
232
|
-
|
233
|
-
|
229
|
+
rule '&.top .tooltip-arrow' do
|
230
|
+
bottom 0
|
231
|
+
left 50.%
|
234
232
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
233
|
+
margin left: -5.px
|
234
|
+
border width: [5.px, 5.px, 0],
|
235
|
+
color: { top: '#000' }
|
236
|
+
end
|
239
237
|
|
240
|
-
|
241
|
-
|
242
|
-
|
238
|
+
rule '&.top-left .tooltip-arrow' do
|
239
|
+
bottom 0
|
240
|
+
left 5.px
|
243
241
|
|
244
|
-
|
245
|
-
|
246
|
-
|
242
|
+
border width: [5.px, 5.px, 0],
|
243
|
+
color: { top: '#000' }
|
244
|
+
end
|
247
245
|
|
248
|
-
|
249
|
-
|
250
|
-
|
246
|
+
rule '&.top-right .tooltip-arrow' do
|
247
|
+
bottom 0
|
248
|
+
right 5.px
|
251
249
|
|
252
|
-
|
253
|
-
|
254
|
-
|
250
|
+
border width: [5.px, 5.px, 0],
|
251
|
+
color: { top: '#000' }
|
252
|
+
end
|
255
253
|
|
256
|
-
|
257
|
-
|
258
|
-
|
254
|
+
rule '&.right .tooltip-arrow' do
|
255
|
+
top 50.%
|
256
|
+
left 0
|
259
257
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
258
|
+
margin top: -5.px
|
259
|
+
border width: [5.px, 5.px, 5.px, 0],
|
260
|
+
color: { right: '#000' }
|
261
|
+
end
|
264
262
|
|
265
|
-
|
266
|
-
|
267
|
-
|
263
|
+
rule '&.left .tooltip-arrow' do
|
264
|
+
top 50.%
|
265
|
+
right 0
|
268
266
|
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
267
|
+
margin top: -5.px
|
268
|
+
border width: [5.px, 0, 5.px, 5.px],
|
269
|
+
color: { left: '#000' }
|
270
|
+
end
|
273
271
|
|
274
|
-
|
275
|
-
|
276
|
-
|
272
|
+
rule '&.bottom .tooltip-arrow' do
|
273
|
+
top 0
|
274
|
+
left 50.%
|
277
275
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
276
|
+
margin left: -5.px
|
277
|
+
border width: [0, 5.px, 5.px],
|
278
|
+
color: { bottom: '#000' }
|
279
|
+
end
|
282
280
|
|
283
|
-
|
284
|
-
|
285
|
-
|
281
|
+
rule '&.bottom-left .tooltip-arrow' do
|
282
|
+
top 0
|
283
|
+
left 5.px
|
286
284
|
|
287
|
-
|
288
|
-
|
289
|
-
|
285
|
+
border width: [0, 5.px, 5.px],
|
286
|
+
color: { bottom: '#000' }
|
287
|
+
end
|
290
288
|
|
291
|
-
|
292
|
-
|
293
|
-
|
289
|
+
rule '&.bottom-right .tooltip-arrow' do
|
290
|
+
top 0
|
291
|
+
right 5.px
|
294
292
|
|
295
|
-
|
296
|
-
|
297
|
-
end
|
293
|
+
border width: [0, 5.px, 5.px],
|
294
|
+
color: { bottom: '#000' }
|
298
295
|
end
|
299
296
|
end
|
300
297
|
|
301
|
-
def self.customize(
|
302
|
-
if args.length == 1
|
303
|
-
options = args.first
|
304
|
-
else
|
305
|
-
name, options = args
|
306
|
-
end
|
307
|
-
|
308
|
-
name ||= "tooltip-custom-#{rand(10000)}"
|
309
|
-
options ||= {}
|
310
|
-
|
298
|
+
def self.customize(options = {}, &block)
|
311
299
|
Class.new(self) {
|
312
|
-
tag class: [:tooltip, name]
|
313
|
-
|
314
300
|
css do
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
if value = options[:opacity]
|
319
|
-
rule '&.in' do
|
320
|
-
opacity value
|
321
|
-
end
|
301
|
+
if value = options[:opacity]
|
302
|
+
rule '&.in' do
|
303
|
+
opacity value
|
322
304
|
end
|
305
|
+
end
|
323
306
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
end
|
307
|
+
if value = options[:foreground] || options[:fg]
|
308
|
+
rule '.tooltip-inner' do
|
309
|
+
color value
|
328
310
|
end
|
311
|
+
end
|
329
312
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
313
|
+
if value = options[:background] || options[:bg]
|
314
|
+
rule '.tooltip-inner' do
|
315
|
+
background color: value
|
316
|
+
end
|
334
317
|
|
335
|
-
|
336
|
-
|
337
|
-
|
318
|
+
rule '&.top .tooltip-arrow' do
|
319
|
+
border color: { top: value }
|
320
|
+
end
|
338
321
|
|
339
|
-
|
340
|
-
|
341
|
-
|
322
|
+
rule '&.top-right .tooltip-arrow' do
|
323
|
+
border color: { top: value }
|
324
|
+
end
|
342
325
|
|
343
|
-
|
344
|
-
|
345
|
-
|
326
|
+
rule '&.top-left .tooltip-arrow' do
|
327
|
+
border color: { top: value }
|
328
|
+
end
|
346
329
|
|
347
|
-
|
348
|
-
|
349
|
-
|
330
|
+
rule '&.right .tooltip-arrow' do
|
331
|
+
border color: { right: value }
|
332
|
+
end
|
350
333
|
|
351
|
-
|
352
|
-
|
353
|
-
|
334
|
+
rule '&.left .tooltip-arrow' do
|
335
|
+
border color: { right: value }
|
336
|
+
end
|
354
337
|
|
355
|
-
|
356
|
-
|
357
|
-
|
338
|
+
rule '&.bottom .tooltip-arrow' do
|
339
|
+
border color: { bottom: value }
|
340
|
+
end
|
358
341
|
|
359
|
-
|
360
|
-
|
361
|
-
|
342
|
+
rule '&.bottom-right .tooltip-arrow' do
|
343
|
+
border color: { bottom: value }
|
344
|
+
end
|
362
345
|
|
363
|
-
|
364
|
-
|
365
|
-
end
|
346
|
+
rule '&.bottom-left .tooltip-arrow' do
|
347
|
+
border color: { bottom: value }
|
366
348
|
end
|
367
349
|
end
|
350
|
+
|
351
|
+
if block.arity == 0
|
352
|
+
instance_exec(&block)
|
353
|
+
else
|
354
|
+
block.call(self)
|
355
|
+
end if block
|
368
356
|
end
|
369
357
|
}
|
370
358
|
end
|
data/opal/lissio/model.rb
CHANGED
@@ -15,13 +15,60 @@ module Lissio
|
|
15
15
|
|
16
16
|
class Model
|
17
17
|
class Property
|
18
|
-
|
18
|
+
def self.coerce(data, as)
|
19
|
+
return data if !as || as === data
|
20
|
+
|
21
|
+
if Module === as
|
22
|
+
if as.ancestors.include?(Model)
|
23
|
+
if as.primary && as.primary.as === data
|
24
|
+
return data
|
25
|
+
else
|
26
|
+
return as.new(*data)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
case
|
32
|
+
when Proc === as
|
33
|
+
as.call(data)
|
34
|
+
|
35
|
+
when Array === as
|
36
|
+
data.map { |d| coerce(d, as.first) }
|
37
|
+
|
38
|
+
when as == Boolean
|
39
|
+
!!data
|
40
|
+
|
41
|
+
when as == Array
|
42
|
+
Array(data)
|
43
|
+
|
44
|
+
when as == String
|
45
|
+
data.to_s
|
46
|
+
|
47
|
+
when as == Symbol
|
48
|
+
data.to_sym
|
49
|
+
|
50
|
+
when as == Integer
|
51
|
+
data.to_i
|
52
|
+
|
53
|
+
when as == Float
|
54
|
+
data.to_f
|
55
|
+
|
56
|
+
when as == Time
|
57
|
+
Time.parse(data)
|
58
|
+
|
59
|
+
else
|
60
|
+
as.new(*data)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :name, :as, :key
|
19
65
|
|
20
66
|
def initialize(name, options)
|
21
67
|
@name = name
|
22
68
|
@default = options[:default]
|
23
69
|
@primary = options[:primary] || false
|
24
70
|
@as = options[:as]
|
71
|
+
@key = options[:key]
|
25
72
|
end
|
26
73
|
|
27
74
|
def primary?
|
@@ -38,27 +85,8 @@ class Model
|
|
38
85
|
|
39
86
|
def new(data)
|
40
87
|
return default if data.nil?
|
41
|
-
return data if !@as || @as === data
|
42
88
|
|
43
|
-
|
44
|
-
if @as.primary.as === data
|
45
|
-
return data
|
46
|
-
else
|
47
|
-
return @as.new(*data)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
case
|
52
|
-
when @as == Boolean then !!data
|
53
|
-
when @as == Array then Array(data)
|
54
|
-
when @as == String then data.to_s
|
55
|
-
when @as == Symbol then data.to_sym
|
56
|
-
when @as == Integer then data.to_i
|
57
|
-
when @as == Float then data.to_f
|
58
|
-
when @as == Time then Time.parse(data)
|
59
|
-
when Proc === @as then @as.call(data)
|
60
|
-
else @as.new(*data)
|
61
|
-
end
|
89
|
+
Property.coerce(data, @as)
|
62
90
|
end
|
63
91
|
|
64
92
|
def define(klass)
|
@@ -68,15 +96,27 @@ class Model
|
|
68
96
|
if Class === @as && @as.ancestors.include?(Model)
|
69
97
|
klass.define_method name do
|
70
98
|
if id = instance_variable_get("@#{name}")
|
71
|
-
as
|
99
|
+
if as === id
|
100
|
+
Promise.value(id)
|
101
|
+
else
|
102
|
+
as.fetch(id)
|
103
|
+
end
|
72
104
|
end
|
73
105
|
end
|
74
106
|
|
107
|
+
klass.define_method "#{name}!" do
|
108
|
+
instance_variable_get("@#{name}")
|
109
|
+
end
|
110
|
+
|
75
111
|
klass.define_method "#{name}=" do |value|
|
76
|
-
if
|
112
|
+
if as === value
|
113
|
+
value = value.id!
|
114
|
+
end
|
115
|
+
|
116
|
+
if instance_variable_get("@#{name}") != value
|
77
117
|
@changed << name
|
78
118
|
|
79
|
-
instance_variable_set "@#{name}", value
|
119
|
+
instance_variable_set "@#{name}", value
|
80
120
|
end
|
81
121
|
end
|
82
122
|
else
|
@@ -156,7 +196,7 @@ class Model
|
|
156
196
|
|
157
197
|
if data
|
158
198
|
properties.each {|name, property|
|
159
|
-
instance_variable_set "@#{name}", property.new(data[name])
|
199
|
+
instance_variable_set "@#{name}", property.new(data[property.key || name])
|
160
200
|
}
|
161
201
|
end
|
162
202
|
end
|