diff --git a/package.json b/package.json index ec6f43f9fd..9fb27524e2 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,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..cf58a1bcbc 100644 --- a/src/components/select/Empty.tsx +++ b/src/components/select/Empty.tsx @@ -3,43 +3,40 @@ 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..40b8ed4f0c --- /dev/null +++ b/src/components/select/OptionsList.tsx @@ -0,0 +1,169 @@ +import React, { useMemo } from 'react'; +import { isNull, noop } from 'lodash'; +import classnames from 'classnames'; +import VirtualList from './VirtualList'; +import { OptionsListProps, Option, MaybeArray } from './interface'; +import Tooltip from '../tooltip'; +import Checkbox from '../checkbox'; + +interface GroupProps { + option: Option; + prefixCls: string; + groupStyle: React.CSSProperties | undefined; +} + +interface TooltipProps { + render: JSX.Element & React.ReactNode; + getContainer?: (node: HTMLElement) => HTMLElement; + prefixCls?: string; + tooltip?: string; +} + +interface OptionProp { + option: Option; + selected: MaybeArray | null | undefined; + prefixCls?: string; + labelRenderer?: (option: Option, isGruop: false) => React.ReactNode; + onOptionClick?: (selectedValue: string | number) => void; + optionStyle?: React.CSSProperties | undefined; + multiple?: boolean; + children?: React.ReactNode; +} + +const RenderGroup: React.FC = (props) => { + const { + option: { value, label }, + prefixCls, + groupStyle, + } = props; + return ( + + ); +}; + +const RenderOption: React.FC = (props) => { + const { + option: { value, disabled, tooltip, groupValue, groupLabel, label, title, ...restOption }, + selected, + onOptionClick, + labelRenderer, + prefixCls, + optionStyle, + multiple, + } = props; + const isSelected = + typeof selected === 'string' || typeof selected === 'number' || isNull(selected) || 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, + ...restOption, + }, + false + ) + : title || label; + return ( +
+ +
+ ); +}; + +const RenderTooltip: React.FC = (props) => { + const { tooltip, render, getContainer } = props; + if (tooltip) { + return ( + + {render} + + ); + } + return render; +}; + +const getFlattenOptions = (data: Option[], hasGroup: boolean) => { + const groupMap = new Map(); + if (!hasGroup) return data; + data?.map((cur: Option) => { + 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 flattenOption: Option[] = []; + groupMap.forEach((value) => { + flattenOption.push(value); + flattenOption.push(...value.options); + }); + return flattenOption; +}; +const OptionsList: React.FC = (props) => { + const { prefixCls, data, groupStyle, hasGroup, height, itemHeight, ...restProps } = props; + + const flattenOptions = useMemo(() => getFlattenOptions(data, hasGroup), [data, hasGroup]); + return ( + + {(option: Option & { isSelectOptGroup: boolean }) => { + return option.isSelectOptGroup ? ( + + ) : ( + } + /> + ); + }} + + ); +}; + +export default OptionsList; diff --git a/src/components/select/Select.stories.tsx b/src/components/select/Select.stories.tsx index cf777ebf83..3ce996b36e 100644 --- a/src/components/select/Select.stories.tsx +++ b/src/components/select/Select.stories.tsx @@ -1,13 +1,15 @@ -import React from 'react'; +import React, { useRef } from 'react'; import { Story, Meta } from '@storybook/react/types-6-0'; - -import Select from './index'; -import { SelectProps } from './interface'; +import Select, { OptionProps, SelectProps } from './index'; import './style'; export default { title: 'Components/Functional/Select', component: Select, + subcomponents: { + Group: Select.Group, + Option: Select.Option, + }, } as Meta; const labels = ['全部', '已上线', '待上线', '已下线', '草稿']; @@ -17,11 +19,38 @@ const optionsWithoutGroup = values.map((value, index) => ({ label: labels[index], })); -export const Default: Story = (args) => ; +}; +export const Default = Template.bind({}); Default.args = { - size: 'small', - style: { width: 140 }, placeholder: '请选择', + searchable: true, + disabled: false, + multiple: false, + bordered: true, + allowClear: true, + className: 'gio-demo', + allowCustomOption: true, + size: 'small', options: optionsWithoutGroup, + style: { width: 160 }, + onChange: (value: string | number, option: OptionProps) => { + console.log('onchange', value, option); + }, + onSearch: (input: string) => { + console.log('input', input); + }, + onSelect: (value: string | number, option: OptionProps) => { + console.log('onselect', value, option); + }, + allowDeselect: false, + onDeSelect: (value: string | number, option: OptionProps) => { + console.log('ondeselect', value, option); + }, + onClear: () => { + console.log('clear'); + }, }; diff --git a/src/components/select/Select.tsx b/src/components/select/Select.tsx index 6fb6413a60..a68fed4213 100644 --- a/src/components/select/Select.tsx +++ b/src/components/select/Select.tsx @@ -1,67 +1,35 @@ 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, isNull } 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 })); - } - }); - return nodeOptions; -} - -export const CustomOption = (value: string | number, withGroup = false, id = customOptionKeyPrefix): OptionProps => - withGroup +export const CustomOption = (value: string | number, withGroup = false, id = customOptionKeyPrefix): Option => { + return withGroup ? { value, label: value.toString(), @@ -72,13 +40,13 @@ export const CustomOption = (value: string | number, withGroup = false, id = cus 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; + if (isGroup || typeof option.label !== 'string') return option.title || option.label; const index = option.label.indexOf(input); return (
@@ -88,15 +56,13 @@ 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?.title || 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) => { - const sizeContext = useContext(SizeContext); - const { - size = sizeContext || 'middle', - options = [], - multiple = false, - allowClear = false, - placeholder, - searchable = false, - disabled = false, - allowCustomOption = false, - notFoundContent = defaultNotFoundContent, - customizePrefixCls, - className, - style, - bordered = true, - arrowComponent = defaultArrowComponent, - autoWidth = true, - listHeight, - listRowHeight = defaultListRowHeight, - labelRenderer = defaultLabelRenderer, - searchPredicate = defaultSearchPredicate, - matchPredicate = defaultMatchPredicate, - optionLabelRenderer = defaultOptionLabelRenderer, - defaultValue, - value: controlledValue, - onChange, - onSearch, - onSelect, - onDeselect, - 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; - const [isFocused, setFocused] = useState(false); - const [isHovered, setIsHovered] = useState(false); - const [_visible, _setVisible] = useState(false); - const visible = isNil(dropDownVisible) ? _visible : dropDownVisible; - const setVisbile = isNil(onDropDownVisibleChange) ? _setVisible : onDropDownVisibleChange; - const [input, setInput] = useState(''); - const inputRef = useRef(null); - const [inputWidth, setInputWidth] = useState(2); - const inputWidthRef = useRef(null); - const selectRef = useRef(null) - const selectorRef = ref || selectRef; - const clearInput = () => { - setInput(''); - }; - - const onInputChange = (e: React.ChangeEvent) => { - e.preventDefault(); - onSearch?.(e.target.value); - setInput(e.target.value); - }; - 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]); +interface CompoundedSelect extends React.ForwardRefExoticComponent> { + Group: typeof OptGroup; + Option: typeof Options; +} - useEffect(() => { - if (!disabled) { - setFocused(visible); - if (visible) { - if (inputRef.current) { - inputRef.current.focus(); +const Select = React.forwardRef( + (props: SelectProps, ref: React.MutableRefObject) => { + const sizeContext = useContext(SizeContext); + const { + size = sizeContext || 'middle', + options = [], + defaultValue = null, + 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, + optionStyle, + groupStyle, + arrowComponent, + closeComponent, + listHeight = defaultListHeight, + listRowHeight = defaultListRowHeight, + labelRenderer = defaultLabelRenderer, + searchPredicate = defaultSearchPredicate, + matchPredicate = defaultMatchPredicate, + optionLabelRenderer = defaultOptionLabelRenderer, + onChange, + onSearch, + onSelect, + onDeselect, + onClear, + getContainer, + dropDownVisible, + onDropDownVisibleChange, + dropDownClassName, + dropDownStyle, + children, + } = props; + + const prefix = usePrefixCls('select', customizePrefixCls); + const [unControlledValue, setUnControlledValue] = useState(defaultValue); + const isControlled = !isNil(controlledValue); + const value = isControlled ? controlledValue : unControlledValue; + const [isFocused, setFocused] = useState(false); + const [isHovered, setIsHovered] = useState(false); + const [_visible, _setVisible] = useState(false); + const visible = isNil(dropDownVisible) ? _visible : dropDownVisible; + const setVisbile = isNil(onDropDownVisibleChange) ? _setVisible : onDropDownVisibleChange; + const [input, setInput] = useState(''); + const inputRef = useRef(null); + const [inputWidth, setInputWidth] = useState(2); + 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); + setInput(e.target.value); + }; + const onInputClick = (e: React.MouseEvent) => { + if (input) e.stopPropagation(); + }; + + useEffect(() => { + if (inputWidthRef.current) { + setInputWidth(inputWidthRef.current?.getBoundingClientRect().width + 4); } - } - }, [visible, disabled]); - - const onVisibleChange = (optVisible: boolean) => { - if (!disabled) { - setVisbile(optVisible); - if (!optVisible) { - setTimeout(clearInput, 0); - inputRef.current?.blur(); + }, [input]); + + useEffect(() => { + if (!disabled) { + setFocused(visible); + if (visible) { + if (inputRef.current) { + inputRef.current.focus(); + } + } } - } - }; - - const getOptionByValue = useCallback( - (optValue: string | number): OptionProps | undefined => { - return valueToOptionMap.get(optValue); - }, - [valueToOptionMap] - ); - - const getOptionsByValue = (optValue: MaybeArray): MaybeArray | undefined => { - return Array.isArray(optValue) - ? optValue.reduce((prev: OptionProps[], v) => { + }, [visible, disabled]); + + const onVisibleChange = (optVisible: boolean) => { + if (!disabled) { + setVisbile(optVisible); + if (!optVisible) { + setTimeout(clearInput, 0); + inputRef.current?.blur(); + } + } + }; + // value to option || options + const getOptionByValue = useCallback( + (optValue: string | number): Option => { + return flattenOptionsMap.get(optValue); + }, + [flattenOptionsMap] + ); + + const getOptionsByValue = (optValue: MaybeArray): MaybeArray