Skip to content

Commit c95ad0c

Browse files
authored
Merge pull request #2515 from Shopify/checkout-unstable-release
Unstable Release (checkout)
2 parents 3d913a8 + 76f0c1c commit c95ad0c

File tree

29 files changed

+493
-10
lines changed

29 files changed

+493
-10
lines changed

.changeset/chatty-mugs-appear.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@shopify/ui-extensions-react': minor
3+
'@shopify/ui-extensions': minor
4+
---
5+
6+
New UI component `ClipboardItem`. `activateTarget` and `activateAction` properties added to action components.

packages/ui-extensions-react/src/surfaces/checkout.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ export type {ChoiceProps} from './checkout/components/Choice/Choice';
123123
export {ChoiceList} from './checkout/components/ChoiceList/ChoiceList';
124124
export type {ChoiceListProps} from './checkout/components/ChoiceList/ChoiceList';
125125

126+
export {ClipboardItem} from './checkout/components/ClipboardItem/ClipboardItem';
127+
export type {ClipboardItemProps} from './checkout/components/ClipboardItem/ClipboardItem';
128+
126129
export {DateField} from './checkout/components/DateField/DateField';
127130
export type {DateFieldProps} from './checkout/components/DateField/DateField';
128131

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import {ClipboardItem as BaseClipboardItem} from '@shopify/ui-extensions/checkout';
2+
import {createRemoteReactComponent} from '@remote-ui/react';
3+
import type {ReactPropsFromRemoteComponentType} from '@remote-ui/react';
4+
5+
export type ClipboardItemProps = ReactPropsFromRemoteComponentType<
6+
typeof BaseClipboardItem
7+
>;
8+
9+
export const ClipboardItem = createRemoteReactComponent(BaseClipboardItem);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
reactExtension,
3+
Button,
4+
ClipboardItem,
5+
} from '@shopify/ui-extensions-react/checkout';
6+
7+
export default reactExtension(
8+
'purchase.checkout.block.render',
9+
() => <Extension />,
10+
);
11+
12+
function Extension() {
13+
return (
14+
<>
15+
<Button
16+
activateTarget="discount-code"
17+
activateAction="copy"
18+
>
19+
Copy discount code
20+
</Button>
21+
<ClipboardItem
22+
text="SAVE 25"
23+
id="discount-code"
24+
/>
25+
</>
26+
);
27+
}
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
reactExtension,
3+
Link,
34
QRCode,
5+
TextBlock,
46
} from '@shopify/ui-extensions-react/checkout';
57

