Closed pier124 closed 1 month ago
There is something really strange. I tested with plain Quasar and got similar issues when using css as value of thumb-style
. If I set the prop as an js object it seems to work: https://codepen.io/rodja/pen/qBzGRjd?editors=101
But I if I try the same in NiceGUI, the whole page breaks:
with ui.scroll_area().props(":thumb-style=\"{background: 'red'}\""):
for i in range(100):
ui.label(f'item {i}')
Connection is dropped with this JS error in the console:
vue.global.prod.js:5 Uncaught TypeError: Failed to set an indexed property [0] on 'CSSStyleDeclaration': Indexed property setter is not supported.
at lr (vue.global.prod.js:5:64103)
at vue.global.prod.js:5:72459
at patchProp (vue.global.prod.js:5:72638)
at $ (vue.global.prod.js:5:34579)
at M (vue.global.prod.js:5:34286)
at T (vue.global.prod.js:5:33656)
at D (vue.global.prod.js:5:35048)
at $ (vue.global.prod.js:5:34458)
at M (vue.global.prod.js:5:34286)
at T (vue.global.prod.js:5:33656)
A difference between "bar-style" and "thumb-style" is that the latter doesn't accept strings:
But I don't understand why .props(":thumb-style=\"{background: 'red'}\"")
doesn't work.
Oh I found a solution:
.props(''' :thumb-style="({background: 'red'})" ''')
The brackets ()
prevent the curly braces being interpreted as a block statement rather than an object literal when passed to JavaScript's eval()
.
This can be solved by replacing eval()
in https://github.com/zauberzeug/nicegui/blob/2c676841090cf9d9f671a7cacf48c896eee95c51/nicegui/static/nicegui.js#L161 with new Function(`return (${value})`)();
like in https://github.com/zauberzeug/nicegui/blob/main/nicegui/static/utils/dynamic_properties.js. Maybe we can even use convertDynamicProperties()
directly and don't need to duplicate code.
I noticed one caveat:
Using new Function(`return ($(value)`)()
instead of eval(value)
breaks values with multiple statements:
ui.button('Loading').props('loading :percentage="{const p = 80; p}"')
This might be a very very rare case, but technically it would be a breaking change.
Description
this one works
this one doesn't (ui.scroll_area won't load at all):