diff --git a/UNRELEASED.md b/UNRELEASED.md
index 44cd8498a0f..8a1f01ee101 100644
--- a/UNRELEASED.md
+++ b/UNRELEASED.md
@@ -27,6 +27,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
### Documentation
+- Converted `ResourceList`, `ResourcePicker`, and `Select` examples to functional components ([#2133](https://github.com/Shopify/polaris-react/pull/2133))
- Converted `Collapsible`, `ColorPicker`, and `DataTable` examples to functional components ([#2128](https://github.com/Shopify/polaris-react/pull/2128))
- Updated the `withContext` section in the [v3 to v4 migration guide](https://github.com/Shopify/polaris-react/blob/master/documentation/guides/migrating-from-v3-to-v4.md) ([#2124](https://github.com/Shopify/polaris-react/pull/2124))
diff --git a/src/components/ResourceList/README.md b/src/components/ResourceList/README.md
index 77f156347c5..e0c400cd33b 100644
--- a/src/components/ResourceList/README.md
+++ b/src/components/ResourceList/README.md
@@ -89,16 +89,43 @@ A resource list with simple items and no bulk actions, sorting, or filtering.
A resource list with simple items and selection.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- selectedItems: [],
- };
+function ResourceListWithSelectionExample() {
+ const [selectedItems, setSelectedItems] = useState([]);
- handleSelectionChange = (selectedItems) => {
- this.setState({selectedItems});
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ return (
+
+
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -115,41 +142,6 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- return (
-
-
-
- );
}
}
```
@@ -159,16 +151,66 @@ class ResourceListExample extends React.Component {
Allows merchants to select items and perform an action on the selection.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- selectedItems: [],
- };
+function ResourceListWithBulkActionsExample() {
+ const [selectedItems, setSelectedItems] = useState([]);
- handleSelectionChange = (selectedItems) => {
- this.setState({selectedItems});
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ const promotedBulkActions = [
+ {
+ content: 'Edit customers',
+ onAction: () => console.log('Todo: implement bulk edit'),
+ },
+ ];
+
+ const bulkActions = [
+ {
+ content: 'Add tags',
+ onAction: () => console.log('Todo: implement bulk add tags'),
+ },
+ {
+ content: 'Remove tags',
+ onAction: () => console.log('Todo: implement bulk remove tags'),
+ },
+ {
+ content: 'Delete customers',
+ onAction: () => console.log('Todo: implement bulk delete'),
+ },
+ ];
+
+ return (
+
+
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -185,64 +227,6 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- const promotedBulkActions = [
- {
- content: 'Edit customers',
- onAction: () => console.log('Todo: implement bulk edit'),
- },
- ];
-
- const bulkActions = [
- {
- content: 'Add tags',
- onAction: () => console.log('Todo: implement bulk add tags'),
- },
- {
- content: 'Remove tags',
- onAction: () => console.log('Todo: implement bulk remove tags'),
- },
- {
- content: 'Delete customers',
- onAction: () => console.log('Todo: implement bulk delete'),
- },
- ];
-
- return (
-
-
-
- );
}
}
```
@@ -252,16 +236,67 @@ class ResourceListExample extends React.Component {
Notifies merchants that list items are being processed.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- selectedItems: [],
- };
+function ResourceListWithLoadingExample() {
+ const [selectedItems, setSelectedItems] = useState([]);
- handleSelectionChange = (selectedItems) => {
- this.setState({selectedItems});
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ const promotedBulkActions = [
+ {
+ content: 'Edit customers',
+ onAction: () => console.log('Todo: implement bulk edit'),
+ },
+ ];
+
+ const bulkActions = [
+ {
+ content: 'Add tags',
+ onAction: () => console.log('Todo: implement bulk add tags'),
+ },
+ {
+ content: 'Remove tags',
+ onAction: () => console.log('Todo: implement bulk remove tags'),
+ },
+ {
+ content: 'Delete customers',
+ onAction: () => console.log('Todo: implement bulk delete'),
+ },
+ ];
+
+ return (
+
+
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -278,65 +313,6 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- const promotedBulkActions = [
- {
- content: 'Edit customers',
- onAction: () => console.log('Todo: implement bulk edit'),
- },
- ];
-
- const bulkActions = [
- {
- content: 'Add tags',
- onAction: () => console.log('Todo: implement bulk add tags'),
- },
- {
- content: 'Remove tags',
- onAction: () => console.log('Todo: implement bulk remove tags'),
- },
- {
- content: 'Delete customers',
- onAction: () => console.log('Todo: implement bulk delete'),
- },
- ];
-
- return (
-
-
-
- );
}
}
```
@@ -346,16 +322,49 @@ class ResourceListExample extends React.Component {
Allows merchants to change the way the list is sorted by selecting one of several options from a [Select](https://polaris.shopify.com/components/forms/select) control.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- sortValue: 'DATE_MODIFIED_DESC',
- };
+function ResourceListWithSortingExample() {
+ const [sortValue, setSortValue] = useState('DATE_MODIFIED_DESC');
- handleSortChange = (sortValue) => {
- this.setState({sortValue});
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ return (
+
+ {
+ setSortValue(selected);
+ console.log(`Sort option changed to ${selected}.`);
+ }}
+ />
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -372,47 +381,6 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- return (
-
- {
- this.setState({sortValue: selected});
- console.log(`Sort option changed to ${selected}.`);
- }}
- />
-
- );
}
}
```
@@ -422,8 +390,39 @@ class ResourceListExample extends React.Component {
Allows merchants to add an alternate tool in the current sort option location when sort may not be the most relevant action for the current list.
```jsx
-class ResourceListExample extends React.Component {
- renderItem = (item) => {
+function ResourceListWithAlternateToolExample() {
+ const resourceName = {
+ singular: 'Customer',
+ plural: 'Customers',
+ };
+
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ return (
+
+ Email customers}
+ />
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -440,39 +439,6 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'Customer',
- plural: 'Customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- return (
-
- Email customers}
- />
-
- );
}
}
```
@@ -482,13 +448,98 @@ class ResourceListExample extends React.Component {
Allows merchants to narrow the resource list to a subset of the original items.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- taggedWith: 'VIP',
- queryValue: null,
+function ResourceListWithFilteringExample() {
+ const [taggedWith, setTaggedWith] = useState('VIP');
+ const [queryValue, setQueryValue] = useState(null);
+
+ const handleTaggedWithChange = useCallback(
+ (value) => setTaggedWith(value),
+ [],
+ );
+ const handleQueryValueChange = useCallback(
+ (value) => setQueryValue(value),
+ [],
+ );
+ const handleTaggedWithRemove = useCallback(() => setTaggedWith(null), []);
+ const handleQueryValueRemove = useCallback(() => setQueryValue(null), []);
+ const handleClearAll = useCallback(() => {
+ handleTaggedWithRemove();
+ handleQueryValueRemove();
+ }, [handleQueryValueRemove, handleTaggedWithRemove]);
+
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ ];
+
+ const filters = [
+ {
+ key: 'taggedWith',
+ label: 'Tagged with',
+ filter: (
+
+ ),
+ shortcut: true,
+ },
+ ];
+
+ const appliedFilters = !isEmpty(taggedWith)
+ ? [
+ {
+ key: 'taggedWith',
+ label: disambiguateLabel('taggedWith', taggedWith),
+ onRemove: handleTaggedWithRemove,
+ },
+ ]
+ : [];
+
+ const filterControl = (
+
+
+
+
+
+ );
+
+ return (
+
+
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location} = item;
const media = ;
@@ -500,117 +551,23 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const {taggedWith, queryValue} = this.state;
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- ];
-
- const filters = [
- {
- key: 'taggedWith',
- label: 'Tagged with',
- filter: (
-
- ),
- shortcut: true,
- },
- ];
-
- const appliedFilters = Object.keys(this.state)
- .filter((key) => !isEmpty(this.state[key]) && key === 'taggedWith')
- .map((key) => {
- return {
- key,
- label: disambiguateLabel(key, this.state[key]),
- onRemove: this.handleRemove,
- };
- });
-
- const filterControl = (
-
-
-
-
-
- );
-
- return (
-
-
-
- );
}
- handleChange = (key) => (value) => {
- this.setState({[key]: value});
- };
-
- handleRemove = (key) => {
- this.setState({[key]: null});
- };
-
- handleQueryClear = () => {
- this.setState({queryValue: null});
- };
-
- handleClearAll = () => {
- this.setState({
- taggedWith: null,
- queryValue: null,
- });
- };
-}
-
-function disambiguateLabel(key, value) {
- switch (key) {
- case 'taggedWith':
- return `Tagged with ${value}`;
- default:
- return value;
+ function disambiguateLabel(key, value) {
+ switch (key) {
+ case 'taggedWith':
+ return `Tagged with ${value}`;
+ default:
+ return value;
+ }
}
-}
-function isEmpty(value) {
- if (Array.isArray(value)) {
- return value.length === 0;
- } else {
- return value === '' || value == null;
+ function isEmpty(value) {
+ if (Array.isArray(value)) {
+ return value.length === 0;
+ } else {
+ return value === '' || value == null;
+ }
}
}
```
@@ -733,16 +690,91 @@ Use persistent shortcut actions in rare cases when the action cannot be made ava
Allows merchants to select or deselect multiple items at once.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- selectedItems: [],
- };
+function ResourceListExample() {
+ const [selectedItems, setSelectedItems] = useState([]);
- handleSelectionChange = (selectedItems) => {
- this.setState({selectedItems});
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item, _, index) => {
+ const items = [
+ {
+ id: 231,
+ url: 'customers/231',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 246,
+ url: 'customers/246',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ },
+ {
+ id: 276,
+ url: 'customers/276',
+ name: 'Joe Smith',
+ location: 'Arizona, USA',
+ },
+ {
+ id: 349,
+ url: 'customers/349',
+ name: 'Haden Jerado',
+ location: 'Decatur, USA',
+ },
+ {
+ id: 419,
+ url: 'customers/419',
+ name: 'Tom Thommas',
+ location: 'Florida, USA',
+ },
+ {
+ id: 516,
+ url: 'customers/516',
+ name: 'Emily Amrak',
+ location: 'Texas, USA',
+ },
+ ];
+
+ const promotedBulkActions = [
+ {
+ content: 'Edit customers',
+ onAction: () => console.log('Todo: implement bulk edit'),
+ },
+ ];
+
+ const bulkActions = [
+ {
+ content: 'Add tags',
+ onAction: () => console.log('Todo: implement bulk add tags'),
+ },
+ {
+ content: 'Remove tags',
+ onAction: () => console.log('Todo: implement bulk remove tags'),
+ },
+ {
+ content: 'Delete customers',
+ onAction: () => console.log('Todo: implement bulk delete'),
+ },
+ ];
+
+ return (
+
+
+
+ );
+
+ function renderItem(item, _, index) {
const {id, url, name, location} = item;
const media = ;
@@ -760,94 +792,11 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 231,
- url: 'customers/231',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- },
- {
- id: 246,
- url: 'customers/246',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- },
- {
- id: 276,
- url: 'customers/276',
- name: 'Joe Smith',
- location: 'Arizona, USA',
- },
- {
- id: 349,
- url: 'customers/349',
- name: 'Haden Jerado',
- location: 'Decatur, USA',
- },
- {
- id: 419,
- url: 'customers/419',
- name: 'Tom Thommas',
- location: 'Florida, USA',
- },
- {
- id: 516,
- url: 'customers/516',
- name: 'Emily Amrak',
- location: 'Texas, USA',
- },
- ];
-
- const promotedBulkActions = [
- {
- content: 'Edit customers',
- onAction: () => console.log('Todo: implement bulk edit'),
- },
- ];
-
- const bulkActions = [
- {
- content: 'Add tags',
- onAction: () => console.log('Todo: implement bulk add tags'),
- },
- {
- content: 'Remove tags',
- onAction: () => console.log('Todo: implement bulk remove tags'),
- },
- {
- content: 'Delete customers',
- onAction: () => console.log('Todo: implement bulk delete'),
- },
- ];
-
- return (
-
-
-
- );
}
-}
-function resolveItemIds({id}) {
- return id;
+ function resolveItemIds({id}) {
+ return id;
+ }
}
```
@@ -856,15 +805,137 @@ function resolveItemIds({id}) {
Use as a broad example that includes most props available to resource list.
```jsx
-class ResourceListExample extends React.Component {
- state = {
- selectedItems: [],
- sortValue: 'DATE_MODIFIED_DESC',
- taggedWith: 'VIP',
- queryValue: null,
+function ResourceListExample() {
+ const [selectedItems, setSelectedItems] = useState([]);
+ const [sortValue, setSortValue] = useState('DATE_MODIFIED_DESC');
+ const [taggedWith, setTaggedWith] = useState('VIP');
+ const [queryValue, setQueryValue] = useState(null);
+
+ const handleTaggedWithChange = useCallback(
+ (value) => setTaggedWith(value),
+ [],
+ );
+ const handleQueryValueChange = useCallback(
+ (value) => setQueryValue(value),
+ [],
+ );
+ const handleTaggedWithRemove = useCallback(() => setTaggedWith(null), []);
+ const handleQueryValueRemove = useCallback(() => setQueryValue(null), []);
+ const handleClearAll = useCallback(() => {
+ handleTaggedWithRemove();
+ handleQueryValueRemove();
+ }, [handleQueryValueRemove, handleTaggedWithRemove]);
+
+ const resourceName = {
+ singular: 'customer',
+ plural: 'customers',
};
- renderItem = (item) => {
+ const items = [
+ {
+ id: 341,
+ url: 'customers/341',
+ name: 'Mae Jemison',
+ location: 'Decatur, USA',
+ latestOrderUrl: 'orders/1456',
+ },
+ {
+ id: 256,
+ url: 'customers/256',
+ name: 'Ellen Ochoa',
+ location: 'Los Angeles, USA',
+ latestOrderUrl: 'orders/1457',
+ },
+ ];
+
+ const promotedBulkActions = [
+ {
+ content: 'Edit customers',
+ onAction: () => console.log('Todo: implement bulk edit'),
+ },
+ ];
+
+ const bulkActions = [
+ {
+ content: 'Add tags',
+ onAction: () => console.log('Todo: implement bulk add tags'),
+ },
+ {
+ content: 'Remove tags',
+ onAction: () => console.log('Todo: implement bulk remove tags'),
+ },
+ {
+ content: 'Delete customers',
+ onAction: () => console.log('Todo: implement bulk delete'),
+ },
+ ];
+
+ const filters = [
+ {
+ key: 'taggedWith',
+ label: 'Tagged with',
+ filter: (
+
+ ),
+ shortcut: true,
+ },
+ ];
+
+ const appliedFilters = !isEmpty(taggedWith)
+ ? [
+ {
+ key: 'taggedWith',
+ label: disambiguateLabel('taggedWith', taggedWith),
+ onRemove: handleTaggedWithRemove,
+ },
+ ]
+ : [];
+
+ const filterControl = (
+
+
+
+
+
+ );
+
+ return (
+
+ {
+ setSortValue(selected);
+ console.log(`Sort option changed to ${selected}.`);
+ }}
+ filterControl={filterControl}
+ />
+
+ );
+
+ function renderItem(item) {
const {id, url, name, location, latestOrderUrl} = item;
const media = ;
const shortcutActions = latestOrderUrl
@@ -885,158 +956,23 @@ class ResourceListExample extends React.Component {
{location}
);
- };
-
- render() {
- const {taggedWith, queryValue} = this.state;
- const resourceName = {
- singular: 'customer',
- plural: 'customers',
- };
-
- const items = [
- {
- id: 341,
- url: 'customers/341',
- name: 'Mae Jemison',
- location: 'Decatur, USA',
- latestOrderUrl: 'orders/1456',
- },
- {
- id: 256,
- url: 'customers/256',
- name: 'Ellen Ochoa',
- location: 'Los Angeles, USA',
- latestOrderUrl: 'orders/1457',
- },
- ];
-
- const promotedBulkActions = [
- {
- content: 'Edit customers',
- onAction: () => console.log('Todo: implement bulk edit'),
- },
- ];
-
- const bulkActions = [
- {
- content: 'Add tags',
- onAction: () => console.log('Todo: implement bulk add tags'),
- },
- {
- content: 'Remove tags',
- onAction: () => console.log('Todo: implement bulk remove tags'),
- },
- {
- content: 'Delete customers',
- onAction: () => console.log('Todo: implement bulk delete'),
- },
- ];
-
- const filters = [
- {
- key: 'taggedWith',
- label: 'Tagged with',
- filter: (
-
- ),
- shortcut: true,
- },
- ];
-
- const appliedFilters = Object.keys(this.state)
- .filter((key) => !isEmpty(this.state[key]) && key === 'taggedWith')
- .map((key) => {
- return {
- key,
- label: disambiguateLabel(key, this.state[key]),
- onRemove: this.handleRemove,
- };
- });
-
- const filterControl = (
-
-
-
-
-
- );
-
- return (
-
- {
- this.setState({sortValue: selected});
- console.log(`Sort option changed to ${selected}.`);
- }}
- filterControl={filterControl}
- />
-
- );
}
- handleSelectionChange = (selectedItems) => {
- this.setState({selectedItems});
- };
-
- handleChange = (key) => (value) => {
- this.setState({[key]: value});
- };
-
- handleRemove = (key) => {
- this.setState({[key]: null});
- };
-
- handleQueryClear = () => {
- this.setState({queryValue: null});
- };
-
- handleClearAll = () => {
- this.setState({
- taggedWith: null,
- queryValue: null,
- });
- };
-}
-
-function disambiguateLabel(key, value) {
- switch (key) {
- case 'taggedWith':
- return `Tagged with ${value}`;
- default:
- return value;
+ function disambiguateLabel(key, value) {
+ switch (key) {
+ case 'taggedWith':
+ return `Tagged with ${value}`;
+ default:
+ return value;
+ }
}
-}
-function isEmpty(value) {
- if (Array.isArray(value)) {
- return value.length === 0;
- } else {
- return value === '' || value == null;
+ function isEmpty(value) {
+ if (Array.isArray(value)) {
+ return value.length === 0;
+ } else {
+ return value === '' || value == null;
+ }
}
}
```
diff --git a/src/components/ResourcePicker/README.md b/src/components/ResourcePicker/README.md
index 15c0be911ce..1a8239224e2 100644
--- a/src/components/ResourcePicker/README.md
+++ b/src/components/ResourcePicker/README.md
@@ -48,25 +48,28 @@ As of v3.17.0, `ResourcePicker` is deprecated. It will be removed in v5.0 as the
When you ask for products, the `onSelection` callback is called with an object that has a `selection` key, which will have an array of objects detailing the selected products (even if `allowMultiple` is set to `false`).
```jsx
-class EmbeddedAppResourcePickerExample extends React.Component {
- state = {
- resourcePickerOpen: false,
- };
-
- render() {
- return (
-
- {
- console.log('Selected products: ', selection);
- this.setState({resourcePickerOpen: false});
- }}
- onCancel={() => this.setState({resourcePickerOpen: false})}
- />
-
- );
- }
+function EmbeddedAppResourcePickerExample() {
+ const [active, setActive] = useState(false);
+
+ const handleResourcePickerClose = useCallback(() => setActive(false), []);
+
+ const handleSelection = useCallback(
+ ({selection}) => {
+ console.log('Selected products: ', selection);
+ handleResourcePickerClose();
+ },
+ [handleResourcePickerClose],
+ );
+
+ return (
+
+
+
+ );
}
```
diff --git a/src/components/Select/README.md b/src/components/Select/README.md
index f4d88240f9a..67f983eff10 100644
--- a/src/components/Select/README.md
+++ b/src/components/Select/README.md
@@ -99,31 +99,25 @@ Options should:
Presents a classic dropdown menu or equivalent picker as determined by merchants’ browsers.
```jsx
-class SelectExample extends React.Component {
- state = {
- selected: 'today',
- };
-
- handleChange = (newValue) => {
- this.setState({selected: newValue});
- };
-
- render() {
- const options = [
- {label: 'Today', value: 'today'},
- {label: 'Yesterday', value: 'yesterday'},
- {label: 'Last 7 days', value: 'lastWeek'},
- ];
+function SelectExample() {
+ const [selected, setSelected] = useState('today');
- return (
-
- );
- }
+ const handleSelectChange = useCallback((value) => setSelected(value), []);
+
+ const options = [
+ {label: 'Today', value: 'today'},
+ {label: 'Yesterday', value: 'yesterday'},
+ {label: 'Last 7 days', value: 'lastWeek'},
+ ];
+
+ return (
+
+ );
}
```
@@ -152,35 +146,29 @@ The Android menu is similar in behavior to the web dropdown.
Use only for cases where the select must fit on a single line, such as in a toolbar.
```jsx
-class InlineLabelExample extends React.Component {
- state = {
- selected: 'newestUpdate',
- };
-
- handleChange = (newValue) => {
- this.setState({selected: newValue});
- };
-
- render() {
- const options = [
- {label: 'Newest update', value: 'newestUpdate'},
- {label: 'Oldest update', value: 'oldestUpdate'},
- {label: 'Most spent', value: 'mostSpent'},
- {label: 'Most orders', value: 'mostOrders'},
- {label: 'Last name A–Z', value: 'lastNameAlpha'},
- {label: 'Last name Z–A', value: 'lastNameReverseAlpha'},
- ];
-
- return (
-
- );
- }
+function InlineLabelExample() {
+ const [selected, setSelected] = useState('newestUpdate');
+
+ const handleSelectChange = useCallback((value) => setSelected(value), []);
+
+ const options = [
+ {label: 'Newest update', value: 'newestUpdate'},
+ {label: 'Oldest update', value: 'oldestUpdate'},
+ {label: 'Most spent', value: 'mostSpent'},
+ {label: 'Most orders', value: 'mostOrders'},
+ {label: 'Last name A–Z', value: 'lastNameAlpha'},
+ {label: 'Last name Z–A', value: 'lastNameReverseAlpha'},
+ ];
+
+ return (
+
+ );
}
```
@@ -219,26 +207,20 @@ Use for selections that aren’t currently available. The surrounding interface
Use to let merchants know if there’s a problem with their selection. For selects, a selection is typically invalid only when using a placeholder option (“Select”) and no other selection has been made.
```jsx
-class ValidationErrorExample extends React.Component {
- state = {
- value: '',
- };
-
- handleChange = (value) => {
- this.setState({value});
- };
-
- render() {
- return (
-
- );
- }
+function ValidationErrorExample() {
+ const [selected, setSelected] = useState('');
+
+ const handleSelectChange = useCallback((value) => setSelected(value), []);
+
+ return (
+
+ );
}
```
@@ -257,51 +239,44 @@ To render an invalid select and its validation error separately:
- Use an [inline error component](https://polaris.shopify.com/components/forms/inline-error) to describe the invalid select input and set its `fieldID` prop to the same unique identifier used for the text field `id`
```jsx
-class SeparateValidationErrorExample extends React.Component {
- state = {
- weight: '12',
- unit: '',
- };
-
- render() {
- const {weight, unit} = this.state;
- const unitSelectID = 'unit';
- const errorMessage = this.generateErrorMessage();
- const formGroupMarkup = (
-
-
-
-
-
-
-
-
-
- );
-
- return {formGroupMarkup};
- }
-
- handleChange = (field) => (value) => {
- this.setState({[field]: value});
- };
-
- generateErrorMessage = () => {
- const {weight, unit} = this.state;
+function SeparateValidationErrorExample() {
+ const [weight, setWeight] = useState('12');
+ const [unit, setUnit] = useState('');
+
+ const handleWeightChange = useCallback((value) => setWeight(value), []);
+ const handleUnitChange = useCallback((value) => setUnit(value), []);
+
+ const unitSelectID = 'unit';
+ const errorMessage = generateErrorMessage();
+ const formGroupMarkup = (
+
+
+
+
+
+
+
+
+
+ );
+
+ return {formGroupMarkup};
+
+ function generateErrorMessage() {
const weightError =
!weight && unit ? 'The numeric weight of the product ' : '';
const unitError =
@@ -321,7 +296,7 @@ class SeparateValidationErrorExample extends React.Component {
);
- };
+ }
}
```