zauberzeug / nicegui

Create web-based user interfaces with Python. The nice way.
https://nicegui.io
MIT License
9.76k stars 580 forks source link

When using the selected slot of ui.select, the panel is not displayed immediately. #2518

Open CrystalWindSnake opened 8 months ago

CrystalWindSnake commented 8 months ago

Description

When using the selected slot of ui.select as text, need to click twice for the options panel to be displayed. In addition, the selected-item slot also has this problem

# When chip is clicked, the options panel is displayed normally
select1 = ui.select(list("ab"), value="a")
with select1.add_slot("selected"):
    with ui.element("q-chip"):
        ui.label("a")

#  need to click on the chip twice for the options panel to appear
select2 = ui.select(list("ab"))
select2.add_slot(
    "selected",
    r"""
<q-chip>
  <div>{{ 'a' }}</div>
</q-chip>
""",
)

未命名项目

falkoschindler commented 8 months ago

Hu, this is strange. Thanks for reporting this issue, @CrystalWindSnake! Does anyone have an idea why this happens?

Here's an even more compact reproduction:

with ui.select(['a', 'b']).add_slot('selected'):
    with ui.element('q-chip'):
        ui.label('a')

ui.select(['a', 'b']).add_slot('selected', r'<q-chip><div>a</div></q-chip>')
CrystalWindSnake commented 8 months ago

I checked both cases and they end up generating the same html snippet. Don't understand why there is a difference in effect

CrystalWindSnake commented 7 months ago

@falkoschindler I seem to have found the problem, here is a reproduction of the problem using quasar.

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet"
        type="text/css">
    <link href="https://cdn.jsdelivr.net/npm/quasar@2.14.5/dist/quasar.prod.css" rel="stylesheet" type="text/css">
</head>

<body>
    <div id="works-app"> </div>
    <div id="issue-app"> </div>

    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@2.14.5/dist/quasar.umd.prod.js"></script>

    <script type="module">
        const { createApp } = Vue

        const works_app = createApp({
            render() {
                return Vue.h(Quasar.QSelect, {
                    filled: true,
                    modelValue: [],
                    options: ['a', 'b'],
                    label: "works",
                    multiple: true,
                    emitValue: true,
                    mapOptions: true
                }, {
                    selected: (props) => Vue.h(Quasar.QChip, {
                        innerHTML: 'a'
                    })
                })
            }
        }
        ).use(Quasar).mount('#works-app');

        const issue_app = createApp({
            render() {
                return Vue.h(Quasar.QSelect, {
                    filled: true,
                    modelValue: [],
                    options: ['a', 'b'],
                    label: "Multi with toggle",
                    multiple: true,
                    emitValue: true,
                    mapOptions: true
                }, {
                    selected: (props) => Vue.h({
                        template: `<q-chip>a</q-chip>`
                    })
                })
            }
        }
        ).use(Quasar).mount('#issue-app');

    </script>
</body>

</html>

When we render the entire slot string as a component into a virtual node, it seems that this virtual node will be rebuilt when clicked, ultimately causing the click to fail.

In addition, this problem leads to another small issue. When using a checkbox in a table slot, the checkbox's toggle transition animation will fail