@pingux/astro 2.16.1-alpha.1 → 2.17.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/lib/cjs/components/ListView/ListView.js +1 -1
  2. package/lib/cjs/components/ListView/ListView.mdx +4 -1
  3. package/lib/cjs/components/ListView/ListView.stories.js +52 -98
  4. package/lib/cjs/components/ListView/ListViewItem.js +126 -0
  5. package/lib/cjs/components/ListViewItem/ListViewItem.js +81 -100
  6. package/lib/cjs/{experimental → components}/ListViewItem/ListViewItem.mdx +4 -4
  7. package/lib/cjs/{experimental → components}/ListViewItem/ListViewItem.stories.js +32 -37
  8. package/lib/cjs/{experimental → components}/ListViewItem/ListViewItem.test.js +3 -3
  9. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.js +5 -5
  10. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.stories.js +5 -5
  11. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.test.js +2 -2
  12. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemMenu.js +8 -8
  13. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemMenu.stories.js +5 -5
  14. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemMenu.test.js +2 -3
  15. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.js +5 -5
  16. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.stories.js +5 -5
  17. package/lib/cjs/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.test.js +2 -2
  18. package/lib/cjs/experimental/PageHeader/PageHeader.js +14 -14
  19. package/lib/cjs/experimental/PageHeader/PageHeader.stories.js +27 -11
  20. package/lib/cjs/experimental/PageHeader/PageHeader.test.js +14 -5
  21. package/lib/cjs/experimental/PanelHeader/PanelHeader.js +1 -1
  22. package/lib/cjs/experimental/PanelHeader/PanelHeader.stories.js +1 -1
  23. package/lib/cjs/index.d.ts +4 -4
  24. package/lib/cjs/index.js +8 -8
  25. package/lib/cjs/recipes/ListAndPanel.stories.js +195 -267
  26. package/lib/cjs/recipes/MaskedValue.stories.js +8 -1
  27. package/lib/cjs/{experimental/recipes → recipes}/ScrollableListView.stories.js +2 -2
  28. package/lib/cjs/utils/designUtils/figmaLinks.js +3 -0
  29. package/lib/components/ListView/ListView.js +1 -1
  30. package/lib/components/ListView/ListView.mdx +4 -1
  31. package/lib/components/ListView/ListView.stories.js +47 -93
  32. package/lib/components/ListView/ListViewItem.js +113 -0
  33. package/lib/components/ListViewItem/ListViewItem.js +78 -99
  34. package/lib/{experimental → components}/ListViewItem/ListViewItem.mdx +4 -4
  35. package/lib/{experimental → components}/ListViewItem/ListViewItem.stories.js +7 -12
  36. package/lib/{experimental → components}/ListViewItem/ListViewItem.test.js +1 -1
  37. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.js +4 -4
  38. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.stories.js +3 -3
  39. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemEditButton.test.js +1 -1
  40. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemMenu.js +5 -5
  41. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemMenu.stories.js +3 -3
  42. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemMenu.test.js +1 -2
  43. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.js +4 -4
  44. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.stories.js +3 -3
  45. package/lib/{experimental → components}/ListViewItem/controls/ListViewItemSwitchField.test.js +1 -1
  46. package/lib/experimental/PageHeader/PageHeader.js +14 -14
  47. package/lib/experimental/PageHeader/PageHeader.stories.js +25 -10
  48. package/lib/experimental/PageHeader/PageHeader.test.js +14 -5
  49. package/lib/experimental/PanelHeader/PanelHeader.js +1 -1
  50. package/lib/experimental/PanelHeader/PanelHeader.stories.js +1 -1
  51. package/lib/index.js +4 -4
  52. package/lib/recipes/ListAndPanel.stories.js +186 -260
  53. package/lib/recipes/MaskedValue.stories.js +7 -0
  54. package/lib/{experimental/recipes → recipes}/ScrollableListView.stories.js +2 -2
  55. package/lib/utils/designUtils/figmaLinks.js +3 -0
  56. package/package.json +1 -1
  57. package/lib/cjs/components/ListItem/ListItem.stories.js +0 -189
  58. package/lib/cjs/experimental/ListView/ListView.mdx +0 -47
  59. package/lib/cjs/experimental/ListView/ListView.stories.js +0 -742
  60. package/lib/cjs/experimental/ListViewItem/ListViewItem.js +0 -108
  61. package/lib/cjs/experimental/recipes/ListAndPanel.stories.js +0 -359
  62. package/lib/cjs/recipes/RadioButtonsWithLinks.stories.js +0 -133
  63. package/lib/cjs/recipes/ScrollableListView.stories.hidden.js +0 -136
  64. package/lib/components/ListItem/ListItem.stories.js +0 -174
  65. package/lib/experimental/ListView/ListView.mdx +0 -47
  66. package/lib/experimental/ListView/ListView.stories.js +0 -729
  67. package/lib/experimental/ListViewItem/ListViewItem.js +0 -93
  68. package/lib/experimental/recipes/ListAndPanel.stories.js +0 -342
  69. package/lib/recipes/RadioButtonsWithLinks.stories.js +0 -118
  70. package/lib/recipes/ScrollableListView.stories.hidden.js +0 -121
  71. /package/lib/cjs/{experimental → components}/ListViewItem/listViewItemAttributes.js +0 -0
  72. /package/lib/cjs/{experimental/recipes → recipes}/items.js +0 -0
  73. /package/lib/{experimental → components}/ListViewItem/listViewItemAttributes.js +0 -0
  74. /package/lib/{experimental/recipes → recipes}/items.js +0 -0
