Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor select, fix tab/keyboard navigation #3157

Merged
merged 16 commits into from May 4, 2018

Conversation

SergioCrisostomo
Copy link
Contributor

This PR is a refactor of the Select component to reduce complexity and code length.
It uses the great work done by @Xotic750 and should solve the tab/keyboard navigation functionality related to #1647

Review welcome! If there are some things I forgot let me know.

@icarusion
Copy link
Contributor

Yesterday in #3156 and #3172 , changed something about Select, about popper.js we discussed before.

@SergioCrisostomo SergioCrisostomo force-pushed the refactor-select branch 3 times, most recently from 30e80e3 to 041b93a Compare March 16, 2018 08:58
@icarusion
Copy link
Contributor

1

When the dropdown is expanded, the up and down key can not use(throw errors).

2

in Searchable mode, the width of dropdown is not correct(looks width is 100%?):

<template>
    <div style="width: 200px;">
        <Select v-model="model11" filterable>
            <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
        </Select>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                cityList: [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    },
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ],
                model11: ''
            }
        }
    }
</script>

image

3

In remote search type, select an item, then delete a few letters, lose focus, will not be restored. And initials will be converted to lowercase.
Image: http://7u2ka3.com1.z0.glb.clouddn.com/iview-issue/select/1.gif

<template>
    <div style="width: 200px">
        <Select
                v-model="model13"
                filterable
                remote
                :remote-method="remoteMethod1"
                :loading="loading1">
            <Option v-for="(option, index) in options1" :value="option.value" :key="index">{{option.label}}</Option>
        </Select>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                model13: '',
                loading1: false,
                options1: [],
                list: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New hampshire', 'New jersey', 'New mexico', 'New york', 'North carolina', 'North dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode island', 'South carolina', 'South dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West virginia', 'Wisconsin', 'Wyoming']
            }
        },
        methods: {
            remoteMethod1 (query) {
                if (query !== '') {
                    this.loading1 = true;
                    setTimeout(() => {
                        this.loading1 = false;
                        const list = this.list.map(item => {
                            return {
                                value: item,
                                label: item
                            };
                        });
                        this.options1 = list.filter(item => item.label.toLowerCase().indexOf(query.toLowerCase()) > -1);
                    }, 200);
                } else {
                    this.options1 = [];
                }
            }
        }
    }
</script>

4

The animation direction of the panel expansion is incorrect, it is not valid after the merge(after popper.js updated).

5

In remove search, when search something, and select an item, the dropdown will hide(show not hide), diff:
old: http://7u2ka3.com1.z0.glb.clouddn.com/iview-issue/select2.gif
now: http://7u2ka3.com1.z0.glb.clouddn.com/iview-issue/select/2.gif

@icarusion
Copy link
Contributor

6

About AutoComplete, the last demo of doc is incorrect:

<template>
    <AutoComplete
        v-model="value4"
        icon="ios-search"
        placeholder="input here"
        style="width:300px">
        <div class="demo-auto-complete-item" v-for="item in data4">
            <div class="demo-auto-complete-group">
                <span>{{ item.title }}</span>
                <a href="https://www.google.com/search?q=iView" target="_blank">更多</a>
            </div>
            <Option v-for="option in item.children" :value="option.title" :key="option.title">
                <span class="demo-auto-complete-title">{{ option.title }}</span>
                <span class="demo-auto-complete-count">{{ option.count }} 人关注</span>
            </Option>
        </div>
        <a href="https://www.google.com/search?q=iView" target="_blank" class="demo-auto-complete-more">查看所有结果</a>
    </AutoComplete>
</template>
<script>
    export default {
        data () {
            return {
                value4: '',
                data4: [
                    {
                        title: '话题',
                        children: [
                            {
                                title: 'iView',
                                count: 10000,

                            },
                            {
                                title: 'iView UI',
                                count: 10600,

                            }
                        ]
                    },
                    {
                        title: '问题',
                        children: [
                            {
                                title: 'iView UI 有多好',
                                count: 60100,

                            },
                            {
                                title: 'iView 是啥',
                                count: 30010,

                            }
                        ]
                    },
                    {
                        title: '文章',
                        children: [
                            {
                                title: 'iView 是一个设计语言',
                                count: 100000,

                            }
                        ]
                    }
                ]
            }
        }
    }