68
export default reactExtension(
@@ -9,5 +11,16 @@ export default reactExtension(
911
);
1012

1113
function Extension() {
12-
return <QRCode content="https://shopify.com" />;
14+
return (
15+
<>
16+
<QRCode content="https://shopify.com" />
17+
18+
<TextBlock>
19+
Scan to visit{' '}
20+
<Link to="https://shopify.com">
21+
Shopify.com
22+
</Link>
23+
</TextBlock>
24+
</>
25+
);
1326
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
extension,
3+
Button,
4+
ClipboardItem,
5+
Icon,
6+
InlineStack,
7+
Text,
8+
} from '@shopify/ui-extensions/checkout';
9+
10+
export default extension(
11+
'purchase.checkout.block.render',
12+
(root) => {
13+
const button = root.createComponent(Button, {
14+
activateTarget: 'sample-id',
15+
});
16+
17+
const inlineStack = root.createComponent(
18+
InlineStack,
19+
{},
20+
);
21+
22+
const text = root.createComponent(
23+
Text,
24+
{},
25+
'Copy to clipboard',
26+
);
27+
28+
const icon = root.createComponent(Icon, {
29+
source: 'clipboard',
30+
appearance: 'monochrome',
31+
});
32+
33+
const clipboardItem = root.createComponent(
34+
ClipboardItem,
35+
{
36+
text: 'This text will be copied to the clipboard',
37+
id: 'sample-id',
38+
onCopy: () => {
39+
icon.updateProps({source: 'success'});
40+
setTimeout(() => {
41+
icon.updateProps({
42+
source: 'clipboard',
43+
});
44+
}, 2500);
45+
},
46+
onCopyError: () => {
47+
icon.updateProps({source: 'error'});
48+
setTimeout(() => {
49+
icon.updateProps({
50+
source: 'clipboard',
51+
});
52+
}, 2500);
53+
},
54+
},
55+
);
56+
57+
button.appendChild(inlineStack);
58+
inlineStack.appendChild(text);
59+
inlineStack.appendChild(icon);
60+
root.appendChild(button);
61+
root.appendChild(clipboardItem);
62+
},
63+
);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import {useState} from 'react';
2+
import {
3+
reactExtension,
4+
Button,
5+
ClipboardItem,
6+
Icon,
7+
InlineStack,
8+
Text,
9+
} from '@shopify/ui-extensions-react/checkout';
10+
11+
import type {IconProps} from '@shopify/ui-extensions/checkout';
12+
13+
export default reactExtension(
14+
'purchase.checkout.block.render',
15+
() => <Extension />,
16+
);
17+
18+
function Extension() {
19+
const [iconSource, setIconSource] =
20+
useState<IconProps['source']>('clipboard');
21+
22+
return (
23+
<>
24+
<Button activateTarget="sample-id">
25+
<InlineStack>
26+
<Text>Copy to clipboard</Text>
27+
<Icon
28+
source={iconSource}
29+
appearance="monochrome"
30+
/>
31+
</InlineStack>
32+
</Button>
33+
<ClipboardItem
34+
text="This text will be copied to the clipboard"
35+
id="sample-id"
36+
onCopy={() => {
37+
setIconSource('success');
38+
setTimeout(() => {
39+
setIconSource('clipboard');
40+
}, 2500);
41+
}}
42+
onCopyError={() => {
43+
setIconSource('error');
44+
setTimeout(() => {
45+
setIconSource('clipboard');
46+
}, 2500);
47+
}}
48+
/>
49+
</>
50+
);
51+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
extension,
3+
BlockStack,
4+
Button,
5+
ClipboardItem,
6+
QRCode,
7+
} from '@shopify/ui-extensions/checkout';
8+
9+
export default extension(
10+
'purchase.checkout.block.render',
11+
(root) => {
12+
const bitcoinAddress =
13+
'14qViLJfdGaP4EeHnDyJbEGQysnCpwk3gd';
14+
const qrCodeContent = `bitcoin:${bitcoinAddress}`;
15+
16+
const qrCode = root.createComponent(QRCode, {
17+
content: qrCodeContent,
18+
size: 'fill',
19+
});
20+
21+
const clipboardItem = root.createComponent(
22+
ClipboardItem,
23+
{
24+
text: bitcoinAddress,
25+
id: 'bitcoin-address',
26+
},
27+
);
28+
29+
const button = root.createComponent(
30+
Button,
31+
{
32+
activateTarget: 'bitcoin-address',
33+
},
34+
'Copy Bitcoin address',
35+
);
36+
37+
const blockStack = root.createComponent(
38+
BlockStack,
39+
{
40+
maxInlineSize: 200,
41+
},
42+
);
43+
44+
blockStack.appendChild(qrCode);
45+
blockStack.appendChild(button);
46+
blockStack.appendChild(clipboardItem);
47+
48+
root.appendChild(blockStack);
49+
},
50+
);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {
2+
reactExtension,
3+
BlockStack,
4+
Button,
5+
ClipboardItem,
6+
QRCode,
7+
} from '@shopify/ui-extensions-react/checkout';
8+
9+
export default reactExtension(
10+
'purchase.checkout.block.render',
11+
() => <Extension />,
12+
);
13+
14+
function Extension() {
15+
const bitcoinAddress =
16+
'14qViLJfdGaP4EeHnDyJbEGQysnCpwk3gd';
17+
18+
return (
19+
<BlockStack maxInlineSize={200}>
20+
<QRCode
21+
size="fill"
22+
content={`bitcoin:${bitcoinAddress}`}
23+
/>
24+
<Button activateTarget="bitcoin-address">
25+
Copy Bitcoin address
26+
</Button>
27+
<ClipboardItem
28+
text={bitcoinAddress}
29+
id="bitcoin-address"
30+
/>
31+
</BlockStack>
32+
);
33+
}

packages/ui-extensions/docs/surfaces/checkout/reference/examples/ui-components/qrcode-image.example.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
extension,
33
QRCode,
4+
TextBlock,
5+
Link,
46
} from '@shopify/ui-extensions/checkout';
57

68
export default extension(
@@ -11,6 +13,20 @@ export default extension(
1113
logo: 'https://cdn.shopify.com/YOUR_IMAGE_HERE',
1214
});
1315

16+
const textBlock = root.createComponent(
17+
TextBlock,
18+
null,
19+
[
20+
'Scan to visit ',
21+
root.createComponent(
22+
Link,
23+
{to: 'https://shopify.com'},
24+
'Shopify.com',
25+
),
26+
],
27+
);
28+
1429
root.appendChild(qrCode);
30+
root.appendChild(textBlock);
1531
},
1632
);

0 commit comments

Comments
 (0)