@@ -1,136 +0,0 @@
1
- "use strict";
2
-
3
- var _typeof = require("@babel/runtime-corejs3/helpers/typeof");
4
- var _WeakMap = require("@babel/runtime-corejs3/core-js-stable/weak-map");
5
- var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
6
- var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor");
7
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
8
- _Object$defineProperty(exports, "__esModule", {
9
- value: true
10
- });
11
- exports["default"] = exports.Default = void 0;
12
- var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
13
- var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));
14
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
15
- var _objectDestructuringEmpty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/objectDestructuringEmpty"));
16
- var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
17
- var _react = _interopRequireWildcard(require("react"));
18
- var _reactStately = require("react-stately");
19
- var _CreateIcon = _interopRequireDefault(require("@pingux/mdi-react/CreateIcon"));
20
- var _FormSelectIcon = _interopRequireDefault(require("@pingux/mdi-react/FormSelectIcon"));
21
- var _MoreVertIcon = _interopRequireDefault(require("@pingux/mdi-react/MoreVertIcon"));
22
- var _index = require("../index");
23
- var _react2 = require("@emotion/react");
24
- function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
26
- var _default = {
27
- title: 'Recipes/Scrollable List View'
28
- };
29
- exports["default"] = _default;
30
- var unfilteredItems = [{
31
- key: 'Aardvark',
32
- name: 'Aardvark',
33
- id: '1'
34
- }, {
35
- key: 'Kangaroo',
36
- name: 'Kangaroo',
37
- id: '2'
38
- }, {
39
- key: 'Snake',
40
- name: 'Snake',
41
- id: '3'
42
- }, {
43
- key: 'Dog',
44
- name: 'Dog',
45
- id: '4'
46
- }, {
47
- key: 'Cat',
48
- name: 'Cat',
49
- id: '5'
50
- }, {
51
- key: 'Mouse',
52
- name: 'Mouse',
53
- id: '6'
54
- }, {
55
- key: 'Jaguar',
56
- name: 'Jaguar',
57
- id: '7'
58
- }, {
59
- key: 'Elephant',
60
- name: 'Elephant',
61
- id: '7'
62
- }];
63
- var Default = function Default(_ref) {
64
- var args = (0, _extends2["default"])({}, ((0, _objectDestructuringEmpty2["default"])(_ref), _ref));
65
- var _useState = (0, _react.useState)(''),
66
- _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
67
- value = _useState2[0],
68
- setValue = _useState2[1];
69
- var _useState3 = (0, _react.useState)(unfilteredItems),
70
- _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
71
- items = _useState4[0],
72
- setItems = _useState4[1];
73
- var filterItems = function filterItems(input) {
74
- var filtered = (0, _filter["default"])(unfilteredItems).call(unfilteredItems, function (obj) {
75
- var _context;
76
- return (0, _includes["default"])(_context = obj.name.toLowerCase()).call(_context, input.toLowerCase());
77
- });
78
- setItems(filtered);
79
- };
80
- var onChangeInput = function onChangeInput(input) {
81
- setValue(input);
82
- filterItems(input);
83
- };
84
- return (0, _react2.jsx)(_index.Box, null, (0, _react2.jsx)(_index.SearchField, {
85
- value: value,
86
- onChange: onChangeInput
87
- }), (0, _react2.jsx)(_index.ScrollBox, {
88
- maxHeight: 450,
89
- hasShadows: true
90
- }, (0, _react2.jsx)(_index.ListView, (0, _extends2["default"])({}, args, {
91
- items: items
92
- }), function (item) {
93
- return (0, _react2.jsx)(_reactStately.Item, {
94
- key: item.name,
95
- textValue: item.name
96
- }, (0, _react2.jsx)(_index.Box, {
97
- isRow: true
98
- }, (0, _react2.jsx)(_index.Box, {
99
- isRow: true,
100
- mr: "auto",
101
- alignSelf: "center"
102
- }, (0, _react2.jsx)(_index.Icon, {
103
- icon: _FormSelectIcon["default"],
104
- mr: "sm",
105
- color: "accent.40",
106
- size: 25,
107
- title: {
108
- name: 'Form Select Icon'
109
- }
110
- }), (0, _react2.jsx)(_index.Text, {
111
- variant: "itemTitle",
112
- alignSelf: "center"
113
- }, item.name)), (0, _react2.jsx)(_index.Box, {
114
- isRow: true,
115
- alignSelf: "center",
116
- gap: "sm"
117
- }, (0, _react2.jsx)(_index.IconButton, {
118
- "aria-label": "create-icon"
119
- }, (0, _react2.jsx)(_index.Icon, {
120
- icon: _CreateIcon["default"],
121
- size: "sm",
122
- title: {
123
- name: 'Create Icon'
124
- }
125
- })), (0, _react2.jsx)(_index.IconButton, {
126
- "aria-label": "create-icon"
127
- }, (0, _react2.jsx)(_index.Icon, {
128
- icon: _MoreVertIcon["default"],
129
- size: "sm",
130
- title: {
131
- name: 'More Vertical Icon'
132
- }
133
- })))));
134
- })));
135
- };
136
- exports.Default = Default;
@@ -1,174 +0,0 @@
1
- import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
2
- import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
3
- import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
4
- import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
5
- import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
6
- import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
7
- import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
8
- import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
9
- import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
10
- import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
11
- import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
12
- function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); enumerableOnly && (symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
13
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var _context, _context2; var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(source), !0)).call(_context, function (key) { _defineProperty(target, key, source[key]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)) : _forEachInstanceProperty(_context2 = ownKeys(Object(source))).call(_context2, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } return target; }
14
- import React, { useState } from 'react';
15
- import AccountIcon from '@pingux/mdi-react/AccountIcon';
16
- import MoreVertIcon from '@pingux/mdi-react/MoreVertIcon';
17
- import { withDesign } from 'storybook-addon-designs';
18
- import DocsLayout from '../../../.storybook/storybookDocsLayout';
19
- import { Box, Icon, IconButton, ListItem, Separator, Text } from '../../index';
20
- import { FIGMA_LINKS } from '../../utils/designUtils/figmaLinks.js';
21
- import { onHoverArgTypes } from '../../utils/docUtils/hoverProps';
22
- import ListItemReadme from './ListItem.mdx';
23
- import { jsx as ___EmotionJSX } from "@emotion/react";
24
- export default {
25
- title: 'Components/ListItem',
26
- component: ListItem,
27
- decorators: [withDesign],
28
- parameters: {
29
- docs: {
30
- page: function page() {
31
- return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(ListItemReadme, null), ___EmotionJSX(DocsLayout, null));
32
- },
33
- source: {
34
- type: 'code'
35
- }
36
- }
37
- },
38
- argTypes: _objectSpread({}, onHoverArgTypes)
39
- };
40
- export var Default = function Default(args) {
41
- return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(Separator, {
42
- margin: 0
43
- }), ___EmotionJSX(ListItem, args, ___EmotionJSX(Box, {
44
- isRow: true,
45
- mr: "auto",
46
- alignSelf: "center"
47
- }, ___EmotionJSX(Icon, {
48
- icon: AccountIcon,
49
- alignSelf: "center",
50
- mr: "sm",
51
- color: "accent.40",
52
- size: 32,
53
- title: {
54
- name: 'Account Icon'
55
- }
56
- }), ___EmotionJSX(Text, {
57
- variant: "itemTitle",
58
- alignSelf: "center"
59
- }, "Fons Vernall")), ___EmotionJSX(Box, {
60
- isRow: true,
61
- alignSelf: "center"
62
- }, ___EmotionJSX(IconButton, {
63
- "aria-label": "filter"
64
- }, ___EmotionJSX(Icon, {
65
- icon: MoreVertIcon,
66
- size: "sm",
67
- color: "neutral.20",
68
- title: {
69
- name: 'More Vertical Icon'
70
- }
71
- })))), ___EmotionJSX(Separator, {
72
- margin: 0
73
- }));
74
- };
75
- Default.parameters = {
76
- design: {
77
- type: 'figma',
78
- url: FIGMA_LINKS.listItem["default"]
79
- }
80
- };
81
- export var WithSubtitle = function WithSubtitle(args) {
82
- return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(Separator, {
83
- margin: 0
84
- }), ___EmotionJSX(ListItem, args, ___EmotionJSX(Box, {
85
- isRow: true,
86
- mr: "auto",
87
- alignSelf: "center"
88
- }, ___EmotionJSX(Icon, {
89
- icon: AccountIcon,
90
- alignSelf: "center",
91
- mr: "sm",
92
- color: "accent.40",
93
- size: 32,
94
- title: {
95
- name: 'Account Icon'
96
- }
97
- }), ___EmotionJSX(Box, null, ___EmotionJSX(Text, {
98
- variant: "itemTitle"
99
- }, "Fons Vernall"), ___EmotionJSX(Text, {
100
- variant: "itemSubtitle",
101
- mt: 1
102
- }, "fvernall0@google.it"))), ___EmotionJSX(Box, {
103
- isRow: true,
104
- alignSelf: "center"
105
- }, ___EmotionJSX(IconButton, {
106
- "aria-label": "filter"
107
- }, ___EmotionJSX(Icon, {
108
- icon: MoreVertIcon,
109
- size: "sm",
110
- color: "neutral.20",
111
- title: {
112
- name: 'More Vertical Icon'
113
- }
114
- })))), ___EmotionJSX(Separator, {
115
- margin: 0
116
- }));
117
- };
118
- export var WithHoverHandlers = function WithHoverHandlers(args) {
119
- var _useState = useState(false),
120
- _useState2 = _slicedToArray(_useState, 2),
121
- isHovered = _useState2[0],
122
- setIsHovered = _useState2[1];
123
- var handleHoverChange = function handleHoverChange() {
124
- setIsHovered(function (previousIsHovered) {
125
- return !previousIsHovered;
126
- });
127
- };
128
- var sx = function sx(shouldTranslate) {
129
- return {
130
- transform: "".concat(shouldTranslate ? 'translate(15px)' : 'translate(0)')
131
- };
132
- };
133
- return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(Separator, {
134
- margin: 0
135
- }), ___EmotionJSX(ListItem, _extends({}, args, {
136
- onHoverEnd: handleHoverChange,
137
- onHoverStart: handleHoverChange
138
- }), ___EmotionJSX(Box, {
139
- isRow: true,
140
- mr: "auto",
141
- alignSelf: "center"
142
- }, ___EmotionJSX(Icon, {
143
- icon: AccountIcon,
144
- alignSelf: "center",
145
- mr: "sm",
146
- color: "accent.40",
147
- size: 32,
148
- title: {
149
- name: 'Account Icon'
150
- }
151
- }), ___EmotionJSX(Box, {
152
- sx: sx(isHovered)
153
- }, ___EmotionJSX(Text, {
154
- variant: "itemTitle"
155
- }, "Fons Vernall"), ___EmotionJSX(Text, {
156
- variant: "itemSubtitle",
157
- mt: 1
158
- }, "fvernall0@google.it"))), ___EmotionJSX(Box, {
159
- isRow: true,
160
- alignSelf: "center"
161
- }, ___EmotionJSX(IconButton, {
162
- size: 26,
163
- "aria-label": "filter"
164
- }, ___EmotionJSX(Icon, {
165
- icon: MoreVertIcon,
166
- size: 20,
167
- color: "neutral.20",
168
- title: {
169
- name: 'More Vertical Icon'
170
- }
171
- })))), ___EmotionJSX(Separator, {
172
- margin: 0
173
- }));
174
- };
@@ -1,47 +0,0 @@
1
- import { Meta } from '@storybook/addon-docs';
2
-
3
- <Meta title="Components/ListView/ListView" />
4
-
5
- # ListView
6
-
7
- ListViews are used to display a list of items. Users can select, view, or edit items in this list.
8
- This virtualized component supports asynchronous data in infinitely scrollable lists.
9
-
10
- This component should:
11
- - Be used to list items that contain a significant amount of information within them.
12
- - Be able to access ListItem information.
13
-
14
- It shouldn’t be used to list items that only have a single piece of information.
15
-
16
- ### Required Components
17
-
18
- This component requires [ListViewItem](./?path=/story/experimental-listviewitem--default).
19
-
20
- ### Accessibility
21
-
22
- This component should adhere to the [WAI-ARIA ListBox](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/) accessibility guidelines.
23
-
24
- #### Keyboard Navigation
25
-
26
- These keys provide additional functionality to the component.
27
-
28
- | Key | Functions |
29
- | ---- | ---- |
30
- | Space or Enter | Selects the item. |
31
- | Tab | Focuses item and follows the page tab sequence. |
32
- | Shift + Tab | Moves focus to the previous focusable component. |
33
- | Arrow keys | Can be used to move the selection in the menu. |
34
- | Home(Fn + Right Arrow Key) Or Control/Command + Home | Shifts the focus to the first row. |
35
- | End(Fn + Left Arrow Key) Or Control/Command + End | Shifts the focus to the last visible row. |
36
-
37
- #### Screen Readers
38
-
39
- This component uses the following attributes to assist screen readers:
40
- - The **`aria-label`** attribute is used to provide an accessible name.
41
- - The **`aria-rowcount`** and **`aria-columncount`** attributes are used to indicate the total number of rows and columns in the grid structure.
42
- - The **`aria-multiselectable`** attribute is used to indicate that users can toggle between items in the grid.
43
- - Each ListViewItem uses the **`aria-rowindex`** attribute, which defines a component's position in the total number of rows.
44
- - Each item also uses the aria-label, **`aria-colindex`** attributes to indicate the component’s column position and aria-selected to indicate the currently selected state.
45
-
46
- #### NOTES:
47
- - See the [ListAndPanel](./?path=/story/experimental-recipes-listandpanel--list-and-panel) and [ScrollableListView](./?path=/story/experimental-recipes-scrollablelistview--scrollable-list-view) recipes for more detailed examples.