</script>
<style>
    .demo-auto-complete-item{
        padding: 4px 0;
        border-bottom: 1px solid #F6F6F6;
    }
    .demo-auto-complete-group{
        font-size: 12px;
        padding: 4px 6px;
    }
    .demo-auto-complete-group span{
        color: #666;
        font-weight: bold;
    }
    .demo-auto-complete-group a{
        float: right;
    }
    .demo-auto-complete-count{
        float: right;
        color: #999;
    }
    .demo-auto-complete-more{
        display: block;
        margin: 0 auto;
        padding: 4px;
        text-align: center;
        font-size: 12px;
    }
</style>

@icarusion
Copy link
Contributor

In addition to the No.1, the remaining issues still exist. And something new:

7

In disabled mode, the arrow style looks wrong.
qq20180322-105435

8

In group, up and down key can not use.

<template>
    <Select v-model="model7" style="width:200px">
        <OptionGroup label="Hot Cities">
            <Option v-for="item in cityList1" :value="item.value" :key="item.value">{{ item.label }}</Option>
        </OptionGroup>
        <OptionGroup label="Other Cities">
            <Option v-for="item in cityList2" :value="item.value" :key="item.value">{{ item.label }}</Option>
        </OptionGroup>
    </Select>
</template>
<script>
    export default {
        data () {
            return {
                cityList: [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    },
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ],
                cityList1: [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    }
                ],
                cityList2: [
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ],
                model7: ''
            }
        }
    }
</script>

9

When press up or down key, the highlight item can not be focused when over about 7 items.
http://7u2ka3.com1.z0.glb.clouddn.com/iview-issue/select/3.gif

@@ -1,4 +1,4 @@
@select-dropdown-prefix-cls: ~"@{css-prefix}select-dropdown";
@select-dropdown-prefix-cls: ~"@{css-prefix}dropdown";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this will affect the style of the Dropdown component.

@icarusion
Copy link
Contributor

icarusion commented Mar 26, 2018

@icarusion
Copy link
Contributor

13

in single search type, when select an item, and can not select another:
http://7u2ka3.com1.z0.glb.clouddn.com/iview-issue/select/8.gif

<template>
    <Select v-model="model11" filterable>
        <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
    </Select>
</template>
<script>
    export default {
        data () {
            return {
                cityList: [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    },
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ],
                model11: ''
            }
        }
    }
</script>

@icarusion
Copy link
Contributor

14

When set v-model data init, and option-data is empty, throw error:

<template>
    <div style="margin: 200px;width: 200px;">
        <Select v-model="model11" filterable>
            <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
        </Select>
        <Button @click="addData">add data</Button>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                cityList: [

                ],
                model11: 'New York'
            }
        },
        methods: {
            addData () {
                this.cityList = [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    },
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ];
            }
        }
    }
</script>

@icarusion
Copy link
Contributor

15

Extension of No.14, the new problem is when set data sync, the v-model item not selected.

code:

<template>
    <div style="margin: 200px;width: 200px;">
        <Select v-model="model11" filterable>
            <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
        </Select>
        <Button @click="addData">add data</Button>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                cityList: [

                ],
                model11: 'New York'
            }
        },
        methods: {
            addData () {
                this.cityList = [
                    {
                        value: 'New York',
                        label: 'New York'
                    },
                    {
                        value: 'London',
                        label: 'London'
                    },
                    {
                        value: 'Sydney',
                        label: 'Sydney'
                    },
                    {
                        value: 'Ottawa',
                        label: 'Ottawa'
                    },
                    {
                        value: 'Paris',
                        label: 'Paris'
                    },
                    {
                        value: 'Canberra',
                        label: 'Canberra'
                    }
                ];
            }
        }
    }
