diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4bc1c2504..ca4b9e6037 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Features
- Added sourcemaps to the dist output to simplify debugging @miroslavstastny ([#2329](https://github.com/microsoft/fluent-ui-react/pull/2329))
- Adding 'expand', 'collapse', 'companion', 'share-to' and 'settings-audio' icons @TanelVari ([#2343](https://github.com/microsoft/fluent-ui-react/pull/2343))
+- Add support for Children API in `List` component @layershifter ([#2207](https://github.com/microsoft/fluent-ui-react/pull/2207))
### Performance
- Add styles caching when there aren't inline overrides defined @mnajdova ([#2309](https://github.com/microsoft/fluent-ui-react/pull/2309))
diff --git a/docs/src/examples/components/List/Content/ListExampleContent.tsx b/docs/src/examples/components/List/Content/ListExampleContent.tsx
index d1287a2b6e..0af74a9f5b 100644
--- a/docs/src/examples/components/List/Content/ListExampleContent.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleContent.tsx
@@ -3,9 +3,15 @@ import { List } from '@fluentui/react'
const ListExample = () => (
-
-
-
+
+
+
)
diff --git a/docs/src/examples/components/List/Content/ListExampleContentMedia.tsx b/docs/src/examples/components/List/Content/ListExampleContentMedia.tsx
index b7b58bf498..777b5c0131 100644
--- a/docs/src/examples/components/List/Content/ListExampleContentMedia.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleContentMedia.tsx
@@ -6,14 +6,17 @@ const ListExample = () => (
)
diff --git a/docs/src/examples/components/List/Content/ListExampleEndMedia.tsx b/docs/src/examples/components/List/Content/ListExampleEndMedia.tsx
index 2aa902d2ce..e0b855c182 100644
--- a/docs/src/examples/components/List/Content/ListExampleEndMedia.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleEndMedia.tsx
@@ -9,16 +9,19 @@ const ListExample = () => (
content="Program the sensor to the SAS alarm through the haptic SQL card!"
endMedia={ellipsis}
selectable
+ index={0}
/>
)
diff --git a/docs/src/examples/components/List/Content/ListExampleHeader.tsx b/docs/src/examples/components/List/Content/ListExampleHeader.tsx
index 0839a297d1..54d707793b 100644
--- a/docs/src/examples/components/List/Content/ListExampleHeader.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleHeader.tsx
@@ -3,9 +3,9 @@ import { List } from '@fluentui/react'
const ListExample = () => (
-
-
-
+
+
+
)
diff --git a/docs/src/examples/components/List/Content/ListExampleHeaderContent.tsx b/docs/src/examples/components/List/Content/ListExampleHeaderContent.tsx
index b1822eb1fe..a9bbceea56 100644
--- a/docs/src/examples/components/List/Content/ListExampleHeaderContent.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleHeaderContent.tsx
@@ -6,14 +6,17 @@ const ListExample = () => (
)
diff --git a/docs/src/examples/components/List/Content/ListExampleHeaderMedia.tsx b/docs/src/examples/components/List/Content/ListExampleHeaderMedia.tsx
index 91b19c8d95..971cd68712 100644
--- a/docs/src/examples/components/List/Content/ListExampleHeaderMedia.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleHeaderMedia.tsx
@@ -3,9 +3,9 @@ import { List } from '@fluentui/react'
const ListExample = () => (
-
-
-
+
+
+
)
diff --git a/docs/src/examples/components/List/Content/ListExampleMedia.tsx b/docs/src/examples/components/List/Content/ListExampleMedia.tsx
index 6028eef957..3da3a4c7d9 100644
--- a/docs/src/examples/components/List/Content/ListExampleMedia.tsx
+++ b/docs/src/examples/components/List/Content/ListExampleMedia.tsx
@@ -8,18 +8,21 @@ const ListExampleMedia = () => (
header="Irving Kuhic"
headerMedia="7:26:56 AM"
content="Program the sensor to the SAS alarm through the haptic SQL card!"
+ index={0}
/>
}
header="Skyler Parks"
headerMedia="11:30:17 PM"
content="Use the online FTP application to input the multi-byte application!"
+ index={1}
/>
}
header="Dante Schneider"
headerMedia="5:22:40 PM"
content="The GB pixel is down, navigate the virtual interface!"
+ index={2}
/>
)
diff --git a/docs/src/examples/components/List/Performance/ListNested.perf.tsx b/docs/src/examples/components/List/Performance/ListNested.perf.tsx
new file mode 100644
index 0000000000..22497bc11c
--- /dev/null
+++ b/docs/src/examples/components/List/Performance/ListNested.perf.tsx
@@ -0,0 +1,865 @@
+import { List } from '@fluentui/react'
+import * as React from 'react'
+
+const items = [
+ {
+ key: 'item-0',
+ media: 'ecd4:f115:0db5:e490:4680:e0bb:ed31:ef38',
+ header: 'Golden19',
+ headerMedia: '2/11/2019',
+ content: 'Veritatis labore tenetur eius similique voluptatem qui labore consequuntur eaque.',
+ contentMedia: 'Molestiae modi qui ipsam odio unde praesentium.',
+ },
+ {
+ key: 'item-1',
+ media: '812d:173e:02c2:3c33:d0a8:d86c:327b:4356',
+ header: 'Christine.Feeney',
+ headerMedia: '3/8/2019',
+ content: 'Sequi voluptas corporis vel deleniti exercitationem ipsam rem hic.',
+ contentMedia: 'Nulla quae minima.',
+ },
+ {
+ key: 'item-2',
+ media: '2f5e:5dab:e88c:b583:b512:b2c3:ecf6:f860',
+ header: 'Amaya.Ritchie',
+ headerMedia: '6/22/2019',
+ content: 'Neque nobis totam rerum.',
+ contentMedia: 'Aut tempora eaque rem blanditiis.',
+ },
+ {
+ key: 'item-3',
+ media: 'b072:ad2d:9ee1:f790:5e46:7b8c:75d1:4140',
+ header: 'Cora.Rippin22',
+ headerMedia: '7/13/2019',
+ content: 'Alias error tempore dolorem laudantium sapiente.',
+ contentMedia: 'Quis ducimus explicabo quia quia rerum dolor deserunt unde.',
+ },
+ {
+ key: 'item-4',
+ media: '9fbb:5c11:582f:e8dd:4e79:f56a:0acb:6bf9',
+ header: 'Melyssa_Walker3',
+ headerMedia: '9/26/2019',
+ content: 'Eum quo non eum repellendus facere sint.',
+ contentMedia: 'Fuga explicabo et ad labore voluptas voluptatibus et perspiciatis.',
+ },
+ {
+ key: 'item-5',
+ media: 'a6ba:8322:b8e2:98ad:f86d:9e87:6322:4058',
+ header: 'Martina.Cronin',
+ headerMedia: '11/27/2019',
+ content: 'Dolorem eveniet dolores repellat officia temporibus sequi.',
+ contentMedia: 'Odio commodi laborum nobis quia.',
+ },
+ {
+ key: 'item-6',
+ media: '5fcd:fa53:c6f1:3bc0:9add:2fd4:d01d:4bf7',
+ header: 'Trinity16',
+ headerMedia: '1/16/2020',
+ content: 'Debitis culpa sit consequatur corrupti.',
+ contentMedia: 'Vero placeat id.',
+ },
+ {
+ key: 'item-7',
+ media: 'f5fe:4259:50e5:72cd:67b3:650b:27c8:5ebc',
+ header: 'Emmet14',
+ headerMedia: '5/10/2019',
+ content: 'Ratione omnis nesciunt repellendus voluptatem aut sint amet voluptatem.',
+ contentMedia: 'Enim aliquam error quaerat.',
+ },
+ {
+ key: 'item-8',
+ media: 'fd29:194a:d44c:dfc0:fce1:bc6c:a75c:c873',
+ header: 'Chet87',
+ headerMedia: '7/30/2019',
+ content: 'Dolor dolor inventore illum eum nulla.',
+ contentMedia: 'Ut debitis aut.',
+ },
+ {
+ key: 'item-9',
+ media: '3f6c:62fe:deea:e526:e242:4e79:0883:8eb3',
+ header: 'Horacio39',
+ headerMedia: '5/6/2019',
+ content: 'Laborum fugit ut debitis voluptatum enim ea voluptas quas fugiat.',
+ contentMedia: 'Sint minus ut.',
+ },
+ {
+ key: 'item-10',
+ media: '5b44:9c9d:bb62:50a9:77b0:3a61:a133:818c',
+ header: 'Aletha.Heaney28',
+ headerMedia: '7/12/2019',
+ content: 'Magnam velit et quo.',
+ contentMedia: 'Distinctio delectus modi et.',
+ },
+ {
+ key: 'item-11',
+ media: '922b:68b1:432b:1c11:6734:e7de:baf6:d202',
+ header: 'Lempi85',
+ headerMedia: '6/3/2019',
+ content: 'Consequatur pariatur vel.',
+ contentMedia: 'Quis quibusdam at repellendus vero fuga accusamus atque provident aperiam.',
+ },
+ {
+ key: 'item-12',
+ media: '9c88:6bcf:1534:d98b:9dfa:170e:0fe4:6f99',
+ header: 'Dayton19',
+ headerMedia: '9/9/2019',
+ content: 'Tempora sint corrupti.',
+ contentMedia: 'Ea est id aut facilis ex possimus.',
+ },
+ {
+ key: 'item-13',
+ media: '931c:709c:7c0c:4142:8cb5:1e7d:a205:5ce5',
+ header: 'Jerel_Dooley95',
+ headerMedia: '4/7/2019',
+ content: 'Ullam nostrum est et necessitatibus possimus distinctio dolorum impedit dolor.',
+ contentMedia: 'Vitae tempore minima dolores tempora ea.',
+ },
+ {
+ key: 'item-14',
+ media: '6309:59b2:6fed:d765:077b:94fa:e22d:2a6a',
+ header: 'Tate.Kuhic',
+ headerMedia: '8/8/2019',
+ content: 'In rerum molestiae.',
+ contentMedia: 'Omnis voluptate nesciunt voluptatem.',
+ },
+ {
+ key: 'item-15',
+ media: 'a1b3:9bf4:3b64:4e8f:6a21:16c3:d208:551d',
+ header: 'Rosalee56',
+ headerMedia: '11/19/2019',
+ content: 'Mollitia quia saepe ut nihil et iure expedita repellendus.',
+ contentMedia: 'Consequuntur ea quia recusandae ratione.',
+ },
+ {
+ key: 'item-16',
+ media: '50d1:2a0c:5997:506a:e748:02f4:c9d2:0e45',
+ header: 'Dorothy_Osinski96',
+ headerMedia: '6/28/2019',
+ content: 'Eum temporibus dicta impedit quas.',
+ contentMedia: 'Consequatur autem minus ut eveniet quo suscipit illo.',
+ },
+ {
+ key: 'item-17',
+ media: '97e3:a2a2:8287:63a5:d1f6:5672:d711:7e8e',
+ header: 'Connie65',
+ headerMedia: '4/1/2019',
+ content: 'In ad beatae debitis.',
+ contentMedia: 'Quia quaerat ut aut in aspernatur et.',
+ },
+ {
+ key: 'item-18',
+ media: '05ce:4ecf:1041:8415:b358:be0e:a65c:c275',
+ header: 'Raphael44',
+ headerMedia: '3/6/2019',
+ content: 'Perferendis soluta hic sint eum.',
+ contentMedia: 'Ut voluptas et consectetur est.',
+ },
+ {
+ key: 'item-19',
+ media: 'cc8d:f10c:cf4f:82fa:64a2:1a36:2461:3434',
+ header: 'Roberta36',
+ headerMedia: '5/5/2019',
+ content: 'Molestiae nihil laborum hic pariatur deserunt ullam similique quibusdam quia.',
+ contentMedia: 'Qui qui id aut deserunt quidem temporibus voluptas.',
+ },
+ {
+ key: 'item-20',
+ media: '63ac:0869:ef30:fd2e:e7ce:71d0:2519:20c1',
+ header: 'Amara45',
+ headerMedia: '5/13/2019',
+ content: 'Placeat a sed quam vel ipsa et quisquam aspernatur.',
+ contentMedia: 'Aut vero accusamus veritatis atque laboriosam harum ab fugit aut.',
+ },
+ {
+ key: 'item-21',
+ media: '7f85:444a:43b9:c878:c5f8:02ac:796d:1006',
+ header: 'Cassandra86',
+ headerMedia: '1/21/2020',
+ content: 'Ut eaque id deserunt consequatur cupiditate.',
+ contentMedia: 'Ducimus aliquam voluptatem sed dolores reiciendis.',
+ },
+ {
+ key: 'item-22',
+ media: '1c44:7233:decf:3ba9:fc2f:6c14:3358:10eb',
+ header: 'Kasandra.Jacobson',
+ headerMedia: '6/4/2019',
+ content: 'Ut culpa nobis enim.',
+ contentMedia: 'Repellat ut nesciunt quis consequuntur ea.',
+ },
+ {
+ key: 'item-23',
+ media: '45da:675d:839f:4aad:c839:f771:16a3:433c',
+ header: 'Orrin65',
+ headerMedia: '1/9/2020',
+ content: 'Sit facilis nihil enim sint.',
+ contentMedia: 'Atque quia dolorem porro delectus libero optio ea ut.',
+ },
+ {
+ key: 'item-24',
+ media: 'f5bd:fd04:d136:e7cb:dfb6:3f0f:418b:fc51',
+ header: 'Imelda79',
+ headerMedia: '1/28/2019',
+ content: 'Aliquam odio repudiandae quia qui tenetur accusantium officia.',
+ contentMedia: 'Ullam accusamus facere sed iure omnis fuga.',
+ },
+ {
+ key: 'item-25',
+ media: '0ed1:d677:780f:1af8:689b:a134:f0b3:a715',
+ header: 'Gerson81',
+ headerMedia: '4/29/2019',
+ content: 'Quo quam dolores consequuntur autem nisi unde placeat eum.',
+ contentMedia: 'Harum eos repellat nihil.',
+ },
+ {
+ key: 'item-26',
+ media: 'd473:7c5c:e688:d3e9:d168:34e3:68ab:cb34',
+ header: 'Ladarius7',
+ headerMedia: '12/9/2019',
+ content: 'Doloremque corporis vero explicabo est similique in.',
+ contentMedia: 'Voluptas consequatur voluptates.',
+ },
+ {
+ key: 'item-27',
+ media: '4a2d:dc17:5ef1:d813:f1d7:73a9:d3ae:3b4f',
+ header: 'Dedric68',
+ headerMedia: '2/4/2019',
+ content: 'Pariatur ab aspernatur minus.',
+ contentMedia: 'Asperiores vel aliquam doloribus quam maxime cumque nisi distinctio autem.',
+ },
+ {
+ key: 'item-28',
+ media: '094c:8254:1146:55d1:6d90:b41d:270a:c993',
+ header: 'Noemie_Nicolas50',
+ headerMedia: '12/24/2019',
+ content: 'Ipsam inventore est omnis eveniet.',
+ contentMedia: 'Animi tempore consequatur voluptatem eaque rerum sit ut et.',
+ },
+ {
+ key: 'item-29',
+ media: 'a903:400f:c7ab:8547:4cf4:0cea:ad85:2f84',
+ header: 'Natalie_Kessler12',
+ headerMedia: '9/13/2019',
+ content: 'Officiis aperiam sed et beatae animi.',
+ contentMedia: 'Et impedit numquam.',
+ },
+ {
+ key: 'item-30',
+ media: '14a0:7da0:6561:bf6e:7b72:6afe:175d:6725',
+ header: 'Liza.Tromp92',
+ headerMedia: '2/25/2019',
+ content: 'Occaecati a exercitationem dolor.',
+ contentMedia: 'Tempora eaque quo consectetur.',
+ },
+ {
+ key: 'item-31',
+ media: '3d66:0500:1c4a:b289:eab9:a3d8:fc1d:8036',
+ header: 'Corrine.Ondricka',
+ headerMedia: '9/17/2019',
+ content: 'Quia sint omnis saepe exercitationem et necessitatibus minima.',
+ contentMedia: 'Necessitatibus eum neque totam accusamus iste.',
+ },
+ {
+ key: 'item-32',
+ media: '3ef6:2e67:4d8a:e0fb:c614:0b87:b046:ee02',
+ header: 'Xzavier.Torphy',
+ headerMedia: '8/15/2019',
+ content: 'Sed saepe et.',
+ contentMedia: 'Nihil similique sunt ducimus.',
+ },
+ {
+ key: 'item-33',
+ media: '8d1b:6a57:b845:deeb:41bd:1f88:6f7b:804f',
+ header: 'Odell89',
+ headerMedia: '2/10/2019',
+ content: 'Ut in voluptatem laudantium adipisci deleniti fugiat nam natus.',
+ contentMedia: 'Molestiae id dolorem sit.',
+ },
+ {
+ key: 'item-34',
+ media: 'f48c:d246:d89a:213b:a252:03a3:7b23:c5e1',
+ header: 'Shakira.Wuckert51',
+ headerMedia: '1/19/2020',
+ content: 'Recusandae maiores laborum voluptas excepturi numquam.',
+ contentMedia: 'Alias et earum exercitationem rerum sed.',
+ },
+ {
+ key: 'item-35',
+ media: 'fd13:2bf9:b739:5216:5a5a:1697:ec14:f388',
+ header: 'Stephan30',
+ headerMedia: '8/8/2019',
+ content: 'Laborum numquam dolores deserunt incidunt accusamus ipsam.',
+ contentMedia: 'Iusto voluptas nobis.',
+ },
+ {
+ key: 'item-36',
+ media: '4df1:1c3e:3519:e661:570a:95e4:7d42:2a9f',
+ header: 'Kenton_Vandervort68',
+ headerMedia: '11/19/2019',
+ content: 'Blanditiis nemo possimus autem et sunt exercitationem inventore dolorum.',
+ contentMedia: 'Odio aspernatur at sapiente voluptatem qui reiciendis suscipit non aut.',
+ },
+ {
+ key: 'item-37',
+ media: 'b0fd:820f:8349:bbe6:709d:bb31:dbcd:04e8',
+ header: 'Milton39',
+ headerMedia: '4/16/2019',
+ content: 'Ratione nihil omnis enim aut rerum molestias nulla sit rem.',
+ contentMedia: 'Rem dolorem ab cupiditate consequatur cum incidunt et vero eveniet.',
+ },
+ {
+ key: 'item-38',
+ media: '2e80:c46e:0b5e:e390:0f07:75a7:ef51:f03a',
+ header: 'Domenic.Bernier63',
+ headerMedia: '7/20/2019',
+ content: 'Amet et soluta rerum vero totam non consequatur sit dolorum.',
+ contentMedia: 'Explicabo in voluptas esse et sint.',
+ },
+ {
+ key: 'item-39',
+ media: '7bed:44f3:d339:6da5:17bb:ac34:9d31:3ef5',
+ header: 'Deshawn68',
+ headerMedia: '9/20/2019',
+ content: 'Mollitia ut sapiente ex eaque ducimus sit culpa et corrupti.',
+ contentMedia: 'Amet voluptatem vero et est dicta est.',
+ },
+ {
+ key: 'item-40',
+ media: '5c39:27f2:3d18:a5ed:805d:98c0:eca1:441d',
+ header: 'Eda_Willms',
+ headerMedia: '6/19/2019',
+ content: 'Nihil quasi et voluptatem dolore et.',
+ contentMedia: 'Rerum dolores reiciendis asperiores fuga nostrum vitae et.',
+ },
+ {
+ key: 'item-41',
+ media: 'ae15:839e:803b:0e90:0382:1502:254c:ff49',
+ header: 'Eliza44',
+ headerMedia: '10/18/2019',
+ content: 'Veniam ab ducimus ut repellat.',
+ contentMedia: 'Et voluptatibus error nihil numquam similique.',
+ },
+ {
+ key: 'item-42',
+ media: 'cd53:e6ce:1aff:8b32:3786:fefa:c00e:a801',
+ header: 'Garry.Connelly',
+ headerMedia: '9/25/2019',
+ content: 'Accusamus esse impedit ratione id sit vero veniam odit nemo.',
+ contentMedia: 'Eveniet vel dolor dolores quam animi rerum temporibus.',
+ },
+ {
+ key: 'item-43',
+ media: 'bb43:d3e5:2f02:e726:0edb:5029:9c59:40b0',
+ header: 'Sigrid4',
+ headerMedia: '10/4/2019',
+ content: 'Quis ut est sunt sit sed facilis rerum debitis iusto.',
+ contentMedia: 'Quos assumenda quam ab sed ea assumenda explicabo suscipit vero.',
+ },
+ {
+ key: 'item-44',
+ media: '63c0:e35e:8a1a:a3b2:90ae:bda1:4466:aac7',
+ header: 'Armando.Durgan',
+ headerMedia: '5/12/2019',
+ content: 'Et numquam non hic et occaecati suscipit.',
+ contentMedia: 'Fugiat voluptatum quia amet aut ut ea nam.',
+ },
+ {
+ key: 'item-45',
+ media: '6d4a:3868:1ac0:7edc:3461:fe0e:df54:0d0d',
+ header: 'Theresia.Thiel',
+ headerMedia: '12/30/2019',
+ content: 'Enim animi sit beatae nisi rerum vitae velit maiores quia.',
+ contentMedia: 'Ut quisquam est doloremque voluptatem iure similique ab sit.',
+ },
+ {
+ key: 'item-46',
+ media: 'e494:2079:8bac:cafb:b075:4718:3791:065a',
+ header: 'Yazmin_Kertzmann',
+ headerMedia: '10/27/2019',
+ content: 'Deleniti iste ab est ut nihil soluta aut rem ex.',
+ contentMedia: 'Distinctio fugit fugiat commodi consequatur laudantium aut quod.',
+ },
+ {
+ key: 'item-47',
+ media: 'e8e8:d347:be4c:90ac:aabf:8fc4:fac2:0c75',
+ header: 'Terry.Schuppe42',
+ headerMedia: '8/1/2019',
+ content: 'Repellendus necessitatibus minima fugit autem odio vel accusantium accusamus quas.',
+ contentMedia: 'Nihil aliquam tenetur veritatis atque.',
+ },
+ {
+ key: 'item-48',
+ media: '9b6f:cc70:91dd:2fae:cab3:892f:b12e:84b4',
+ header: 'Gilda_Kuhlman41',
+ headerMedia: '5/22/2019',
+ content: 'Eum aut assumenda quia aperiam culpa aliquid pariatur qui sit.',
+ contentMedia: 'Voluptatem delectus odit.',
+ },
+ {
+ key: 'item-49',
+ media: 'a479:0ac9:94bd:eda7:2105:9b91:003e:ff0f',
+ header: 'Mathew_Bashirian',
+ headerMedia: '11/27/2019',
+ content: 'Iusto rerum voluptas.',
+ contentMedia: 'Ea molestiae quos cupiditate laborum.',
+ },
+ {
+ key: 'item-50',
+ media: '86e6:9dab:6835:7cb3:39aa:009b:e1ee:3d3f',
+ header: 'Roma84',
+ headerMedia: '7/6/2019',
+ content: 'Deleniti sunt doloremque perferendis quod assumenda ipsa.',
+ contentMedia: 'Est commodi illo incidunt provident alias ab aut ut placeat.',
+ },
+ {
+ key: 'item-51',
+ media: 'c9c0:e84c:b2e7:9687:9089:f2d3:3c24:ee17',
+ header: 'Hans_Hayes',
+ headerMedia: '4/29/2019',
+ content: 'Dolores quibusdam nihil et modi earum officia earum incidunt et.',
+ contentMedia: 'Et officiis ea velit tempore enim at commodi dolores.',
+ },
+ {
+ key: 'item-52',
+ media: '8738:61a1:bc19:1958:c7cb:f878:1ddc:a847',
+ header: 'Sam80',
+ headerMedia: '11/14/2019',
+ content: 'Eaque quam distinctio.',
+ contentMedia: 'Vel numquam asperiores ut assumenda veniam est dolorum officiis.',
+ },
+ {
+ key: 'item-53',
+ media: '5295:1bbf:5778:011e:207a:d67b:517a:a02e',
+ header: 'Madaline53',
+ headerMedia: '5/6/2019',
+ content: 'Et error rerum odio ex molestiae.',
+ contentMedia: 'In quidem numquam omnis voluptas nam et ratione.',
+ },
+ {
+ key: 'item-54',
+ media: 'dc6b:7b5a:739b:9ce7:3bf0:0801:f19f:e5ca',
+ header: 'Ardith46',
+ headerMedia: '7/18/2019',
+ content: 'Qui possimus quae hic ea ex voluptatum culpa.',
+ contentMedia: 'Cupiditate sequi vel.',
+ },
+ {
+ key: 'item-55',
+ media: 'da52:440c:e8ce:65aa:2492:6bb7:f34c:fe8d',
+ header: 'Linnea22',
+ headerMedia: '2/22/2019',
+ content: 'Rerum quis in ad ad maiores possimus error optio.',
+ contentMedia: 'Eaque quo explicabo sunt et rerum.',
+ },
+ {
+ key: 'item-56',
+ media: '0a4f:bfa5:8c03:e5f8:75b3:0751:6763:912b',
+ header: 'Mervin.Hickle85',
+ headerMedia: '10/6/2019',
+ content: 'Quo nesciunt culpa aliquam consequuntur.',
+ contentMedia: 'Iure eos perferendis.',
+ },
+ {
+ key: 'item-57',
+ media: 'ae6a:016b:11ca:4c9e:203e:045d:b0e4:12cf',
+ header: 'Abel78',
+ headerMedia: '8/22/2019',
+ content: 'Voluptatem saepe est sit illo nihil enim iure ut quia.',
+ contentMedia: 'Rerum officia ut eveniet aut consequatur.',
+ },
+ {
+ key: 'item-58',
+ media: 'ebcd:0202:ef1b:94f7:7003:dbae:53cb:e035',
+ header: 'Lexi.Pacocha18',
+ headerMedia: '7/11/2019',
+ content: 'Autem qui voluptatem.',
+ contentMedia: 'Quis nostrum repellat maxime.',
+ },
+ {
+ key: 'item-59',
+ media: '0ea2:847a:c88b:a67b:a525:b0d1:5801:3383',
+ header: 'Braeden44',
+ headerMedia: '9/29/2019',
+ content: 'Quae consequatur pariatur et ea.',
+ contentMedia: 'Quisquam odit ipsa quo.',
+ },
+ {
+ key: 'item-60',
+ media: '39d9:38bc:a073:8df5:e24c:8061:a0b2:5797',
+ header: 'Dena44',
+ headerMedia: '11/4/2019',
+ content: 'Odio enim corrupti doloribus neque velit eum quaerat modi.',
+ contentMedia: 'Quo totam dolorum officia nihil corporis earum doloremque voluptas quod.',
+ },
+ {
+ key: 'item-61',
+ media: 'd2d8:af56:3f45:fd15:befb:e30b:73df:c011',
+ header: 'Donato12',
+ headerMedia: '9/7/2019',
+ content: 'Et expedita vero recusandae soluta autem assumenda.',
+ contentMedia: 'Ullam fuga minima laboriosam facilis velit.',
+ },
+ {
+ key: 'item-62',
+ media: 'f6c3:9c9f:9c45:7439:c286:e8ac:91b2:f3b0',
+ header: 'Walker.Heidenreich5',
+ headerMedia: '11/30/2019',
+ content: 'Beatae dolorem eveniet.',
+ contentMedia: 'Et voluptas ullam beatae corporis quaerat et sint quasi.',
+ },
+ {
+ key: 'item-63',
+ media: '3df8:81ab:9f29:d0a1:4360:0b1c:c4ac:9ef6',
+ header: 'Rosalinda_Kuphal75',
+ headerMedia: '5/27/2019',
+ content: 'Atque animi consectetur laborum.',
+ contentMedia: 'Aut quisquam rem.',
+ },
+ {
+ key: 'item-64',
+ media: 'c249:12c6:642c:49be:4a08:d66a:8d0d:1a98',
+ header: 'Bella_Becker46',
+ headerMedia: '12/6/2019',
+ content: 'Similique placeat et possimus voluptates quia non non.',
+ contentMedia: 'Sit et reiciendis ad unde est porro quibusdam.',
+ },
+ {
+ key: 'item-65',
+ media: '6b01:d676:8c9a:7559:5639:493e:d3f8:e529',
+ header: 'Zechariah.Zulauf75',
+ headerMedia: '12/9/2019',
+ content: 'Optio dolorem aut.',
+ contentMedia: 'Blanditiis voluptas quia corrupti laborum.',
+ },
+ {
+ key: 'item-66',
+ media: '61a1:e08f:3b2c:6775:a768:79ef:fbc5:1d2b',
+ header: 'Amina_Reilly',
+ headerMedia: '4/2/2019',
+ content: 'Sed earum fuga pariatur ipsam officia amet.',
+ contentMedia: 'Minus facilis quam.',
+ },
+ {
+ key: 'item-67',
+ media: '32d8:895f:7f5f:f3f8:3f71:ddee:0e80:6da8',
+ header: 'Jackson.Bauch17',
+ headerMedia: '12/31/2019',
+ content: 'Non corrupti quisquam et.',
+ contentMedia: 'Nulla soluta explicabo esse ea in nemo id reiciendis.',
+ },
+ {
+ key: 'item-68',
+ media: 'e51d:a9e9:c018:ab6b:78aa:ce10:d01e:ba61',
+ header: 'Marcelo99',
+ headerMedia: '9/19/2019',
+ content: 'Odit nobis dicta vero impedit expedita voluptates aliquid.',
+ contentMedia: 'Ipsum consequatur accusantium.',
+ },
+ {
+ key: 'item-69',
+ media: 'bca7:7384:2454:e457:f029:5f2b:23b6:e8e9',
+ header: 'Leonora_Wolf35',
+ headerMedia: '10/17/2019',
+ content: 'Beatae ut cum et occaecati excepturi molestiae sequi aut esse.',
+ contentMedia: 'Ipsa laboriosam rerum.',
+ },
+ {
+ key: 'item-70',
+ media: '01a2:9bbd:3a4f:1c02:c4f8:f232:dfa7:452d',
+ header: 'Haleigh.Williamson',
+ headerMedia: '9/23/2019',
+ content: 'Animi fuga in omnis.',
+ contentMedia: 'Eos reiciendis quidem nam corrupti vero atque dolores ut.',
+ },
+ {
+ key: 'item-71',
+ media: '1642:ec3a:415b:a5a6:4873:853f:6052:f601',
+ header: 'Elian_Lang',
+ headerMedia: '11/12/2019',
+ content: 'Autem nesciunt quia magnam qui.',
+ contentMedia: 'Repudiandae atque ipsum perspiciatis possimus tempora deleniti a.',
+ },
+ {
+ key: 'item-72',
+ media: 'c135:5daa:737b:aba0:2241:c19f:42ce:8a91',
+ header: 'Filiberto_Runolfsdottir',
+ headerMedia: '6/16/2019',
+ content: 'Itaque nesciunt sit ducimus error adipisci et est vitae.',
+ contentMedia: 'Doloribus praesentium ut ut qui sint mollitia quasi rem non.',
+ },
+ {
+ key: 'item-73',
+ media: '4e2d:cda6:9c1e:f561:a416:ce2d:4ed4:1807',
+ header: 'Darwin_Price',
+ headerMedia: '1/18/2020',
+ content: 'Sit delectus corrupti omnis et alias reprehenderit praesentium nihil.',
+ contentMedia: 'Aut minus sunt ut.',
+ },
+ {
+ key: 'item-74',
+ media: 'a8db:749a:e801:5d86:929a:f04f:0fe0:7f3c',
+ header: 'River.Shields',
+ headerMedia: '4/12/2019',
+ content: 'Nobis voluptatem ipsum.',
+ contentMedia: 'Deserunt non ex eos deserunt.',
+ },
+ {
+ key: 'item-75',
+ media: '65ca:2e7d:5a73:ab88:3d47:6e95:8ce0:c0be',
+ header: 'Marcelina97',
+ headerMedia: '11/12/2019',
+ content: 'Dolores ex aut.',
+ contentMedia: 'Ad dolorem ullam libero ipsam vel eum id molestiae qui.',
+ },
+ {
+ key: 'item-76',
+ media: '28b5:6f91:ba1a:a099:bd84:1805:3c4e:6d3a',
+ header: 'Hector_Jacobs',
+ headerMedia: '6/19/2019',
+ content: 'Assumenda nostrum aut eum.',
+ contentMedia: 'Accusamus quae rerum molestias reprehenderit ducimus in.',
+ },
+ {
+ key: 'item-77',
+ media: '5a9b:2b1c:0c64:978e:d0d8:a205:f1ba:d022',
+ header: 'Hank.Gutkowski',
+ headerMedia: '11/28/2019',
+ content: 'Nam itaque et.',
+ contentMedia: 'Esse aut ducimus illo sint error doloremque consequatur sunt assumenda.',
+ },
+ {
+ key: 'item-78',
+ media: '22e4:aa44:2ca1:3505:06a8:6eb8:fbfd:738c',
+ header: 'Bianka_Bode',
+ headerMedia: '10/14/2019',
+ content: 'Hic incidunt officia.',
+ contentMedia: 'Vitae sunt nostrum nobis occaecati sed molestiae est impedit.',
+ },
+ {
+ key: 'item-79',
+ media: 'fbee:c95c:d813:44ac:3925:7642:8e1c:7e16',
+ header: 'Neil81',
+ headerMedia: '2/23/2019',
+ content: 'Excepturi et corporis sed autem unde qui doloribus.',
+ contentMedia: 'Distinctio consequatur dignissimos enim.',
+ },
+ {
+ key: 'item-80',
+ media: 'a3f7:3619:438a:b723:1666:403f:864d:e8f1',
+ header: 'Finn.Abshire29',
+ headerMedia: '2/20/2019',
+ content: 'Explicabo magni omnis eum consequatur numquam tenetur.',
+ contentMedia: 'Quas exercitationem delectus quasi sequi ut repellat maiores recusandae aut.',
+ },
+ {
+ key: 'item-81',
+ media: '3a7a:9528:8159:40aa:4e91:1a05:886d:59e6',
+ header: 'Bartholome_Bartoletti44',
+ headerMedia: '8/11/2019',
+ content: 'Adipisci et ducimus et pariatur consequatur quibusdam.',
+ contentMedia: 'Omnis architecto odit illo enim.',
+ },
+ {
+ key: 'item-82',
+ media: 'e5fe:d840:e9ee:467f:a631:a5ee:26ea:f5e4',
+ header: 'Amanda_Eichmann',
+ headerMedia: '10/6/2019',
+ content: 'Libero vitae laborum omnis consectetur beatae aut quas architecto quis.',
+ contentMedia: 'Est iusto tempore quaerat.',
+ },
+ {
+ key: 'item-83',
+ media: '4398:93a6:1de1:94f3:903e:954c:77cd:d013',
+ header: 'Izaiah30',
+ headerMedia: '5/5/2019',
+ content: 'Voluptate provident omnis sequi enim dolorem quod.',
+ contentMedia: 'Assumenda aut officia deleniti velit corporis.',
+ },
+ {
+ key: 'item-84',
+ media: 'defd:93e0:086c:c54c:91f8:3cd3:f906:2399',
+ header: 'Emmanuelle_Hodkiewicz',
+ headerMedia: '10/20/2019',
+ content: 'Quis quasi reiciendis cupiditate necessitatibus deleniti.',
+ contentMedia: 'Nam debitis voluptate labore ea non vel eveniet sint consequuntur.',
+ },
+ {
+ key: 'item-85',
+ media: '5500:c4a6:1062:fb2b:1ec0:7a2f:2ff6:00a6',
+ header: 'Bailee_Metz4',
+ headerMedia: '9/11/2019',
+ content: 'Cumque ut et ut voluptates aliquam dolore occaecati quisquam rem.',
+ contentMedia: 'Consequatur deleniti sed illum cupiditate aliquam.',
+ },
+ {
+ key: 'item-86',
+ media: '28ff:bcb7:ba28:6f30:9193:8d67:fd3a:a95f',
+ header: 'Roel14',
+ headerMedia: '1/9/2020',
+ content: 'Facere omnis itaque facere eligendi iusto corporis.',
+ contentMedia: 'Et autem pariatur iste magnam esse ab.',
+ },
+ {
+ key: 'item-87',
+ media: '793d:32e6:3b90:1e5c:2974:4a05:9d15:a687',
+ header: 'Liliane.Welch',
+ headerMedia: '4/7/2019',
+ content: 'Aut unde nostrum quis corrupti placeat quibusdam.',
+ contentMedia: 'Saepe sit quis ullam.',
+ },
+ {
+ key: 'item-88',
+ media: 'ab9f:016b:aabe:45cd:6457:a5be:1449:9ac3',
+ header: 'Emmet_Fritsch58',
+ headerMedia: '11/5/2019',
+ content: 'Sint culpa et corporis consequatur doloremque placeat fugiat nemo rerum.',
+ contentMedia: 'Deserunt deleniti et consequuntur consequuntur nemo molestias excepturi rerum.',
+ },
+ {
+ key: 'item-89',
+ media: '5426:e139:7c43:360c:e540:305d:0dd3:c3d4',
+ header: 'Alba9',
+ headerMedia: '10/17/2019',
+ content: 'Expedita commodi qui.',
+ contentMedia: 'Quasi non sunt suscipit nesciunt enim ipsam quaerat.',
+ },
+ {
+ key: 'item-90',
+ media: '64fc:571b:ad34:65cb:deab:4ce8:220b:8e67',
+ header: 'Colton_Stroman9',
+ headerMedia: '11/6/2019',
+ content: 'Impedit dolorum ut facilis neque qui.',
+ contentMedia: 'At amet hic.',
+ },
+ {
+ key: 'item-91',
+ media: '7788:9eec:848d:468b:0264:2c4b:dd36:cec7',
+ header: 'Baylee.Leffler9',
+ headerMedia: '7/14/2019',
+ content: 'Aut dolores aperiam.',
+ contentMedia: 'Voluptatem aut aut molestias labore optio deserunt harum quos reprehenderit.',
+ },
+ {
+ key: 'item-92',
+ media: 'b4f5:008d:9fe0:cef5:e1a0:f291:8a2e:50c8',
+ header: 'Emmanuel.Crona',
+ headerMedia: '2/6/2019',
+ content: 'Facere repudiandae rem voluptatem saepe rerum est velit porro.',
+ contentMedia: 'Molestiae aut eum reiciendis et voluptatibus quasi ut quasi consectetur.',
+ },
+ {
+ key: 'item-93',
+ media: '77e2:f427:7f58:5e7e:7e70:c3b0:80cd:4495',
+ header: 'Aurelia.Olson4',
+ headerMedia: '10/17/2019',
+ content: 'Tempore aut facilis laboriosam minus.',
+ contentMedia: 'Id omnis est voluptatem sit non quo quaerat.',
+ },
+ {
+ key: 'item-94',
+ media: '0079:dea3:8261:4801:d2d5:7dea:0dc2:4c2c',
+ header: 'Morris_Morar',
+ headerMedia: '10/27/2019',
+ content: 'Qui explicabo non.',
+ contentMedia: 'Dolore consequatur totam modi et.',
+ },
+ {
+ key: 'item-95',
+ media: '6f85:fda7:38b4:e019:606d:6ed6:56c4:a4bf',
+ header: 'Ray.Berge',
+ headerMedia: '8/8/2019',
+ content: 'Et amet ut rerum debitis consequatur.',
+ contentMedia: 'Omnis voluptatum ut quisquam ut quidem.',
+ },
+ {
+ key: 'item-96',
+ media: 'f498:acb8:7241:3d26:3fa3:a63f:3fd9:da18',
+ header: 'Freida.Keeling99',
+ headerMedia: '7/7/2019',
+ content: 'Et eveniet quae sapiente.',
+ contentMedia: 'Ea optio voluptatem maxime sunt aliquam nesciunt quia dicta sint.',
+ },
+ {
+ key: 'item-97',
+ media: 'ca0a:c574:e92f:fc64:679b:27f6:930e:9379',
+ header: 'Frederic_Schuppe',
+ headerMedia: '2/10/2019',
+ content: 'Aliquam incidunt est aut sit esse.',
+ contentMedia: 'Non voluptatem quae adipisci et voluptatem voluptas velit ut.',
+ },
+ {
+ key: 'item-98',
+ media: 'd909:4f8a:12bc:921d:b8f2:b9d5:b036:e5f9',
+ header: 'Selena.Schultz16',
+ headerMedia: '5/21/2019',
+ content: 'Quam dolorem rerum quo nulla.',
+ contentMedia: 'Laudantium ut quia iusto.',
+ },
+ {
+ key: 'item-99',
+ media: 'd049:44b4:1d31:c7d1:62fd:db1c:2d79:b4c9',
+ header: 'Chloe_Shields0',
+ headerMedia: '2/10/2019',
+ content: 'Optio quas culpa eum unde debitis laudantium et excepturi.',
+ contentMedia: 'Molestias officia est delectus harum inventore dolor.',
+ },
+]
+
+const ListNestedPerf = () => (
+
,
+ },
+ {
+ key: 'list-2',
+ content:
,
+ },
+ {
+ key: 'list-3',
+ content:
,
+ },
+ ]}
+ />
+ ),
+ },
+ {
+ key: 'list-2',
+ content: (
+
,
+ },
+ {
+ key: 'list-2',
+ content:
,
+ },
+ {
+ key: 'list-3',
+ content:
,
+ },
+ ]}
+ />
+ ),
+ },
+ ]}
+ />
+)
+
+ListNestedPerf.iterations = 1
+ListNestedPerf.filename = 'ListNested.perf.tsx'
+
+export default ListNestedPerf
diff --git a/docs/src/examples/components/List/Performance/ListWith60ListItems.perf.tsx b/docs/src/examples/components/List/Performance/ListWith60ListItems.perf.tsx
index 0af619c5e9..da8fbcd8d1 100644
--- a/docs/src/examples/components/List/Performance/ListWith60ListItems.perf.tsx
+++ b/docs/src/examples/components/List/Performance/ListWith60ListItems.perf.tsx
@@ -27,9 +27,9 @@ const items = _.times(60, i => ({
header: `${headers[i % headers.length]}`,
}))
-const ListCommonPerf = () =>
+const ListWith60ListItems = () =>
-ListCommonPerf.iterations = 1
-ListCommonPerf.filename = 'ListCommon.perf.tsx'
+ListWith60ListItems.iterations = 1
+ListWith60ListItems.filename = 'ListWith60ListItems.perf.tsx'
-export default ListCommonPerf
+export default ListWith60ListItems
diff --git a/docs/src/examples/components/List/Performance/index.tsx b/docs/src/examples/components/List/Performance/index.tsx
index a281ff59d4..eff0447d12 100644
--- a/docs/src/examples/components/List/Performance/index.tsx
+++ b/docs/src/examples/components/List/Performance/index.tsx
@@ -15,6 +15,11 @@ const Performance = () => (
description="A list to be benchmarked against a Tree with List Items."
examplePath="components/List/Performance/ListWith60ListItems.perf"
/>
+
)
diff --git a/docs/src/examples/components/List/Types/ListExample.tsx b/docs/src/examples/components/List/Types/ListExample.tsx
index 72685b974d..52e49d1a97 100644
--- a/docs/src/examples/components/List/Types/ListExample.tsx
+++ b/docs/src/examples/components/List/Types/ListExample.tsx
@@ -12,18 +12,21 @@ const ListExampleSelectable = () => {
header="Irving Kuhic"
headerMedia="7:26:56 AM"
content="Program the sensor to the SAS alarm through the haptic SQL card!"
+ index={0}
/>
}
header="Skyler Parks"
headerMedia="11:30:17 PM"
content="Use the online FTP application to input the multi-byte application!"
+ index={1}
/>
}
header="Dante Schneider"
headerMedia="5:22:40 PM"
content="The GB pixel is down, navigate the virtual interface!"
+ index={2}
/>
)
diff --git a/docs/src/examples/components/List/Types/ListExampleNavigable.tsx b/docs/src/examples/components/List/Types/ListExampleNavigable.tsx
index 1ff3071564..8ff504ff42 100644
--- a/docs/src/examples/components/List/Types/ListExampleNavigable.tsx
+++ b/docs/src/examples/components/List/Types/ListExampleNavigable.tsx
@@ -9,6 +9,7 @@ const ListExampleNavigable = () => (
headerMedia="7:26:56 AM"
content="Program the sensor to the SAS alarm through the haptic SQL card!"
navigable
+ index={0}
/>
}
@@ -16,6 +17,7 @@ const ListExampleNavigable = () => (
headerMedia="11:30:17 PM"
content="Use the online FTP application to input the multi-byte application!"
navigable
+ index={1}
/>
}
@@ -23,6 +25,7 @@ const ListExampleNavigable = () => (
headerMedia="5:22:40 PM"
content="The GB pixel is down, navigate the virtual interface!"
navigable
+ index={2}
/>
)
diff --git a/docs/src/examples/components/List/Types/ListExampleSelectable.tsx b/docs/src/examples/components/List/Types/ListExampleSelectable.tsx
index f8d97a0202..28f6db6108 100644
--- a/docs/src/examples/components/List/Types/ListExampleSelectable.tsx
+++ b/docs/src/examples/components/List/Types/ListExampleSelectable.tsx
@@ -7,22 +7,22 @@ const ListExampleSelectable = () => (
media={}
header="Irving Kuhic"
headerMedia="7:26:56 AM"
+ index={0}
content="Program the sensor to the SAS alarm through the haptic SQL card!"
- selectable
/>
}
header="Skyler Parks"
headerMedia="11:30:17 PM"
+ index={1}
content="Use the online FTP application to input the multi-byte application!"
- selectable
/>
}
header="Dante Schneider"
headerMedia="5:22:40 PM"
+ index={2}
content="The GB pixel is down, navigate the virtual interface!"
- selectable
/>
)
diff --git a/docs/src/examples/components/List/Usage/ListExampleMemo.tsx b/docs/src/examples/components/List/Usage/ListExampleMemo.tsx
new file mode 100644
index 0000000000..6cbbd12c63
--- /dev/null
+++ b/docs/src/examples/components/List/Usage/ListExampleMemo.tsx
@@ -0,0 +1,59 @@
+import { useLogKnob } from '@fluentui/docs-components'
+import { List, ListItem } from '@fluentui/react'
+import * as React from 'react'
+
+type MemoItemProps = {
+ children?: string
+ index: number
+ onRender: (index: number) => void
+}
+
+const RenderLogger: React.FC = props => {
+ const { 'data-id': id, onRender, ...rest } = props
+ onRender(id)
+
+ return
+}
+
+const MemoItem = React.memo(props => {
+ const { children, index, onRender } = props
+
+ return (
+
+ )
+})
+
+const ListExampleSelectable = () => {
+ // (!) `handleRender` and `RenderLogger` are used only for logging purposes and are not required
+ // for an actual implementation
+ const handleRender = useLogKnob(
+ 'MemoItem:render',
+ undefined,
+ (id: string, index: number) => `${new Date().toLocaleTimeString()}: ${id}({ id: ${index} })`,
+ )
+
+ return (
+
+
+ This is an item 0
+
+
+ This is an item 1
+
+
+ This is an item 2
+
+
+ This is an item 3
+
+
+ )
+}
+
+export default ListExampleSelectable
diff --git a/docs/src/examples/components/List/Usage/index.tsx b/docs/src/examples/components/List/Usage/index.tsx
new file mode 100644
index 0000000000..cd7447d0fe
--- /dev/null
+++ b/docs/src/examples/components/List/Usage/index.tsx
@@ -0,0 +1,19 @@
+import * as React from 'react'
+import ComponentExample from '../../../../components/ComponentDoc/ComponentExample'
+import ExampleSection from '../../../../components/ComponentDoc/ExampleSection'
+
+const Usage = () => (
+
+
+ List with React.memo()
+ >
+ }
+ description="React.memo() can be used to avoid rerenders."
+ examplePath="components/List/Usage/ListExampleMemo"
+ />
+
+)
+
+export default Usage
diff --git a/docs/src/examples/components/List/Variations/ListExampleTruncate.tsx b/docs/src/examples/components/List/Variations/ListExampleTruncate.tsx
index 2fd2387f22..5046acfb47 100644
--- a/docs/src/examples/components/List/Variations/ListExampleTruncate.tsx
+++ b/docs/src/examples/components/List/Variations/ListExampleTruncate.tsx
@@ -17,6 +17,7 @@ const ListExample = () => {
headerMedia="7:26:56 AM"
content="Program the sensor to the SAS alarm through the haptic SQL card!"
contentMedia="!!"
+ index={0}
/>
}
@@ -24,6 +25,7 @@ const ListExample = () => {
headerMedia="11:30:17 PM"
content="Use the online FTP application to input the multi-byte application!"
contentMedia="!!"
+ index={1}
/>
}
@@ -31,6 +33,7 @@ const ListExample = () => {
headerMedia="5:22:40 PM"
content="The GB pixel is down, navigate the virtual interface!"
contentMedia="!!"
+ index={2}
/>
diff --git a/docs/src/examples/components/List/index.tsx b/docs/src/examples/components/List/index.tsx
index 47ad2ce4a6..fae919b8e2 100644
--- a/docs/src/examples/components/List/index.tsx
+++ b/docs/src/examples/components/List/index.tsx
@@ -5,6 +5,7 @@ import Types from './Types'
import Content from './Content'
import Variations from './Variations'
import Performance from './Performance'
+import Usage from './Usage'
const ListExamples = () => (
<>
@@ -13,6 +14,7 @@ const ListExamples = () => (
+
>
)
diff --git a/packages/react-context-selector/package.json b/packages/react-context-selector/package.json
index 871d2044f8..117605bb4a 100644
--- a/packages/react-context-selector/package.json
+++ b/packages/react-context-selector/package.json
@@ -1,7 +1,7 @@
{
"name": "@fluentui/react-context-selector",
"description": "React useContextSelector & useContextSelectors hooks in userland",
- "version": "0.43.0",
+ "version": "0.44.0",
"author": "Oleksandr Fediashov ",
"bugs": "https://github.com/microsoft/fluent-ui-react/issues",
"dependencies": {
diff --git a/packages/react/package.json b/packages/react/package.json
index 258d52fbb6..c17e5dc8ec 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -10,6 +10,7 @@
"@fluentui/react-bindings": "^0.44.0",
"@fluentui/react-component-event-listener": "^0.44.0",
"@fluentui/react-component-nesting-registry": "^0.44.0",
+ "@fluentui/react-context-selector": "^0.44.0",
"@fluentui/react-component-ref": "^0.44.0",
"@fluentui/react-proptypes": "^0.44.0",
"@fluentui/styles": "^0.44.0",
diff --git a/packages/react/src/components/List/List.tsx b/packages/react/src/components/List/List.tsx
index 10df6c5e41..078c48bb86 100644
--- a/packages/react/src/components/List/List.tsx
+++ b/packages/react/src/components/List/List.tsx
@@ -3,11 +3,10 @@ import {
getElementType,
getUnhandledProps,
useAccessibility,
- useStateManager,
+ useAutoControlled,
useStyles,
useTelemetry,
} from '@fluentui/react-bindings'
-import { createListManager } from '@fluentui/state'
import * as customPropTypes from '@fluentui/react-proptypes'
import * as _ from 'lodash'
import * as PropTypes from 'prop-types'
@@ -32,6 +31,7 @@ import {
rtlTextContainer,
createShorthandFactory,
} from '../../utils'
+import { ListContextProvider, ListContextValue } from './listContext'
import ListItem, { ListItemProps } from './ListItem'
export interface ListProps extends UIComponentProps, ChildrenComponentProps {
@@ -76,16 +76,6 @@ export interface ListProps extends UIComponentProps, ChildrenComponentProps {
wrap?: (children: ReactChildren) => React.ReactNode
}
-// List props that are passed to each individual Item props
-const itemProps = [
- 'debug',
- 'selectable',
- 'navigable',
- 'truncateContent',
- 'truncateHeader',
- 'variables',
-]
-
const List: React.FC> &
FluentComponentStaticProps & {
Item: typeof ListItem
@@ -100,21 +90,22 @@ const List: React.FC> &
children,
className,
debug,
- defaultSelectedIndex,
design,
horizontal,
- navigable,
items,
+ navigable,
selectable,
- selectedIndex,
styles,
+ truncateContent,
+ truncateHeader,
variables,
wrap,
} = props
- const { state, actions } = useStateManager(createListManager, {
- mapPropsToInitialState: () => ({ selectedIndex: defaultSelectedIndex }),
- mapPropsToState: () => ({ selectedIndex }),
+ const [selectedIndex, setSelectedIndex] = useAutoControlled({
+ defaultValue: props.defaultSelectedIndex,
+ value: props.selectedIndex,
+ initialValue: -1,
})
const getA11Props = useAccessibility(accessibility, {
debugName: List.displayName,
@@ -132,42 +123,38 @@ const List: React.FC> &
rtl: context.rtl,
})
+ const latestProps = React.useRef(props)
+ latestProps.current = props
+
const ElementType = getElementType(props)
const unhandledProps = getUnhandledProps(List.handledProps, props)
const hasContent = childrenExist(children) || (items && items.length > 0)
-
- const handleItemOverrides = (predefinedProps: ListItemProps) => ({
- onClick: (e: React.SyntheticEvent, itemProps: ListItemProps) => {
- _.invoke(predefinedProps, 'onClick', e, itemProps)
-
+ const onItemClick = React.useCallback(
+ (e, itemIndex) => {
if (selectable) {
- actions.select(itemProps.index)
- _.invoke(props, 'onSelectedIndexChange', e, {
- ...props,
- ...{ selectedIndex: itemProps.index },
+ setSelectedIndex(itemIndex)
+ _.invoke(latestProps.current, 'onSelectedIndexChange', e, {
+ ...latestProps.current,
+ selectedIndex: itemIndex,
})
}
},
- })
+ [latestProps, setSelectedIndex],
+ )
+ const childProps: ListContextValue = {
+ debug,
+ navigable,
+ onItemClick,
+ selectable,
+ selectedIndex,
+ truncateContent,
+ truncateHeader,
+ variables,
+ }
const renderItems = () =>
- _.map(items, (item, index) => {
- const maybeSelectableItemProps = {} as any
-
- if (selectable) {
- maybeSelectableItemProps.selected = index === state.selectedIndex
- }
-
- return ListItem.create(item, {
- defaultProps: () => ({
- ..._.pick(props, itemProps),
- ...maybeSelectableItemProps,
- index,
- }),
- overrideProps: handleItemOverrides,
- })
- })
+ _.map(items, (item, index) => ListItem.create(item, { defaultProps: () => ({ index }) }))
const element = getA11Props.unstable_wrapWithFocusZone(
> &
...unhandledProps,
})}
>
- {hasContent && wrap(childrenExist(children) ? children : renderItems())}
+
+ {hasContent && wrap(childrenExist(children) ? children : renderItems())}
+
,
)
setEnd()
diff --git a/packages/react/src/components/List/ListItem.tsx b/packages/react/src/components/List/ListItem.tsx
index 6af5e1aed2..496103f29b 100644
--- a/packages/react/src/components/List/ListItem.tsx
+++ b/packages/react/src/components/List/ListItem.tsx
@@ -6,6 +6,7 @@ import {
useStyles,
useTelemetry,
} from '@fluentui/react-bindings'
+import { useContextSelectors } from '@fluentui/react-context-selector'
import cx from 'classnames'
import * as _ from 'lodash'
import * as PropTypes from 'prop-types'
@@ -28,6 +29,7 @@ import {
commonPropTypes,
ContentComponentProps,
} from '../../utils'
+import { ListContext, ListContextSubscribedValue } from './listContext'
export interface ListItemSlotClassNames {
header: string
@@ -98,13 +100,26 @@ const ListItem: React.FC & { index: number }> &
headerMedia,
media,
styles,
- debug,
- navigable,
- selectable,
- selected,
- truncateContent,
- truncateHeader,
- variables,
+ } = props
+
+ const parentProps: ListContextSubscribedValue = useContextSelectors(ListContext, {
+ debug: v => v.debug,
+ navigable: v => v.navigable,
+ selectable: v => v.selectable,
+ truncateContent: v => v.truncateContent,
+ truncateHeader: v => v.truncateHeader,
+ variables: v => v.variables,
+ onItemClick: v => v.onItemClick,
+ selected: v => v.selectedIndex === props.index,
+ })
+ const {
+ debug = parentProps.debug,
+ navigable = parentProps.navigable,
+ selectable = parentProps.selectable,
+ selected = parentProps.selected,
+ truncateContent = parentProps.truncateContent,
+ truncateHeader = parentProps.truncateHeader,
+ variables = parentProps.variables,
} = props
const getA11Props = useAccessibility(accessibility, {
@@ -147,6 +162,7 @@ const ListItem: React.FC & { index: number }> &
const handleClick = (e: React.MouseEvent | React.KeyboardEvent) => {
_.invoke(props, 'onClick', e, props)
+ parentProps.onItemClick(e, props.index)
}
const contentElement = Box.create(content, {
diff --git a/packages/react/src/components/List/listContext.ts b/packages/react/src/components/List/listContext.ts
new file mode 100644
index 0000000000..f1e3ead194
--- /dev/null
+++ b/packages/react/src/components/List/listContext.ts
@@ -0,0 +1,43 @@
+import { createContext } from '@fluentui/react-context-selector'
+import { ComponentVariablesInput } from '@fluentui/styles'
+import * as React from 'react'
+
+export type ListContextValue = {
+ debug: boolean
+ selectable: boolean
+ navigable: boolean
+ truncateContent: boolean
+ truncateHeader: boolean
+ variables: ComponentVariablesInput
+
+ onItemClick: (e: React.KeyboardEvent | React.MouseEvent, itemIndex: number) => void
+ selectedIndex: number
+}
+
+export type ListContextSubscribedValue = Pick<
+ ListContextValue,
+ | 'debug'
+ | 'selectable'
+ | 'navigable'
+ | 'truncateContent'
+ | 'truncateHeader'
+ | 'variables'
+ | 'onItemClick'
+> & { selected: boolean }
+
+export const ListContext = createContext(
+ {
+ debug: false,
+ selectable: false,
+ navigable: false,
+ truncateContent: false,
+ truncateHeader: false,
+ variables: {},
+
+ onItemClick: () => {},
+ selectedIndex: -1,
+ },
+ { strict: false },
+)
+
+export const ListContextProvider = ListContext.Provider
diff --git a/packages/react/test/specs/components/List/List-test.tsx b/packages/react/test/specs/components/List/List-test.tsx
index 98f00b23cd..f00dbe370b 100644
--- a/packages/react/test/specs/components/List/List-test.tsx
+++ b/packages/react/test/specs/components/List/List-test.tsx
@@ -45,34 +45,54 @@ describe('List', () => {
describe('selectedIndex', () => {
it('should not be set by default', () => {
- const listItems = mountWithProvider(
).find('ListItem')
- expect(listItems.everyWhere(item => !item.props().selected)).toBe(true)
+ const wrapper = mountWithProvider(
)
+
+ expect(
+ wrapper.find('li').filterWhere(item => Boolean(item.prop('aria-selected'))),
+ ).toHaveLength(0)
})
it('can be set a default value', () => {
- const listItems = mountWithProvider(
+ const wrapper = mountWithProvider(
,
- ).find('ListItem')
- expect(listItems.first().props().selected).toBe(true)
+ )
+ expect(
+ wrapper
+ .find('li')
+ .at(0)
+ .prop('aria-selected'),
+ ).toBe(true)
})
it('should be set when item is clicked', () => {
const wrapper = mountWithProvider(
,
)
- const listItems = wrapper.find('ListItem')
- expect(listItems.at(0).props().selected).toBe(true)
- listItems
- .at(1)
+ expect(
+ wrapper
+ .find('li')
+ .at(0)
+ .prop('aria-selected'),
+ ).toBe(true)
+
+ wrapper
.find('li')
- .first()
+ .at(1)
.simulate('click')
- const updatedItems = wrapper.find('ListItem')
-
- expect(updatedItems.at(0).props().selected).toBe(false)
- expect(updatedItems.at(1).props().selected).toBe(true)
+ expect(
+ wrapper
+ .find('li')
+ .at(0)
+ .prop('aria-selected'),
+ ).toBe(false)
+ expect(
+ wrapper
+ .find('li')
+ .at(1)
+ .prop('aria-selected'),
+ ).toBe(true)
})
it('calls onClick handler for item if `selectable`', () => {
diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json
index 61bd5687e9..ce400f030e 100644
--- a/packages/react/tsconfig.json
+++ b/packages/react/tsconfig.json
@@ -17,6 +17,7 @@
{ "path": "../react-component-event-listener" },
{ "path": "../react-component-nesting-registry" },
{ "path": "../react-component-ref" },
+ { "path": "../react-context-selector" },
{ "path": "../react-proptypes" }
]
}
diff --git a/packages/state/src/index.ts b/packages/state/src/index.ts
index e90adc3260..a326eb9b85 100644
--- a/packages/state/src/index.ts
+++ b/packages/state/src/index.ts
@@ -1,7 +1,6 @@
export * from './managers/checkboxManager'
export * from './managers/dialogManager'
export * from './managers/dropdownManager'
-export * from './managers/listManager'
export * from './managers/sliderManager'
export { default as createManager } from './createManager'
diff --git a/packages/state/src/managers/listManager.ts b/packages/state/src/managers/listManager.ts
deleted file mode 100644
index 4ff9c73926..0000000000
--- a/packages/state/src/managers/listManager.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import createManager from '../createManager'
-import { Manager, ManagerConfig } from '../types'
-
-export type ListState = {
- selectedIndex?: number
-}
-
-export type ListActions = {
- select: (index: number) => void
-}
-
-export type ListManager = Manager
-
-export const createListManager = (
- config: Partial> = {},
-): ListManager =>
- createManager({
- ...config,
- actions: {
- select: index => () => ({ selectedIndex: index }),
- },
- state: {
- selectedIndex: -1,
- ...config.state,
- },
- })