From 9dbc1ac8e3988c8c3e095a815afe00cd8667b049 Mon Sep 17 00:00:00 2001 From: shiliqian Date: Fri, 22 Jan 2021 11:46:43 +0800 Subject: [PATCH] feat(select): independent select Remove list component dependency fix #677 --- package.json | 1 + .../__snapshots__/Pagination.test.js.snap | 220 ++++++++-- src/components/select/Empty.tsx | 26 -- src/components/select/OptionsList.tsx | 140 +++++++ src/components/select/Select.stories.tsx | 132 +++++- src/components/select/Select.tsx | 384 ++++++++++-------- src/components/select/VirtualList.tsx | 33 ++ .../select/__tests__/Select.test.js | 135 ++++-- .../__snapshots__/Select.test.js.snap | 18 +- src/components/select/interface.ts | 232 +++++++++-- src/components/select/style/index.less | 94 ++++- src/components/select/utils.ts | 37 ++ yarn.lock | 19 + 13 files changed, 1146 insertions(+), 325 deletions(-) create mode 100644 src/components/select/OptionsList.tsx create mode 100644 src/components/select/VirtualList.tsx create mode 100644 src/components/select/utils.ts diff --git a/package.json b/package.json index 82c22cfc13..baa84aa54e 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "rc-trigger": "^4.3.0", "rc-upload": "^3.2.0", "rc-util": "^5.0.5", + "rc-virtual-list": "^3.2.6", "react-dnd": "^11.1.3", "react-dnd-html5-backend": "^11.1.3", "react-use": "^15.3.3", diff --git a/src/components/pagination/__test__/__snapshots__/Pagination.test.js.snap b/src/components/pagination/__test__/__snapshots__/Pagination.test.js.snap index 41b52cc602..8594c2383f 100644 --- a/src/components/pagination/__test__/__snapshots__/Pagination.test.js.snap +++ b/src/components/pagination/__test__/__snapshots__/Pagination.test.js.snap @@ -1225,12 +1225,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -1443,9 +1444,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -1461,12 +1464,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -1761,9 +1765,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -2270,12 +2276,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -2488,9 +2495,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -2506,12 +2515,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -2806,9 +2816,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -4193,12 +4205,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -4411,9 +4424,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -4429,12 +4444,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -4729,9 +4745,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -5238,12 +5256,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -5456,9 +5475,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -5474,12 +5495,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -5774,9 +5796,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -6960,12 +6984,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -7178,9 +7203,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -7196,12 +7223,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -7496,9 +7524,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -8005,12 +8035,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -8223,9 +8254,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -8241,12 +8274,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -8541,9 +8575,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -9927,12 +9963,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -10145,9 +10182,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -10163,12 +10202,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -10463,9 +10503,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -10972,12 +11014,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -11190,9 +11233,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -11208,12 +11253,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -11508,9 +11554,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -12894,12 +12942,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -13112,9 +13161,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -13130,12 +13181,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -13430,9 +13482,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -13939,12 +13993,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -14157,9 +14212,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -14175,12 +14232,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -14475,9 +14533,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -15861,12 +15921,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -16079,9 +16140,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -16097,12 +16160,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -16397,9 +16461,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -16906,12 +16972,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -17124,9 +17191,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -17142,12 +17211,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -17442,9 +17512,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -18828,12 +18900,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -19046,9 +19119,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -19064,12 +19139,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -19364,9 +19440,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -19873,12 +19951,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -20091,9 +20170,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -20109,12 +20190,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -20409,9 +20491,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -21795,12 +21879,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -22013,9 +22098,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -22031,12 +22118,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -22331,9 +22419,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -22840,12 +22930,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -23058,9 +23149,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -23076,12 +23169,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -23376,9 +23470,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -24197,12 +24293,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -24415,9 +24512,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -24433,12 +24532,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -24733,9 +24833,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -25242,12 +25344,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -25460,9 +25563,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -25478,12 +25583,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -25778,9 +25884,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -27164,12 +27272,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -27382,9 +27491,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -27400,12 +27511,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -27700,9 +27812,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -28209,12 +28323,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -28427,9 +28542,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -28445,12 +28562,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -28745,9 +28863,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -29931,12 +30051,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -30149,9 +30270,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -30167,12 +30290,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -30467,9 +30591,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -30976,12 +31102,13 @@ initialize { "namespace": "http://www.w3.org/1999/xhtml", "next": Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -31194,9 +31321,11 @@ initialize { "prev": [Circular], "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, @@ -31212,12 +31341,13 @@ initialize { }, Object { "attribs": Object { + "aria-hidden": "true", "class": "gio-select-arrow", }, "children": Array [ Object { "attribs": Object { - "class": "gio-icon", + "class": "gio-icon gio-select-icon-arrow", }, "children": Array [ Object { @@ -31512,9 +31642,11 @@ initialize { }, "type": "tag", "x-attribsNamespace": Object { + "aria-hidden": undefined, "class": undefined, }, "x-attribsPrefix": Object { + "aria-hidden": undefined, "class": undefined, }, }, diff --git a/src/components/select/Empty.tsx b/src/components/select/Empty.tsx index b3dd323257..bf5a71cf90 100644 --- a/src/components/select/Empty.tsx +++ b/src/components/select/Empty.tsx @@ -3,32 +3,6 @@ import './style/empty.less'; function SvgComponent(): React.ReactElement { return ( - // - // - // - // - // - // - // - // - // diff --git a/src/components/select/OptionsList.tsx b/src/components/select/OptionsList.tsx new file mode 100644 index 0000000000..4d28a4934a --- /dev/null +++ b/src/components/select/OptionsList.tsx @@ -0,0 +1,140 @@ +import React, { useMemo, useRef } from 'react'; +import { noop } from 'lodash'; +import classnames from 'classnames'; +import VirtualList from './VirtualList'; +import { OptionsListProps, Option } from './interface'; +import Tooltip from '../tooltip'; +import Checkbox from '../checkbox'; + +const OptionsList: React.FC = (props) => { + const { + labelRenderer, + prefixCls, + data, + groupStyle, + optionStyle, + selected, + multiple, + hasGroup, + height, + itemHeight, + onOptionClick, + optionLabelRenderer, + ...restProps + } = props; + + const flettensOptions = useMemo(() => { + const groupMap = new Map(); + if (!hasGroup) return data; + data.map((cur) => { + const gvalue = groupMap.get(cur.groupValue) + if (gvalue) { + const { options, ...rest } = gvalue; + return groupMap.set(cur.groupValue, { + options: [...options, cur], + ...rest + }) + } + return groupMap.set(cur.groupValue, { + label: cur.groupLabel, + value: cur.groupValue, + isSelectOptGroup: true, + options: [cur] + }); + }) + const flettenOption: Option[] = []; + groupMap.forEach((value) => { + flettenOption.push(value) + flettenOption.push(...value.options) + }) + return flettenOption; + }, [data, hasGroup]) + + const renderGroupItem = (option: Option) => { + const { value, label } = option; + return ( + + ) + } + + const renderTootip = (option: Option, render: JSX.Element & React.ReactNode) => { + const { tooltip } = option; + if (tooltip) { + return ( + + {render} + + ) + } + return render + } + + const renderOption = (option: Option) => { + const { value, disabled, tooltip, groupValue, groupLabel, label, ...restOption } = option; + const isSelected = (typeof selected === 'string' || typeof selected === 'number' || typeof selected === 'undefined') ? selected === value : selected.includes(value); + const onClick = (event: React.MouseEvent) => { + event.stopPropagation(); + event.preventDefault(); + if (onOptionClick) { + onOptionClick(value) + } + }; + const labelNode = labelRenderer ? labelRenderer({ + value, + disabled, + tooltip, + groupValue, + groupLabel, + label: optionLabelRenderer(value, option), + ...restOption + }, false) : optionLabelRenderer(value, option); + return ( +
+ +
+ + ) + } + return ( + + {(option: Option & { isSelectOptGroup: boolean }) => option.isSelectOptGroup ? renderGroupItem(option) : renderTootip(option, renderOption(option))} + + ) +} + +export default OptionsList; \ No newline at end of file diff --git a/src/components/select/Select.stories.tsx b/src/components/select/Select.stories.tsx index cf777ebf83..5a58cdbb08 100644 --- a/src/components/select/Select.stories.tsx +++ b/src/components/select/Select.stories.tsx @@ -1,9 +1,12 @@ -import React from 'react'; +import React, { createRef, useState } from 'react'; import { Story, Meta } from '@storybook/react/types-6-0'; import Select from './index'; +import Button from '../button' +import Radio from '../radio' import { SelectProps } from './interface'; import './style'; +import { SizeType } from '../config-provider/SizeContext'; export default { title: 'Components/Functional/Select', @@ -12,16 +15,133 @@ export default { const labels = ['全部', '已上线', '待上线', '已下线', '草稿']; const values = ['all', 'online', 'pending', 'off', 'draft']; -const optionsWithoutGroup = values.map((value, index) => ({ + +const defaultValues = []; +let i = 0; + +while (i < 100) { + defaultValues.push(`${values[i % 5]}${i}`); + i +=1; +} + +const options = values.map((value,index)=>({ value, - label: labels[index], -})); + label:labels[index], + disabled:!!(index % 2), +})) -export const Default: Story = (args) => + +
+

多选

+ ; Default.args = { size: 'small', - style: { width: 140 }, placeholder: '请选择', options: optionsWithoutGroup, }; + +Search.args = { + // size: 'small', + searchable:true, + multiple:true, + placeholder: '请选择', + allowClear:true, + // allowCustomOption:true, + options: normal, +}; diff --git a/src/components/select/Select.tsx b/src/components/select/Select.tsx index 6fb6413a60..586494c270 100644 --- a/src/components/select/Select.tsx +++ b/src/components/select/Select.tsx @@ -1,81 +1,50 @@ import React, { useState, useContext, useMemo, useRef, useEffect, useCallback } from 'react'; import classnames from 'classnames'; - import { DownFilled, CloseCircleFilled } from '@gio-design/icons'; -import { filter, isNil, without, uniqueId, findIndex, concat, isEmpty } from 'lodash'; +import { filter, isNil, without, uniqueId, findIndex, isEmpty } from 'lodash'; import { SizeContext } from '../config-provider/SizeContext'; import Dropdown from '../dropdown'; import Tag from '../tag'; -import List from '../list'; +import OptionsList from './OptionsList'; import usePrefixCls from '../../utils/hooks/use-prefix-cls'; import Options from './Options'; import { SelectProps, Option, MaybeArray, OptionProps } from './interface'; import OptGroup from './OptGroup'; import BoxFilled from './Empty'; +import { convertChildrenToData } from './utils'; -const defaultArrowComponent = ; -const defaultListRowHeight = 44; +const defaultArrowComponent = (prefix: string) => { + return +}; +const defaultCloseComponent = (prefix: string) => { + return +}; +const defaultListRowHeight = 32; +const defaultListHeight = 240; const customOptionKeyPrefix = 'select_custom_option_'; +const ungroupedOptionKeyPrefix = 'select_isungrouped_option_'; const customOptionKey = uniqueId(customOptionKeyPrefix); +const ungroupedOptionKey = uniqueId(ungroupedOptionKeyPrefix); +const ungroupedOptionLabel = '未分组'; -interface CompoundedSelect extends React.ForwardRefExoticComponent> { - Group: typeof OptGroup; - Option: typeof Options; -} - -interface group { - key?: string | React.Key; - groupLabel?: string; - groupValue?: string | number; -} - -// ReactNode To Options -function convertNodeToOption(node: React.ReactElement, group: group): OptionProps { - const { - props: { value, label, children, ...restProps }, - } = node as React.ReactElement; - const { groupValue, groupLabel } = group; - return { value, label: children !== undefined ? children : label, groupValue, groupLabel, ...restProps }; -} - -export function convertChildrenToData(nodes: React.ReactNode, group = {}): OptionProps[] { - let nodeOptions: OptionProps[] = []; - React.Children.forEach(nodes, (node: React.ReactElement) => { - if (!React.isValidElement(node)) { - return; - } - const { - type: { isSelectOptGroup }, - props: { children, label, value }, - } = node as React.ReactElement & { type: { isSelectOptGroup?: boolean } }; // 联合类型 - if (!isSelectOptGroup) { - // option - nodeOptions.push(convertNodeToOption(node, group)); - } else { - // Group - nodeOptions = concat(nodeOptions, convertChildrenToData(children, { groupLabel: label, groupValue: value })); +export const CustomOption = (value: string | number, withGroup = false, id = customOptionKeyPrefix): Option => { + return withGroup + ? { + value, + label: value.toString(), + groupValue: id, + groupLabel: '自由输入', } - }); - return nodeOptions; + : + { + value, + label: value.toString(), + }; } - -export const CustomOption = (value: string | number, withGroup = false, id = customOptionKeyPrefix): OptionProps => - withGroup - ? { - value, - label: value.toString(), - groupValue: id, - groupLabel: '自由输入', - } - : { - value, - label: value.toString(), - }; - // provide search matching hightlight; export const defaultLabelRenderer = (input: string, prefix: string) => ( - option: OptionProps, + option: Option, isGroup: boolean ): React.ReactNode => { if (isGroup || typeof option.label !== 'string') return option.label; @@ -88,15 +57,12 @@ export const defaultLabelRenderer = (input: string, prefix: string) => (
); }; - -const defaultSearchPredicate = (input: string) => (o: OptionProps) => { - return typeof o.label === 'string' ? o.label.includes(input) : true; -}; - -const defaultMatchPredicate = (input: string) => (o: OptionProps) => o.label === input; - +const defaultOptionLabelRenderer = (value: string | number, option?: Option) => option?.label || value; +const defaultSearchPredicate = (input: string) => (o: Option) => typeof o.label === 'string' ? o.label.includes(input) : true; +const defaultMatchPredicate = (input: string) => (o: Option) => o.label === input; const defaultNotFoundContent = (
-
+
暂无选项
); -const defaultOptionLabelRenderer = (value: string | number, option?: OptionProps) => option?.label || value; -const Select = React.forwardRef((props: SelectProps, ref: React.MutableRefObject) => { +interface CompoundedSelect extends React.ForwardRefExoticComponent> { + Group: typeof OptGroup; + Option: typeof Options; +} + +const Select = React.forwardRef((props: SelectProps, ref: React.MutableRefObject) => { const sizeContext = useContext(SizeContext); const { size = sizeContext || 'middle', options = [], + defaultValue, + value: controlledValue, multiple = false, allowClear = false, placeholder, searchable = false, disabled = false, + bordered = true, allowCustomOption = false, + autoWidth = true, + allowDeselect = false || multiple, notFoundContent = defaultNotFoundContent, customizePrefixCls, className, style, - bordered = true, - arrowComponent = defaultArrowComponent, - autoWidth = true, - listHeight, + optionStyle, + groupStyle, + arrowComponent, + closeComponent, + listHeight = defaultListHeight, listRowHeight = defaultListRowHeight, labelRenderer = defaultLabelRenderer, searchPredicate = defaultSearchPredicate, matchPredicate = defaultMatchPredicate, optionLabelRenderer = defaultOptionLabelRenderer, - defaultValue, - value: controlledValue, onChange, onSearch, onSelect, onDeselect, + onClear, getContainer, dropDownVisible, onDropDownVisibleChange, dropDownClassName, dropDownStyle, children, - onClear, - allowDeselect = false || multiple, } = props; const prefix = usePrefixCls('select', customizePrefixCls); - const [unControlledValue, setUnControlledValue] = useState(defaultValue); const isControlled = !isNil(controlledValue); const value = isControlled ? controlledValue : unControlledValue; @@ -169,10 +141,36 @@ const Select = React.forwardRef((props: SelectProps, const inputWidthRef = useRef(null); const selectRef = useRef(null) const selectorRef = ref || selectRef; + const clearInput = () => { setInput(''); }; + /** merge Option & nodeOption & mergedOptionsMap */ + const nodesToOptions = useMemo(() => convertChildrenToData(children), [children]); + + const [flattenOptionsMap, mergedFlattenOPtions, hasGroup] = useMemo(() => { + const group = !![...options, ...nodesToOptions].find(v => Object.prototype.hasOwnProperty.call(v, 'groupValue')); + const flattenOptions: Option[] = []; + const optionsMap = [...options, ...nodesToOptions].reduce((m, option: Option) => { + const { groupLabel: optionGroupLabel, groupValue: optionGroupValue, value: optionValue } = option; + if (group && !optionGroupValue && !optionGroupLabel) { + const ungroupedOption = { + groupLabel: ungroupedOptionLabel, + groupValue: ungroupedOptionKey, + ...option + } + m.set(optionValue, ungroupedOption) + flattenOptions.push(ungroupedOption) + } else { + m.set(optionValue, option) + flattenOptions.push(option) + } + return m; + }, new Map()); + return [optionsMap, flattenOptions, group]; + }, [options, nodesToOptions]); + // input const onInputChange = (e: React.ChangeEvent) => { e.preventDefault(); onSearch?.(e.target.value); @@ -181,16 +179,12 @@ const Select = React.forwardRef((props: SelectProps, const onInputClick = (e: React.MouseEvent) => { if (input) e.stopPropagation(); }; - const nodesToOptions = useMemo(() => convertChildrenToData(children), [children]); - const [valueToOptionMap, hasGroup] = useMemo(() => { - let group = false; - const map = [...options, ...nodesToOptions].reduce((m, option) => { - if (option.groupLabel) group = true; - m.set(option.value, option); - return m; - }, new Map()); - return [map, group]; - }, [options, nodesToOptions]); + + useEffect(() => { + if (inputWidthRef.current) { + setInputWidth(inputWidthRef.current?.getBoundingClientRect().width + 4); + } + }, [input]); useEffect(() => { if (!disabled) { @@ -212,57 +206,56 @@ const Select = React.forwardRef((props: SelectProps, } } }; - + // value to option || options const getOptionByValue = useCallback( - (optValue: string | number): OptionProps | undefined => { - return valueToOptionMap.get(optValue); + (optValue: string | number): Option | undefined => { + return flattenOptionsMap.get(optValue); }, - [valueToOptionMap] + [flattenOptionsMap] ); - const getOptionsByValue = (optValue: MaybeArray): MaybeArray | undefined => { + const getOptionsByValue = (optValue: MaybeArray): MaybeArray