</script>

@icarusion
Copy link
Contributor

16

problem of #3371
steps:

  1. select one item
  2. click button, and the options is empty, value removed
  3. click button again, the options just have one which last selected.
<template>
    <div style="margin: 200px;width: 200px;">
        <i-select filterable v-model="model">
            <i-option v-for="item in list" :key="item.value" :value="item.value">{{item.label}}</i-option>
        </i-select>
        <i-button @click="change">Click</i-button>
    </div>
</template>
<script>
    export default {
        data () {
            return {
                list: [{
                    value: 'a',
                    label: 'a'
                }, {
                    value: 'b',
                    label: 'b'
                }, {
                    value: 'c',
                    label: 'c'
                }],
                model: '',
            }
        },
        methods: {
            change: function(){
                if (this.list.length) {
                    this.model = '';
                    this.list = [];
                } else {
                    this.list = [{
                        value: 'a',
                        label: 'a'
                    }, {
                        value: 'b',
                        label: 'b'
                    }, {
                        value: 'c',
                        label: 'c'
                    }]
                }
            }
        }
    }
</script>

@icarusion
Copy link
Contributor

  • About AutoComplete, the problem is:
    When Option is not empty, the input box is focused and the drop-down panel is displayed without entering anything like:
    image
<template>
    <AutoComplete
        v-model="value4"
        icon="ios-search"
        placeholder="input here"
        style="width:300px">
        <div class="demo-auto-complete-item" v-for="item in data4">
            <div class="demo-auto-complete-group">
                <span>{{ item.title }}</span>
                <a href="https://www.google.com/search?q=iView" target="_blank">更多</a>
            </div>
            <Option v-for="option in item.children" :value="option.title" :key="option.title">
                <span class="demo-auto-complete-title">{{ option.title }}</span>
                <span class="demo-auto-complete-count">{{ option.count }} 人关注</span>
            </Option>
        </div>
        <a href="https://www.google.com/search?q=iView" target="_blank" class="demo-auto-complete-more">查看所有结果</a>
    </AutoComplete>
</template>
<script>
    export default {
        data () {
            return {
                value4: '',
                data4: [
                    {
                        title: '话题',
                        children: [
                            {
                                title: 'iView',
                                count: 10000,

                            },
                            {
                                title: 'iView UI',
                                count: 10600,

                            }
                        ]
                    },
                    {
                        title: '问题',
                        children: [
                            {
                                title: 'iView UI 有多好',
                                count: 60100,

                            },
                            {
                                title: 'iView 是啥',
                                count: 30010,

                            }
                        ]
                    },
                    {
                        title: '文章',
                        children: [
                            {
                                title: 'iView 是一个设计语言',
                                count: 100000,

                            }
                        ]
                    }
                ]
            }
        }
    }
</script>
<style>
    .demo-auto-complete-item{
        padding: 4px 0;
        border-bottom: 1px solid #F6F6F6;
    }
    .demo-auto-complete-group{
        font-size: 12px;
        padding: 4px 6px;
    }
    .demo-auto-complete-group span{
        color: #666;
        font-weight: bold;
    }
    .demo-auto-complete-group a{
        float: right;
    }
    .demo-auto-complete-count{
        float: right;
        color: #999;
    }
    .demo-auto-complete-more{
        display: block;
        margin: 0 auto;
        padding: 4px;
        text-align: center;
        font-size: 12px;
    }
</style>
  • Another problem with Select is that it throws many errors when selecting an item and scrolling the page(Any example will be reproduced):

image

SergioCrisostomo and others added 6 commits April 24, 2018 08:54
fixed in multiple type, when select some options, the position of popper not recalculation, so the position is wrong. By the way, it resolve the problem: when select one option, scroll page, throw many errors of popper.
@icarusion icarusion merged commit 4ce11f8 into iview:2.0 May 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants