Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ The Draft Order API provides an extension with data about the current draft orde
'id',
),
},
{
codeblock: generateJsxCodeBlockForDraftOrderApi(
"Retrieve a draft order's name, ID, and associated customer ID",
'draft-order-details',
),
},
],
},
category: 'APIs',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ The Order API provides an extension with data about the current order.
'id',
),
},
{
codeblock: generateJsxCodeBlockForOrderApi(
"Retrieve an order's name, ID, and associated customer ID",
'order-details',
),
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const data: ReferenceEntityTemplateSchema = {
'validation',
),
},
{
codeblock: generateJsxCodeBlockForToastApi(
'Configure PinPad options and handle dismissal',
'validation-with-options',
),
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ The Product API provides an extension with data about the current Product.
'id',
),
},
{
codeblock: generateJsxCodeBlockForProductApi(
'Retrieve product and product variant IDs',
'product-variant',
),
},
],
},
category: 'APIs',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@ The Scanner API enables an extension to access scanner data and available scanni
examples: [
{
codeblock: generateCodeBlockForScannerApi(
'Conditional scanner source rendering example',
'Render conditionally based on available scanner sources',
'conditional-scanner-example',
),
},
{
codeblock: generateCodeBlockForScannerApi(
'Subscribe to scanner data events and track scanning history',
'scanner-data-subscribe',
),
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,16 @@ const data: ReferenceEntityTemplateSchema = {
examples: [
{
codeblock: generateJsxCodeBlockForSessionApi(
'Retrieve the current session data',
'Retrieve a session token for backend communication',
'token',
),
},
{
codeblock: generateJsxCodeBlockForSessionApi(
'Access properties associated with the current session',
'current-session',
),
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const data: ReferenceEntityTemplateSchema = {
'show',
),
},
{
codeblock: generateJsxCodeBlockForToastApi(
'Display a toast notification for a custom duration',
'show-with-duration',
),
},
],
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const {id, name, customerId} = shopify.draftOrder;

return (
<s-page heading="Draft Order Details">
<s-scroll-box>
<s-stack direction="block">
<s-text>Draft Order ID: {id}</s-text>
<s-text>Draft Order Name: {name}</s-text>
{customerId ? (
<s-text>Customer ID: {customerId}</s-text>
) : (
<s-text>No customer associated with this draft order</s-text>
)}
</s-stack>
</s-scroll-box>
</s-page>
);
};



Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render } from "preact";
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const {id, name, customerId} = shopify.order;

return (
<s-page heading="Order Details">
<s-scroll-box>
<s-stack direction="block">
<s-text>Order ID: {id}</s-text>
<s-text>Order Name: {name}</s-text>
{customerId ? (
<s-text>Customer ID: {customerId}</s-text>
) : (
<s-text>No customer associated with this order</s-text>
)}
</s-stack>
</s-scroll-box>
</s-page>
);
};



Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {PinPadOptions} from '@shopify/ui-extensions/point-of-sale';
import {render} from 'preact';
import {useState} from 'preact/hooks';

export default async () => {
render(<Extension />, document.body);
};

function Extension() {
const VALID_PIN = '123456';
const [statusMessage, setStatusMessage] = useState('');

const options = {
label: 'Enter your PIN',
title: 'Authorization Required',
masked: true,
minPinLength: 6,
maxPinLength: 6,
onDismissed: (reason) => {
if (reason === 'accept') {
setStatusMessage('PIN validated successfully!');
} else {
setStatusMessage('PIN validation cancelled or failed');
}
},
};

const onShowPinPad = () => {
setStatusMessage('');
shopify.pinPad.showPinPad((pin) => {
if (pin.join('') === VALID_PIN) {
return {result: 'accept'};
} else {
return {
result: 'reject',
errorMessage: 'Incorrect PIN. Please try again.',
};
}
}, options);
};

return (
<s-page heading="PIN Pad with Options">
<s-scroll-box>
<s-stack direction="block">
<s-button onClick={onShowPinPad}>Authorize with PIN</s-button>
{statusMessage && <s-text>{statusMessage}</s-text>}
</s-stack>
</s-scroll-box>
</s-page>
);
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const {id, variantId} = shopify.product;

return (
<s-page heading="Product & Variant">
<s-scroll-box>
<s-stack direction="block">
<s-text>Product ID: {id}</s-text>
<s-text>Variant ID: {variantId}</s-text>
</s-stack>
</s-scroll-box>
</s-page>
);
};



Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {render} from 'preact';
import {useState, useEffect} from 'preact/hooks';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const [scanData, setScanData] = useState('');
const [scanSource, setScanSource] = useState('');
const [scanHistory, setScanHistory] = useState([]);

useEffect(() => {
const unsubscribe = shopify.scanner.scannerData.current.subscribe(
(result) => {
if (result.data) {
setScanData(result.data);
setScanSource(result.source || 'unknown');
setScanHistory((prev) => [
{
data: result.data,
source: result.source,
timestamp: new Date().toLocaleTimeString(),
},
...prev,
]);
}
},
);

return () => {
unsubscribe();
};
}, []);

return (
<s-page heading="Scanner Data">
<s-scroll-box>
<s-stack direction="block">
<s-section heading="Latest Scan">
{scanData ? (
<>
<s-text>Data: {scanData}</s-text>
<s-text>Source: {scanSource}</s-text>
</>
) : (
<s-text>Waiting for scan...</s-text>
)}
</s-section>
{scanHistory.length > 0 && (
<s-section heading="Recent Scans">
{scanHistory.map((scan, index) => (
<s-text key={index}>
[{scan.timestamp}] {scan.data} ({scan.source})
</s-text>
))}
</s-section>
)}
</s-stack>
</s-scroll-box>
</s-page>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const session = shopify.session.currentSession;

return (
<s-page heading="Current Session">
<s-scroll-box>
<s-stack direction="block">
<s-section heading="Shop Information">
<s-text>Shop ID: {session.shopId}</s-text>
<s-text>Shop Domain: {session.shopDomain}</s-text>
<s-text>Currency: {session.currency}</s-text>
</s-section>
<s-section heading="User & Staff">
<s-text>User ID: {session.userId}</s-text>
<s-text>Location ID: {session.locationId}</s-text>
{session.staffMemberId && (
<s-text>Staff Member ID: {session.staffMemberId}</s-text>
)}
</s-section>
<s-section heading="System">
<s-text>POS Version: {session.posVersion}</s-text>
</s-section>
</s-stack>
</s-scroll-box>
</s-page>
);
};



Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {render} from 'preact';

export default async () => {
render(<Extension />, document.body);
};

const Extension = () => {
const showShortToast = () => {
shopify.toast.show('Quick message', {duration: 2000});
};

const showLongToast = () => {
shopify.toast.show('This is a longer notification', {duration: 8000});
};

return (
<s-page heading="Toast with Duration">
<s-scroll-box>
<s-stack direction="block">
<s-button onClick={showShortToast}>Show Short Toast (2s)</s-button>
<s-button onClick={showLongToast}>Show Long Toast (8s)</s-button>
</s-stack>
</s-scroll-box>
</s-page>
);
};



Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export interface ActionApiContent {
/** Presents the `action-overlay.render` extension target on top of present view.
/** Presents the corresponding `.action.render` extension target as a modal overlay.
*
* For example: if we are calling presentModal() from pos.purchase.post.action.menu-item.render,
* it should present pos.purchase.post.action.render.
* it will present pos.purchase.post.action.render.
*/
presentModal(): void;
}
Expand Down