diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/draft-order-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/draft-order-api.doc.ts index c4f4064ccc..2b1c5d33ee 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/draft-order-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/draft-order-api.doc.ts @@ -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', diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/order-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/order-api.doc.ts index c8512bdbf1..8c00a63e73 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/order-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/order-api.doc.ts @@ -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', + ), + }, ], }, }; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/pinpad-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/pinpad-api.doc.ts index 66d737f77d..cd219b91b7 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/pinpad-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/pinpad-api.doc.ts @@ -28,6 +28,12 @@ const data: ReferenceEntityTemplateSchema = { 'validation', ), }, + { + codeblock: generateJsxCodeBlockForToastApi( + 'Configure PinPad options and handle dismissal', + 'validation-with-options', + ), + }, ], }, }; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/product-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/product-api.doc.ts index bc1f12ef27..2d2dc54e1a 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/product-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/product-api.doc.ts @@ -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', diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/scanner-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/scanner-api.doc.ts index 8cdde2bcb0..b9d9017b60 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/scanner-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/scanner-api.doc.ts @@ -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', + ), + }, ], }, }; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/session-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/session-api.doc.ts index b86092f3dc..cabd845394 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/session-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/session-api.doc.ts @@ -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', + ), + }, ], }, }; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/toast-api.doc.ts b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/toast-api.doc.ts index 13fe422205..403317fae7 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/toast-api.doc.ts +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/apis/toast-api.doc.ts @@ -27,6 +27,12 @@ const data: ReferenceEntityTemplateSchema = { 'show', ), }, + { + codeblock: generateJsxCodeBlockForToastApi( + 'Display a toast notification for a custom duration', + 'show-with-duration', + ), + }, ], }, }; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/draft-order-api/draft-order-details.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/draft-order-api/draft-order-details.jsx new file mode 100644 index 0000000000..1550eca6ea --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/draft-order-api/draft-order-details.jsx @@ -0,0 +1,28 @@ +import {render} from 'preact'; + +export default async () => { + render(, document.body); +}; + +const Extension = () => { + const {id, name, customerId} = shopify.draftOrder; + + return ( + + + + Draft Order ID: {id} + Draft Order Name: {name} + {customerId ? ( + Customer ID: {customerId} + ) : ( + No customer associated with this draft order + )} + + + + ); +}; + + + diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/navigation-api/native-screen.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/navigation-api/native-screen.jsx index c1baf5ca65..a6f744ae6c 100644 --- a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/navigation-api/native-screen.jsx +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/navigation-api/native-screen.jsx @@ -1,4 +1,4 @@ -import { render } from "preact"; +import {render} from 'preact'; export default async () => { render(, document.body); diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/order-api/order-details.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/order-api/order-details.jsx new file mode 100644 index 0000000000..07e9797dd5 --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/order-api/order-details.jsx @@ -0,0 +1,28 @@ +import {render} from 'preact'; + +export default async () => { + render(, document.body); +}; + +const Extension = () => { + const {id, name, customerId} = shopify.order; + + return ( + + + + Order ID: {id} + Order Name: {name} + {customerId ? ( + Customer ID: {customerId} + ) : ( + No customer associated with this order + )} + + + + ); +}; + + + diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/pinpad-api/validation-with-options.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/pinpad-api/validation-with-options.jsx new file mode 100644 index 0000000000..33736f4fbb --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/pinpad-api/validation-with-options.jsx @@ -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(, 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 ( + + + + Authorize with PIN + {statusMessage && {statusMessage}} + + + + ); +} + + diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/product-api/product-variant.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/product-api/product-variant.jsx new file mode 100644 index 0000000000..4fa8b0a86e --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/product-api/product-variant.jsx @@ -0,0 +1,23 @@ +import {render} from 'preact'; + +export default async () => { + render(, document.body); +}; + +const Extension = () => { + const {id, variantId} = shopify.product; + + return ( + + + + Product ID: {id} + Variant ID: {variantId} + + + + ); +}; + + + diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/scanner-api/scanner-data-subscribe.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/scanner-api/scanner-data-subscribe.jsx new file mode 100644 index 0000000000..a2a0b284a8 --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/scanner-api/scanner-data-subscribe.jsx @@ -0,0 +1,63 @@ +import {render} from 'preact'; +import {useState, useEffect} from 'preact/hooks'; + +export default async () => { + render(, 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 ( + + + + + {scanData ? ( + <> + Data: {scanData} + Source: {scanSource} + + ) : ( + Waiting for scan... + )} + + {scanHistory.length > 0 && ( + + {scanHistory.map((scan, index) => ( + + [{scan.timestamp}] {scan.data} ({scan.source}) + + ))} + + )} + + + + ); +}; diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/session-api/current-session.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/session-api/current-session.jsx new file mode 100644 index 0000000000..59f0809347 --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/session-api/current-session.jsx @@ -0,0 +1,36 @@ +import {render} from 'preact'; + +export default async () => { + render(, document.body); +}; + +const Extension = () => { + const session = shopify.session.currentSession; + + return ( + + + + + Shop ID: {session.shopId} + Shop Domain: {session.shopDomain} + Currency: {session.currency} + + + User ID: {session.userId} + Location ID: {session.locationId} + {session.staffMemberId && ( + Staff Member ID: {session.staffMemberId} + )} + + + POS Version: {session.posVersion} + + + + + ); +}; + + + diff --git a/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/toast-api/show-with-duration.jsx b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/toast-api/show-with-duration.jsx new file mode 100644 index 0000000000..d00f4eead1 --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/point-of-sale/reference/examples/toast-api/show-with-duration.jsx @@ -0,0 +1,29 @@ +import {render} from 'preact'; + +export default async () => { + render(, 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 ( + + + + Show Short Toast (2s) + Show Long Toast (8s) + + + + ); +}; + + + diff --git a/packages/ui-extensions/src/surfaces/point-of-sale/api/action-api/action-api.ts b/packages/ui-extensions/src/surfaces/point-of-sale/api/action-api/action-api.ts index 800bb8c319..39bafe47b3 100644 --- a/packages/ui-extensions/src/surfaces/point-of-sale/api/action-api/action-api.ts +++ b/packages/ui-extensions/src/surfaces/point-of-sale/api/action-api/action-api.ts @@ -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; }