@@ -9,7 +9,7 @@ Create a widget to select files.
9
9
If `multiple=true` the observable will hold an array containing the paths of all
10
10
selected files. Use `accept` to only accept some formats, e.g. `accept=".csv"`
11
11
"""
12
- function filepicker (:: WidgetTheme , lbl= " Choose a file..." ; attributes= PropDict (),
12
+ function filepicker (theme :: WidgetTheme , lbl= " Choose a file..." ; attributes= PropDict (),
13
13
label= lbl, className= " " , multiple= false , value= multiple ? String[] : " " , kwargs... )
14
14
15
15
(value isa AbstractObservable) || (value = Observable {Any} (value))
@@ -34,22 +34,22 @@ function filepicker(::WidgetTheme, lbl="Choose a file..."; attributes=PropDict()
34
34
multiple && (attributes= merge (attributes, PropDict (:multiple => true )))
35
35
attributes = merge (attributes, PropDict (:type => " file" , :style => " display: none;" ,
36
36
Symbol (" data-bind" ) => " event: {change: onFileUpload}" ))
37
- className = mergeclasses (getclass (:input , " file" ), className)
37
+ className = mergeclasses (getclass (theme, :input , " file" ), className)
38
38
template = dom " div[style=display:flex; align-items:center;]" (
39
- node (:label , className= getclass (:input , " file" , " label" ))(
39
+ node (:label , className= getclass (theme, :input , " file" , " label" ))(
40
40
node (:input ; className= className, attributes= attributes, kwargs... ),
41
41
node (:span ,
42
- node (:span , (node (:i , className = getclass (:input , " file" , " icon" ))), className= getclass (:input , " file" , " span" , " icon" )),
43
- node (:span , label, className= getclass (:input , " file" , " span" , " label" )),
44
- className= getclass (:input , " file" , " span" ))
42
+ node (:span , (node (:i , className = getclass (theme, :input , " file" , " icon" ))), className= getclass (theme, :input , " file" , " span" , " icon" )),
43
+ node (:span , label, className= getclass (theme, :input , " file" , " span" , " label" )),
44
+ className= getclass (theme, :input , " file" , " span" ))
45
45
),
46
46
node (:span , attributes = Dict (" data-bind" => " text: filename() == '' ? 'No file chosen' : filename()" ),
47
- className = getclass (:input , " file" , " name" ))
47
+ className = getclass (theme, :input , " file" , " name" ))
48
48
)
49
49
50
50
observs = [" path" => value, " filename" => filename]
51
51
ui = knockout (template, observs, methods = [" onFileUpload" => onFileUpload])
52
- slap_design! (ui)
52
+ slap_design! (ui, theme )
53
53
Widget {:filepicker} (observs, scope = ui, output = ui[" path" ], layout = node (:div , className = " field interact-widget" )∘ Widgets. scope)
54
54
end
55
55
@@ -110,7 +110,7 @@ function dialog(dialogtype; value, className = "", label = "dialog", icon = noth
110
110
console .log (this .dialog .$dialogtype ($options, $callback));
111
111
}
112
112
""" )
113
- className = mergeclasses (getclass (:button ), className)
113
+ className = mergeclasses (getclass (theme, :button ), className)
114
114
content = if icon === nothing
115
115
(label,)
116
116
else
@@ -121,7 +121,7 @@ function dialog(dialogtype; value, className = "", label = "dialog", icon = noth
121
121
events= Dict (" click" => @js event -> ($ clicks[] = $ clicks[] + 1 )),
122
122
className = className)
123
123
scp. dom = btn
124
- slap_design! (scp)
124
+ slap_design! (scp, theme )
125
125
Widget {:dialog} ([]; output = value, scope = scp, layout = Widgets. scope)
126
126
end
127
127
@@ -156,20 +156,20 @@ function timepicker end
156
156
157
157
for (func, typ, str, unit) in [(:timepicker , :(Dates. Time), " time" , Dates. Second), (:datepicker , :(Dates. Date), " date" , Dates. Day) ]
158
158
@eval begin
159
- function $func (:: WidgetTheme , val= nothing ; value= val, kwargs... )
159
+ function $func (theme :: WidgetTheme , val= nothing ; value= val, kwargs... )
160
160
(value isa AbstractObservable) || (value = Observable {Union{$typ, Nothing}} (value))
161
161
f = x -> x === nothing ? " " : _string (x)
162
162
g = t -> _parse ($ typ, t)
163
163
pair = ObservablePair (value, f= f, g= g)
164
- ui = input (pair. second; typ= $ str, kwargs... )
164
+ ui = input (theme, pair. second; typ= $ str, kwargs... )
165
165
Widget {$(Expr(:quote, func))} (ui, output = value)
166
166
end
167
167
168
- function $func (T :: WidgetTheme , vals:: AbstractRange , val= medianelement (vals); value= val, kwargs... )
168
+ function $func (theme :: WidgetTheme , vals:: AbstractRange , val= medianelement (vals); value= val, kwargs... )
169
169
f = x -> x === nothing ? " " : _string (x)
170
170
fs = x -> x === nothing ? " " : split (string (convert ($ unit, x)), ' ' )[1 ]
171
171
min, max = extrema (vals)
172
- $ func (T ; value= value, min= f (min), max= f (max), step= fs (step (vals)), kwargs... )
172
+ $ func (theme ; value= value, min= f (min), max= f (max), step= fs (step (vals)), kwargs... )
173
173
end
174
174
end
175
175
end
@@ -195,18 +195,18 @@ Create a widget to select numbers with placeholder `label`. An optional `range`
195
195
specifies maximum and minimum value accepted as well as the step. Use `step="any"` to allow all
196
196
decimal numbers.
197
197
"""
198
- function spinbox (:: WidgetTheme , label= " " ; value= nothing , placeholder= label, isinteger= nothing , kwargs... )
198
+ function spinbox (theme :: WidgetTheme , label= " " ; value= nothing , placeholder= label, isinteger= nothing , kwargs... )
199
199
isinteger === nothing || @warn " `isinteger` is deprecated"
200
200
if ! isa (value, AbstractObservable)
201
201
T = something (isinteger, isa (value, Integer)) ? Int : Float64
202
202
value = Observable {Union{T, Nothing}} (value)
203
203
end
204
- ui = input (value; isnumeric= true , placeholder= placeholder, typ= " number" , kwargs... )
205
- Widget {:spinbox} (ui, output = value)
204
+ ui = input (theme, value; isnumeric= true , placeholder= placeholder, typ= " number" , kwargs... )
205
+ Widget {:spinbox} (ui; output = value)
206
206
end
207
207
208
- spinbox (T :: WidgetTheme , vals:: AbstractRange , args... ; value= first (vals), kwargs... ) =
209
- spinbox (T , args... ; value= value, min= minimum (vals), max= maximum (vals), step= step (vals), kwargs... )
208
+ spinbox (theme :: WidgetTheme , vals:: AbstractRange , args... ; value= first (vals), kwargs... ) =
209
+ spinbox (theme , args... ; value= value, min= minimum (vals), max= maximum (vals), step= step (vals), kwargs... )
210
210
211
211
"""
212
212
`autocomplete(options, label=""; value="")`
236
236
Create an HTML5 input element of type `type` (e.g. "text", "color", "number", "date") with `o`
237
237
as initial value.
238
238
"""
239
- function input (:: WidgetTheme , o; extra_js= js "" , extra_obs= [], label= nothing , typ= " text" , wdgtyp= typ,
239
+ @noinline function input (theme :: WidgetTheme , o; extra_js= js "" , extra_obs= [], label= nothing , typ= " text" , wdgtyp= typ,
240
240
className= " " , style= Dict (), isnumeric= Knockout. isnumeric (o),
241
241
computed= [], attributes= Dict (), bind= " value" , bindto= " value" , valueUpdate= " input" , changes= 0 , kwargs... )
242
242
@@ -254,15 +254,15 @@ function input(::WidgetTheme, o; extra_js=js"", extra_obs=[], label=nothing, typ
254
254
Symbol (" data-bind" ) => " $bind : $bindto , valueUpdate: '$valueUpdate ', event: {change: $countChanges }"
255
255
)
256
256
)
257
- className = mergeclasses (getclass (:input , wdgtyp), className)
257
+ className = mergeclasses (getclass (theme, :input , wdgtyp), className)
258
258
template = node (:input ; className= className, attributes= attrDict, style= style, kwargs... )()
259
259
ui = knockout (template, data, extra_js; computed= computed)
260
- (label != nothing ) && (ui. dom = flex_row (wdglabel (label), ui. dom))
261
- slap_design! (ui)
260
+ (label != nothing ) && (ui. dom = flex_row (wdglabel (theme, label), ui. dom))
261
+ slap_design! (ui, theme )
262
262
Widget {:input} (data, scope = ui, output = ui[bindto], layout = node (:div , className = " field interact-widget" )∘ Widgets. scope)
263
263
end
264
264
265
- function input (:: WidgetTheme ; typ= " text" , kwargs... )
265
+ @noinline function input (:: WidgetTheme ; typ= " text" , kwargs... )
266
266
if typ in [" checkbox" , " radio" ]
267
267
o = false
268
268
elseif typ in [" number" , " range" ]
@@ -283,41 +283,41 @@ The `clicks` variable is initialized at `value=0`. Given a button `b`, `b["is-lo
283
283
whether the button is in a loading state (spinning wheel). Use `b["is-loading"][]=true` or
284
284
`b["is-loading"][]=false` respectively to display or take away the spinner.
285
285
"""
286
- function button (:: WidgetTheme , content... ; label = " Press me!" , value = 0 , style = Dict {String, Any} (),
287
- className = getclass (:button , " primary" ), attributes= Dict (), kwargs... )
286
+ function button (theme :: WidgetTheme , content... ; label = " Press me!" , value = 0 , style = Dict {String, Any} (),
287
+ className = getclass (theme, :button , " primary" ), attributes= Dict (), kwargs... )
288
288
isempty (content) && (content = (label,))
289
289
(value isa AbstractObservable) || (value = Observable (value))
290
290
loading = Observable (false )
291
- className = " delete" in split (className, ' ' ) ? className : mergeclasses (getclass (:button ), className)
291
+ className = " delete" in split (className, ' ' ) ? className : mergeclasses (getclass (theme, :button ), className)
292
292
countClicks = js_lambda (" this.clicks(this.clicks()+1)" )
293
293
attrdict = merge (
294
294
Dict (" data-bind" => " click: $countClicks , css: {'is-loading' : loading}" ),
295
295
attributes
296
296
)
297
297
template = node (:button , content... ; className= className, attributes= attrdict, style= style, kwargs... )
298
298
button = knockout (template, [" clicks" => value, " loading" => loading])
299
- slap_design! (button)
299
+ slap_design! (button, theme )
300
300
Widget {:button} ([" is-loading" => loading], scope = button, output = value,
301
301
layout = node (:div , className = " field interact-widget" )∘ Widgets. scope)
302
302
end
303
303
304
304
for wdg in [:toggle , :checkbox ]
305
305
@eval begin
306
- $ wdg (:: WidgetTheme , value, lbl:: AbstractString = " " ; label= lbl, kwargs... ) =
307
- $ wdg (gettheme () ; value= value, label= label, kwargs... )
306
+ $ wdg (theme :: WidgetTheme , value, lbl:: AbstractString = " " ; label= lbl, kwargs... ) =
307
+ $ wdg (theme ; value= value, label= label, kwargs... )
308
308
309
- $ wdg (:: WidgetTheme , label:: AbstractString , val= false ; value= val, kwargs... ) =
310
- $ wdg (gettheme () ; value= value, label= label, kwargs... )
309
+ $ wdg (theme :: WidgetTheme , label:: AbstractString , val= false ; value= val, kwargs... ) =
310
+ $ wdg (theme ; value= value, label= label, kwargs... )
311
311
312
- $ wdg (:: WidgetTheme , value:: AbstractString , label:: AbstractString ; kwargs... ) =
312
+ $ wdg (theme :: WidgetTheme , value:: AbstractString , label:: AbstractString ; kwargs... ) =
313
313
error (" value cannot be a string" )
314
314
315
- function $wdg (:: WidgetTheme ; bind= " checked" , valueUpdate= " change" , value= false , label= " " , labelclass= " " , kwargs... )
315
+ function $wdg (theme :: WidgetTheme ; bind= " checked" , valueUpdate= " change" , value= false , label= " " , labelclass= " " , kwargs... )
316
316
s = gensym () |> string
317
317
(label isa Tuple) || (label = (label,))
318
318
widgettype = $ (Expr (:quote , wdg))
319
319
wdgtyp = string (widgettype)
320
- labelclass = mergeclasses (getclass (:input , wdgtyp, " label" ), labelclass)
320
+ labelclass = mergeclasses (getclass (theme, :input , wdgtyp, " label" ), labelclass)
321
321
ui = input (value; bind= bind, typ= " checkbox" , valueUpdate= " change" , wdgtyp= wdgtyp, id= s, kwargs... )
322
322
Widgets. scope (ui). dom = node (:div , className = " field interact-widget" )(Widgets. scope (ui). dom, dom " label[className=$labelclass, for=$s]" (label... ))
323
323
Widget {widgettype} (ui)
@@ -349,8 +349,8 @@ e.g. `textbox("enter number:")`. Use `typ=...` to specify the type of text. For
349
349
`typ="email"` or `typ="password"`. Use `multiline=true` to display a `textarea` spanning
350
350
several lines.
351
351
"""
352
- function textbox (:: WidgetTheme , hint= " " ; multiline= false , placeholder= hint, value= " " , typ= " text" , kwargs... )
353
- multiline && return textarea (gettheme () ; placeholder= placeholder, value= value, kwargs... )
352
+ function textbox (theme :: WidgetTheme , hint= " " ; multiline= false , placeholder= hint, value= " " , typ= " text" , kwargs... )
353
+ multiline && return textarea (theme ; placeholder= placeholder, value= value, kwargs... )
354
354
Widget {:textbox} (input (value; typ= typ, placeholder= placeholder, kwargs... ))
355
355
end
356
356
@@ -360,25 +360,25 @@ end
360
360
Create a textarea with an optional placeholder `hint`
361
361
e.g. `textarea("enter number:")`. Use `rows=...` to specify how many rows to display
362
362
"""
363
- function textarea (:: WidgetTheme , hint= " " ; label= nothing , className= " " ,
363
+ function textarea (theme :: WidgetTheme , hint= " " ; label= nothing , className= " " ,
364
364
placeholder= hint, value= " " , attributes= Dict (), style= Dict (), bind= " value" , valueUpdate = " input" , kwargs... )
365
365
366
366
(value isa AbstractObservable) || (value = Observable (value))
367
367
attrdict = convert (PropDict, attributes)
368
368
attrdict[:placeholder ] = placeholder
369
369
attrdict[" data-bind" ] = " $bind : value, valueUpdate: '$valueUpdate '"
370
- className = mergeclasses (getclass (:textarea ), className)
370
+ className = mergeclasses (getclass (theme, :textarea ), className)
371
371
template = node (:textarea ; className= className, attributes= attrdict, style= style, kwargs... )
372
372
ui = knockout (template, [" value" => value])
373
- (label != nothing ) && (ui. dom = flex_row (wdglabel (label), ui. dom))
374
- slap_design! (ui)
373
+ (label != nothing ) && (ui. dom = flex_row (wdglabel (theme, label), ui. dom))
374
+ slap_design! (ui, theme )
375
375
Widget {:textarea} (scope = ui, output = ui[" value" ], layout = node (:div , className = " field interact-widget" )∘ Widgets. scope)
376
376
end
377
377
378
- function wdglabel (T :: WidgetTheme , text; padt= 5 , padr= 10 , padb= 0 , padl= 10 ,
378
+ function wdglabel (theme :: WidgetTheme , text; padt= 5 , padr= 10 , padb= 0 , padl= 10 ,
379
379
className= " " , style = Dict (), kwargs... )
380
380
381
- className = mergeclasses (getclass (:wdglabel ), className)
381
+ className = mergeclasses (getclass (theme, :wdglabel ), className)
382
382
padding = Dict (:padding => " $(padt) px $(padr) px $(padb) px $(padl) px" )
383
383
node (:label , text; className= className, style = merge (padding, style), kwargs... )
384
384
end
0 commit comments