Skip to content

Commit c1b466c

Browse files
Alex-Paladfatbattk
andauthored
Storage API Docs (#2947)
* add StorageAPI documentation. * add changeset. --------- Co-authored-by: Han T. <[email protected]>
1 parent 8856bbe commit c1b466c

File tree

14 files changed

+379
-1
lines changed

14 files changed

+379
-1
lines changed

.changeset/neat-ways-collect.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@shopify/ui-extensions': minor
3+
---
4+
5+
add storageapi documentation
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs';
2+
import {CUSTOM_DATA} from '../helpers/helper.docs';
3+
import {generateCodeBlock} from '../helpers/generateCodeBlock';
4+
5+
const generateCodeBlockForStorageApi = (title: string, fileName: string) =>
6+
generateCodeBlock(title, 'storage-api', fileName);
7+
8+
const data: ReferenceEntityTemplateSchema = {
9+
name: 'Storage API',
10+
description: `The Storage API allows fetching, setting, updating, and clearing an extension's data from the POS local storage.
11+
- If a target (such as \`pos.home.tile.render\`) is disabled or removed, the extension data remains.
12+
- All stored extension data that has not been updated for a month is cleared automatically after that period.
13+
14+
> Note:
15+
> This is part of a POS UI Extensions developer preview. More information to come.`,
16+
isVisualComponent: false,
17+
type: 'APIs',
18+
category: 'APIs',
19+
related: [],
20+
definitions: [CUSTOM_DATA('Storage', 'StorageApi')],
21+
examples: {
22+
description: 'Examples of using the Storage API',
23+
examples: [
24+
{
25+
codeblock: generateCodeBlockForStorageApi(
26+
'Getting a single value from storage',
27+
'get',
28+
),
29+
},
30+
{
31+
codeblock: generateCodeBlockForStorageApi(
32+
'Setting a single value in storage',
33+
'set',
34+
),
35+
},
36+
{
37+
codeblock: generateCodeBlockForStorageApi(
38+
'Deleting a single value from storage',
39+
'delete',
40+
),
41+
},
42+
{
43+
codeblock: generateCodeBlockForStorageApi(
44+
'Clear all entries for an extension from storage',
45+
'clear',
46+
),
47+
},
48+
{
49+
codeblock: generateCodeBlockForStorageApi(
50+
'Retrieve all entries for an extension from storage',
51+
'entries',
52+
),
53+
},
54+
],
55+
exampleGroups: [
56+
{
57+
title: 'Use cases',
58+
examples: [
59+
{
60+
description:
61+
"In this example, we use a Smart Grid Tile to show the contents of the extension's Storage API.",
62+
codeblock: generateCodeBlockForStorageApi(
63+
'Debugging StorageAPI',
64+
'debugging-storage-api',
65+
),
66+
},
67+
],
68+
},
69+
],
70+
},
71+
};
72+
73+
export default data;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale';
2+
3+
export default extension('pos.home.tile.render', (root, api) => {
4+
let itemCount = 0;
5+
6+
const tile = root.createComponent(Tile, {
7+
title: 'Storage app',
8+
subtitle: 'Clear example',
9+
badgeValue: itemCount,
10+
enabled: true,
11+
onPress: async () => {
12+
await api.storage.clear();
13+
api.toast.show('All data cleared');
14+
itemCount = 0;
15+
tile.updateProps({badgeValue: itemCount});
16+
},
17+
});
18+
19+
const initializeData = async () => {
20+
const count = 10;
21+
for (let i = 0; i < count; i++) {
22+
await api.storage.set(`key-${i}`, `value-${i}`);
23+
}
24+
itemCount = count;
25+
tile.updateProps({badgeValue: itemCount});
26+
};
27+
28+
initializeData();
29+
30+
root.append(tile);
31+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, {useState, useEffect} from 'react';
2+
import {
3+
Tile,
4+
reactExtension,
5+
useApi,
6+
} from '@shopify/ui-extensions-react/point-of-sale';
7+
8+
const TileComponent = () => {
9+
const api = useApi<'pos.home.tile.render'>();
10+
const [itemCount, setItemCount] = useState(0);
11+
12+
useEffect(() => {
13+
const initializeData = async () => {
14+
const count = 10;
15+
for (let i = 0; i < count; i++) {
16+
await api.storage.set(`key-${i}`, `value-${i}`);
17+
}
18+
setItemCount(count);
19+
};
20+
21+
initializeData();
22+
}, [api.storage]);
23+
24+
return (
25+
<Tile
26+
title="Storage app"
27+
subtitle="Clear example"
28+
badgeValue={itemCount}
29+
onPress={async () => {
30+
await api.storage.clear();
31+
api.toast.show('All data cleared');
32+
setItemCount(0);
33+
}}
34+
enabled
35+
/>
36+
);
37+
};
38+
39+
export default reactExtension('pos.home.tile.render', () => <TileComponent />);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale';
2+
3+
export default extension('pos.home.tile.render', (root, api) => {
4+
const tile = root.createComponent(Tile, {
5+
title: 'Storage app',
6+
subtitle: 'Delete example',
7+
enabled: true,
8+
onPress: async () => {
9+
await api.storage.set('key', 'A temporary value');
10+
const storedData = await api.storage.get('key');
11+
api.toast.show(`Current value: ${String(storedData)}`);
12+
setTimeout(async () => {
13+
api.storage.delete('key');
14+
const storedData = (await api.storage.get('key')) ?? '';
15+
api.toast.show(`Current value after deletion: ${String(storedData)}`);
16+
}, 2000);
17+
},
18+
});
19+
20+
root.append(tile);
21+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import {
3+
Tile,
4+
reactExtension,
5+
useApi,
6+
} from '@shopify/ui-extensions-react/point-of-sale';
7+
8+
const TileComponent = () => {
9+
const api = useApi<'pos.home.tile.render'>();
10+
return (
11+
<Tile
12+
title="Storage app"
13+
subtitle="Delete example"
14+
onPress={async () => {
15+
await api.storage.set('key', 'A temporary value');
16+
const storedData = await api.storage.get('key');
17+
api.toast.show(`Current value: ${String(storedData)}`);
18+
setTimeout(async () => {
19+
api.storage.delete('key');
20+
const storedData = (await api.storage.get('key')) ?? '';
21+
api.toast.show(`Current value after deletion: ${String(storedData)}`);
22+
}, 2000);
23+
}}
24+
enabled
25+
/>
26+
);
27+
};
28+
29+
export default reactExtension('pos.home.tile.render', () => <TileComponent />);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale';
2+
import type {Storage} from '@shopify/ui-extensions/point-of-sale';
3+
4+
interface ExampleStorage {
5+
attempts: number;
6+
darkMode: boolean;
7+
trackingId: string;
8+
}
9+
10+
export default extension('pos.home.tile.render', (root, api) => {
11+
const storage: Storage<ExampleStorage> = api.storage;
12+
13+
const tile = root.createComponent(Tile, {
14+
title: 'Storage app',
15+
subtitle: 'Entries example',
16+
enabled: true,
17+
onPress: async () => {
18+
await storage.set('attempts', 2);
19+
await storage.set('darkMode', true);
20+
await storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3');
21+
22+
const allEntries = await storage.entries();
23+
const message = allEntries.length
24+
? allEntries.map(([key, value]) => `${key}: ${value}`).join(', ')
25+
: 'Nothing stored';
26+
27+
api.toast.show(message);
28+
},
29+
});
30+
31+
root.append(tile);
32+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import type {Storage} from '@shopify/ui-extensions/point-of-sale';
3+
import {
4+
Tile,
5+
reactExtension,
6+
useApi,
7+
} from '@shopify/ui-extensions-react/point-of-sale';
8+
9+
interface ExampleStorage {
10+
attempts: number;
11+
darkMode: boolean;
12+
trackingId: string;
13+
}
14+
15+
const TileComponent = () => {
16+
const api = useApi<'pos.home.tile.render'>();
17+
const storage: Storage<ExampleStorage> = api.storage;
18+
return (
19+
<Tile
20+
title="Storage app"
21+
subtitle="Entries example"
22+
onPress={async () => {
23+
await storage.set('attempts', 2);
24+
await storage.set('darkMode', true);
25+
await storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3');
26+
27+
const allEntries = await storage.entries();
28+
const message = allEntries.length
29+
? allEntries.map(([key, value]) => `${key}: ${value}`).join(', ')
30+
: 'Nothing stored';
31+
32+
api.toast.show(message);
33+
}}
34+
enabled
35+
/>
36+
);
37+
};
38+
39+
export default reactExtension('pos.home.tile.render', () => <TileComponent />);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale';
2+
3+
export default extension('pos.home.tile.render', (root, api) => {
4+
const tile = root.createComponent(Tile, {
5+
title: 'Storage app',
6+
subtitle: 'Get example',
7+
enabled: true,
8+
onPress: async () => {
9+
const storedData = await api.storage.get('key');
10+
api.toast.show(String(storedData ?? ''));
11+
},
12+
});
13+
14+
root.append(tile);
15+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react';
2+
import {
3+
Tile,
4+
reactExtension,
5+
useApi,
6+
} from '@shopify/ui-extensions-react/point-of-sale';
7+
8+
const TileComponent = () => {
9+
const api = useApi<'pos.home.tile.render'>();
10+
return (
11+
<Tile
12+
title="Storage app"
13+
subtitle="Get example"
14+
onPress={async () => {
15+
const storedData = await api.storage.get('key');
16+
api.toast.show(String(storedData ?? ''));
17+
}}
18+
enabled
19+
/>
20+
);
21+
};
22+
23+
export default reactExtension('pos.home.tile.render', () => <TileComponent />);

0 commit comments

Comments
 (0)