From 5ef687483fb0d7f609572a6a286941fa25bb021c Mon Sep 17 00:00:00 2001 From: Michelle Vinci Date: Tue, 10 Mar 2026 13:17:49 -0700 Subject: [PATCH] Generate shared component docs for customer account UI extensions --- .../Badge/examples/basic-badge.example.tsx | 13 + .../Badge/examples/status-badge.example.tsx | 38 + .../Banner/examples/basic-banner.example.tsx | 18 + .../examples/basic-blocklayout.example.tsx | 23 + .../examples/basic-blockspacer.example.tsx | 24 + .../examples/basic-blockstack.example.tsx | 26 + .../Button/examples/basic-button.example.tsx | 21 + .../Chat/examples/basic-chat.example.tsx | 16 + .../examples/basic-checkbox.example.tsx | 17 + .../Choice/examples/basic-choice.example.tsx | 43 + .../examples/basic-choicelist.example.tsx | 76 + .../examples/basic-clipboarditem.example.tsx | 27 + .../basic-consent-checkbox.example.tsx | 17 + ...t-phone-field-consent-checkbox.example.tsx | 38 + .../basic-consent-phone-field.example.tsx | 18 + ...t-checkbox-consent-phone-field.example.tsx | 38 + .../examples/basic-datefield.example.tsx | 13 + .../examples/basic-datepicker.example.tsx | 13 + .../examples/basic-disclosure.example.tsx | 20 + .../examples/basic-divider.example.tsx | 13 + .../examples/basic-DropZone-react.example.tsx | 13 + .../Form/examples/basic-form.example.tsx | 44 + .../Grid/examples/basic-grid.example.tsx | 39 + .../examples/basic-griditem.example.tsx | 39 + .../examples/basic-heading.example.tsx | 13 + .../examples/basic-headinggroup.example.tsx | 26 + .../Icon/examples/basic-icon.example.tsx | 13 + .../Image/examples/basic-image.example.tsx | 15 + .../examples/basic-inlinelayout.example.tsx | 23 + .../examples/basic-inlinespacer.example.tsx | 33 + .../examples/basic-inlinestack.example.tsx | 29 + .../Link/examples/basic-link.example.tsx | 17 + .../List/examples/basic-list.example.tsx | 20 + .../examples/basic-listitem.example.tsx | 18 + .../Map/examples/basic-map.example.tsx | 21 + .../examples/basic-mapmarker.example.tsx | 28 + .../examples/basic-mappopover.example.tsx | 34 + .../Modal/examples/basic-modal.example.tsx | 52 + .../examples/basic-paymenticon.example.tsx | 13 + .../examples/basic-phonefield.example.tsx | 18 + .../examples/basic-popover.example.tsx | 41 + .../examples/basic-pressable.example.tsx | 27 + .../basic-productthumbnail.example.tsx | 18 + .../examples/basic-progress.example.tsx | 15 + .../QRCode/examples/basic-qrcode.example.tsx | 26 + .../examples/basic-scrollview.example.tsx | 52 + .../Select/examples/basic-select.example.tsx | 44 + .../examples/time-picking-select.example.tsx | 44 + .../Sheet/examples/basic-sheet.example.tsx | 33 + .../examples/basic-skeletonimage.example.tsx | 18 + .../examples/basic-skeletontext.example.tsx | 13 + .../basic-skeletontextblock.example.tsx | 13 + .../examples/basic-spinner.example.tsx | 13 + .../examples/basic-stepper.example.tsx | 13 + .../Switch/examples/basic-switch.example.tsx | 15 + .../Tag/examples/basic-tag.example.tsx | 13 + .../Text/examples/basic-text.example.tsx | 23 + .../examples/basic-textblock.example.tsx | 29 + .../examples/basic-textfield.example.tsx | 13 + .../examples/basic-togglebutton.example.tsx | 25 + .../basic-togglebuttongroup.example.tsx | 72 + .../examples/basic-tooltip.example.tsx | 26 + .../View/examples/basic-view.example.tsx | 17 + .../docs/surfaces/build-doc-shared.mjs | 72 + .../surfaces/customer-account/build-docs.mjs | 288 + .../categories/components.doc.ts | 24 - .../2025-07}/generated_docs_data.json | 14215 +++++++++++++++- .../generated/generated_category_pages.json | 21 - .../generated/generated_static_pages.json | 848 - packages/ui-extensions/package.json | 2 +- .../components/Avatar/Avatar.doc.ts | 3 +- .../components/Badge/Badge.doc.ts | 76 + .../Badge/examples/basic-badge.example.ts | 7 + .../Badge/examples/status-badge.example.ts | 39 + .../components/Banner/Banner.doc.ts | 57 + .../Banner/examples/basic-banner.example.ts | 11 + .../components/BlockLayout/BlockLayout.doc.ts | 57 + .../examples/basic-blocklayout.example.ts | 16 + .../components/BlockSpacer/BlockSpacer.doc.ts | 47 + .../examples/basic-blockspacer.example.ts | 11 + .../components/BlockStack/BlockStack.doc.ts | 67 + .../examples/basic-blockstack.example.ts | 11 + .../components/Button/Button.doc.ts | 64 + .../Button/examples/basic-button.example.ts | 11 + .../components/Card/Card.doc.ts | 3 +- .../components/Chat/Chat.doc.ts | 208 + .../app-bridge-communication.example.js | 18 + .../app-bridge-communication.example.tsx | 34 + .../Chat/examples/app-bridge-css.example.css | 16 + .../examples/app-bridge-resize.example.html | 48 + .../examples/app-bridge-resize.example.tsx | 9 + .../app-bridge-shopify-config.example.js | 2 + .../Chat/examples/basic-chat.example.ts | 13 + .../chat-custom-properties-css.example.css | 9 + .../examples/include-app-bridge.example.html | 3 + .../shopify-extension-toml.example.toml | 5 + .../components/Checkbox/Checkbox.doc.ts | 49 + .../examples/basic-checkbox.example.ts | 11 + .../components/Choice/Choice.doc.ts | 57 + .../Choice/examples/basic-choice.example.ts | 39 + .../components/ChoiceList/ChoiceList.doc.ts | 103 + .../examples/basic-choicelist.example.ts | 81 + .../ClipboardItem/ClipboardItem.doc.ts | 75 + .../examples/basic-clipboarditem.example.ts | 21 + .../ConsentCheckbox/ConsentCheckbox.doc.ts | 72 + .../basic-consent-checkbox.example.ts | 11 + ...nt-phone-field-consent-checkbox.example.ts | 43 + .../ConsentPhoneField.doc.ts | 72 + .../basic-consent-phone-field.example.ts | 10 + ...nt-checkbox-consent-phone-field.example.ts | 43 + .../CustomerAccountAction.doc.ts | 3 +- .../components/DateField/DateField.doc.ts | 49 + .../examples/basic-datefield.example.ts | 9 + .../components/DatePicker/DatePicker.doc.ts | 50 + .../examples/basic-datepicker.example.ts | 9 + .../components/Disclosure/Disclosure.doc.ts | 61 + .../examples/basic-disclosure.example.ts | 19 + .../components/Divider/Divider.doc.ts | 41 + .../Divider/examples/basic-divider.example.ts | 7 + .../components/DropZone/DropZone.doc.ts | 68 + .../examples/basic-DropZone-js.example.ts | 9 + .../components/Form/Form.doc.ts | 50 + .../Form/examples/basic-form.example.ts | 48 + .../components/Grid/Grid.doc.ts | 63 + .../Grid/examples/basic-grid.example.ts | 45 + .../components/GridItem/GridItem.doc.ts | 63 + .../examples/basic-griditem.example.ts | 42 + .../components/Heading/Heading.doc.ts | 69 + .../Heading/examples/basic-heading.example.ts | 7 + .../HeadingGroup/HeadingGroup.doc.ts | 63 + .../examples/basic-headinggroup.example.ts | 20 + .../components/Icon/Icon.doc.ts | 57 + .../Icon/examples/basic-icon.example.ts | 7 + .../components/Image/Image.doc.ts | 49 + .../Image/examples/basic-image.example.ts | 9 + .../components/ImageGroup/ImageGroup.doc.ts | 3 +- .../InlineLayout/InlineLayout.doc.ts | 68 + .../examples/basic-inlinelayout.example.ts | 16 + .../InlineSpacer/InlineSpacer.doc.ts | 41 + .../examples/basic-inlinespacer.example.ts | 20 + .../components/InlineStack/InlineStack.doc.ts | 57 + .../examples/basic-inlinestack.example.ts | 18 + .../components/Link/Link.doc.ts | 64 + .../Link/examples/basic-link.example.ts | 11 + .../components/List/List.doc.ts | 58 + .../List/examples/basic-list.example.ts | 11 + .../components/ListItem/ListItem.doc.ts | 42 + .../examples/basic-listitem.example.ts | 9 + .../components/Map/Map.doc.ts | 54 + .../Map/examples/basic-map.example.ts | 13 + .../components/MapMarker/MapMarker.doc.ts | 62 + .../examples/basic-mapmarker.example.ts | 23 + .../components/MapPopover/MapPopover.doc.ts | 62 + .../examples/basic-mappopover.example.ts | 36 + .../components/Menu/Menu.doc.ts | 3 +- .../components/Modal/Modal.doc.ts | 57 + .../Modal/examples/basic-modal.example.ts | 44 + .../components/Page/Page.doc.ts | 3 +- .../components/PaymentIcon/PaymentIcon.doc.ts | 55 + .../examples/basic-paymenticon.example.ts | 7 + .../components/PhoneField/PhoneField.doc.ts | 41 + .../examples/basic-phonefield.example.ts | 10 + .../components/Popover/Popover.doc.ts | 57 + .../Popover/examples/basic-popover.example.ts | 30 + .../components/Pressable/Pressable.doc.ts | 48 + .../examples/basic-pressable.example.ts | 27 + .../ProductThumbnail/ProductThumbnail.doc.ts | 50 + .../basic-productthumbnail.example.ts | 11 + .../components/Progress/Progress.doc.ts | 89 + .../examples/basic-progress.example.ts | 9 + .../components/QRCode/QRCode.doc.ts | 71 + .../QRCode/examples/basic-qrcode.example.ts | 20 + .../ResourceItem/ResourceItem.doc.ts | 3 +- .../components/ScrollView/ScrollView.doc.ts | 48 + .../examples/basic-scrollview.example.ts | 38 + .../components/Select/Select.doc.ts | 76 + .../Select/examples/basic-select.example.ts | 36 + .../examples/time-picking-select.example.ts | 36 + .../components/Sheet/Sheet.doc.ts | 76 + .../Sheet/examples/basic-sheet.example.ts | 29 + .../SkeletonImage/SkeletonImage.doc.ts | 52 + .../examples/basic-skeletonimage.example.ts | 10 + .../SkeletonText/SkeletonText.doc.ts | 52 + .../examples/basic-skeletontext.example.ts | 7 + .../SkeletonTextBlock.doc.ts | 41 + .../basic-skeletontextblock.example.ts | 7 + .../components/Spinner/Spinner.doc.ts | 57 + .../Spinner/examples/basic-spinner.example.ts | 7 + .../components/Stepper/Stepper.doc.ts | 50 + .../Stepper/examples/basic-stepper.example.ts | 10 + .../components/Switch/Switch.doc.ts | 80 + .../Switch/examples/basic-switch.example.ts | 9 + .../components/Tag/Tag.doc.ts | 41 + .../Tag/examples/basic-tag.example.ts | 7 + .../components/Text/Text.doc.ts | 76 + .../Text/examples/basic-text.example.ts | 14 + .../components/TextBlock/TextBlock.doc.ts | 76 + .../examples/basic-textblock.example.ts | 22 + .../components/TextField/TextField.doc.ts | 49 + .../examples/basic-textfield.example.ts | 9 + .../ToggleButton/ToggleButton.doc.ts | 48 + .../examples/basic-togglebutton.example.ts | 20 + .../ToggleButtonGroup.doc.ts | 80 + .../basic-togglebuttongroup.example.ts | 76 + .../components/Tooltip/Tooltip.doc.ts | 50 + .../Tooltip/examples/basic-tooltip.example.ts | 23 + .../components/View/View.doc.ts | 57 + .../View/examples/basic-view.example.ts | 11 + .../surfaces/customer-account/helper.docs.ts | 232 + .../style/examples/defaultstyle.example.tsx | 9 + .../style/examples/hiding.example.tsx | 8 + .../examples/simplecondition.example.tsx | 9 + .../style/examples/style.example.ts | 18 + .../style/examples/style.example.tsx | 22 + .../customer-account/style/style.doc.ts | 180 + 215 files changed, 20893 insertions(+), 1810 deletions(-) create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/status-badge.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Button/examples/basic-button.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-react.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Form/examples/basic-form.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Image/examples/basic-image.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Link/examples/basic-link.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/List/examples/basic-list.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Map/examples/basic-map.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Select/examples/basic-select.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Text/examples/basic-text.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.tsx create mode 100644 packages/ui-extensions-react/src/surfaces/customer-account/components/View/examples/basic-view.example.tsx create mode 100644 packages/ui-extensions/docs/surfaces/build-doc-shared.mjs create mode 100644 packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs delete mode 100644 packages/ui-extensions/docs/surfaces/customer-account/categories/components.doc.ts rename packages/ui-extensions/docs/surfaces/customer-account/generated/{ => customer_account_ui_extensions/2025-07}/generated_docs_data.json (80%) delete mode 100644 packages/ui-extensions/docs/surfaces/customer-account/generated/generated_category_pages.json delete mode 100644 packages/ui-extensions/docs/surfaces/customer-account/generated/generated_static_pages.json create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Badge/Badge.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/status-badge.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Banner/Banner.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/BlockLayout.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/BlockSpacer.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/BlockStack.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Button/Button.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Button/examples/basic-button.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/Chat.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.js create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-css.example.css create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.html create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-shopify-config.example.js create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/chat-custom-properties-css.example.css create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/include-app-bridge.example.html create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/shopify-extension-toml.example.toml create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/Checkbox.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Choice/Choice.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/ChoiceList.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/ClipboardItem.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/ConsentCheckbox.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/ConsentPhoneField.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DateField/DateField.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/DatePicker.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/Disclosure.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Divider/Divider.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DropZone/DropZone.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-js.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Form/Form.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Form/examples/basic-form.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Grid/Grid.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/GridItem/GridItem.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Heading/Heading.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/HeadingGroup.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Icon/Icon.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Image/Image.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Image/examples/basic-image.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/InlineLayout.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/InlineSpacer.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/InlineStack.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Link/Link.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Link/examples/basic-link.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/List/List.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/List/examples/basic-list.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ListItem/ListItem.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Map/Map.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Map/examples/basic-map.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/MapMarker.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/MapPopover.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Modal/Modal.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/PaymentIcon.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/PhoneField.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Popover/Popover.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Pressable/Pressable.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/ProductThumbnail.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Progress/Progress.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/QRCode/QRCode.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/ScrollView.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Select/Select.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/basic-select.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Sheet/Sheet.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/SkeletonImage.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/SkeletonText.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/SkeletonTextBlock.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Spinner/Spinner.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Stepper/Stepper.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Switch/Switch.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Tag/Tag.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Text/Text.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Text/examples/basic-text.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/TextBlock.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/TextField/TextField.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/ToggleButton.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/ToggleButtonGroup.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/Tooltip.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/View/View.doc.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/components/View/examples/basic-view.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/helper.docs.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/examples/defaultstyle.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/examples/hiding.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/examples/simplecondition.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.ts create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.tsx create mode 100644 packages/ui-extensions/src/surfaces/customer-account/style/style.doc.ts diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.tsx new file mode 100644 index 0000000000..7b6e57335e --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Badge, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return Available; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/status-badge.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/status-badge.example.tsx new file mode 100644 index 0000000000..8bcfc7096b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/status-badge.example.tsx @@ -0,0 +1,38 @@ +import { + reactExtension, + Badge, + BlockStack, + Text, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + + Subscription + + Mini garden seeds + + + + $35.00 monthly + + Paused + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.tsx new file mode 100644 index 0000000000..a5795ddc9b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + Banner, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.tsx new file mode 100644 index 0000000000..52311fb627 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.tsx @@ -0,0 +1,23 @@ +import { + reactExtension, + BlockLayout, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + 60 + + + fill + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.tsx new file mode 100644 index 0000000000..f9b8e49684 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.tsx @@ -0,0 +1,24 @@ +import { + reactExtension, + BlockSpacer, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + <> + + View + + + + View + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.tsx new file mode 100644 index 0000000000..51f41f9866 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.tsx @@ -0,0 +1,26 @@ +import { + reactExtension, + BlockStack, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + View + + + View + + + View + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Button/examples/basic-button.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Button/examples/basic-button.example.tsx new file mode 100644 index 0000000000..0a8658efac --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Button/examples/basic-button.example.tsx @@ -0,0 +1,21 @@ +import { + reactExtension, + Button, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.tsx new file mode 100644 index 0000000000..b405b085a8 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.tsx @@ -0,0 +1,16 @@ +import { + reactExtension, + Chat, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +// This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file. +// Its value will be used as the `src` attribute of the Chat component. + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.tsx new file mode 100644 index 0000000000..7f1b2c46b8 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.tsx @@ -0,0 +1,17 @@ +import { + reactExtension, + Checkbox, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + Save this information for next time + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.tsx new file mode 100644 index 0000000000..be325cace0 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.tsx @@ -0,0 +1,43 @@ +import { + reactExtension, + Choice, + ChoiceList, + InlineStack, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + Ship + + + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + + Gift message + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.tsx new file mode 100644 index 0000000000..85cb557cc6 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.tsx @@ -0,0 +1,76 @@ +import { + reactExtension, + BlockStack, + Choice, + ChoiceList, + Icon, + InlineStack, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + + } + id="ship" + > + Ship + + + } + id="ship-to-pickup-point" + > + Ship to pickup point + + + } + id="pick-up" + > + Pick up in store + + + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + + + Save this information for next time + + + Email me with news and offers + + + Text me with news and offers + + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.tsx new file mode 100644 index 0000000000..84621ed91f --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.tsx @@ -0,0 +1,27 @@ +import { + reactExtension, + Button, + ClipboardItem, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + <> + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.tsx new file mode 100644 index 0000000000..a5796b3766 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.tsx @@ -0,0 +1,17 @@ +import { + reactExtension, + ConsentCheckbox, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + Text me with news and offers + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.tsx new file mode 100644 index 0000000000..21f8a5069c --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.tsx @@ -0,0 +1,38 @@ +import { + reactExtension, + BlockStack, + ConsentCheckbox, + ConsentPhoneField, + InlineStack, + InlineSpacer, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Text me with news and offers + + + + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.tsx new file mode 100644 index 0000000000..eeed9a4eb2 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + ConsentPhoneField, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.tsx new file mode 100644 index 0000000000..21f8a5069c --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.tsx @@ -0,0 +1,38 @@ +import { + reactExtension, + BlockStack, + ConsentCheckbox, + ConsentPhoneField, + InlineStack, + InlineSpacer, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Text me with news and offers + + + + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.tsx new file mode 100644 index 0000000000..4ac09fb934 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + DateField, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.tsx new file mode 100644 index 0000000000..dad6a66cff --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + DatePicker, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.tsx new file mode 100644 index 0000000000..6f341fcfa5 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.tsx @@ -0,0 +1,20 @@ +import { + reactExtension, + Disclosure, + Button, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Content + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.tsx new file mode 100644 index 0000000000..d530a1bed2 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Divider, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-react.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-react.example.tsx new file mode 100644 index 0000000000..e781bfb2d2 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-react.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + DropZone, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Form/examples/basic-form.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Form/examples/basic-form.example.tsx new file mode 100644 index 0000000000..fd0e667d3f --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Form/examples/basic-form.example.tsx @@ -0,0 +1,44 @@ +import { + reactExtension, + BlockSpacer, + Button, + Form, + Grid, + GridItem, + TextField, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( +
+ console.log('onSubmit event') + } + > + + + + + + + + + + + + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.tsx new file mode 100644 index 0000000000..9a28f21de5 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.tsx @@ -0,0 +1,39 @@ +import { + reactExtension, + Grid, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + 20% / 300 + + + fill / 300 + + + auto / 300 + + + 20% / auto + + + fill / auto + + + auto / auto + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.tsx new file mode 100644 index 0000000000..0f8f5762e2 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.tsx @@ -0,0 +1,39 @@ +import { + reactExtension, + Grid, + GridItem, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + 20% / 300 + + + fill / 300 + + + auto / 300 + + + + 20% + fill / auto + + + + auto / auto + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.tsx new file mode 100644 index 0000000000..302fe93755 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Heading, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return Store name; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.tsx new file mode 100644 index 0000000000..a79f759a51 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.tsx @@ -0,0 +1,26 @@ +import { + reactExtension, + HeadingGroup, + Heading, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + <> + Heading <h1> + + + Heading <h2> + + + Heading <h3> + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.tsx new file mode 100644 index 0000000000..68685c5f79 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Icon, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Image/examples/basic-image.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Image/examples/basic-image.example.tsx new file mode 100644 index 0000000000..12798cb2f1 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Image/examples/basic-image.example.tsx @@ -0,0 +1,15 @@ +import { + reactExtension, + Image, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.tsx new file mode 100644 index 0000000000..c3dcda016b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.tsx @@ -0,0 +1,23 @@ +import { + reactExtension, + InlineLayout, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + 20% + + + fill + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.tsx new file mode 100644 index 0000000000..84e54dd4e0 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.tsx @@ -0,0 +1,33 @@ +import { + reactExtension, + InlineSpacer, + InlineStack, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + View + + + + View + + + + View + + + + View + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.tsx new file mode 100644 index 0000000000..702a053d75 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.tsx @@ -0,0 +1,29 @@ +import { + reactExtension, + InlineStack, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + View + + + View + + + View + + + View + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Link/examples/basic-link.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Link/examples/basic-link.example.tsx new file mode 100644 index 0000000000..3e2504ce52 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Link/examples/basic-link.example.tsx @@ -0,0 +1,17 @@ +import { + reactExtension, + Link, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + Sustainability fund + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/List/examples/basic-list.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/List/examples/basic-list.example.tsx new file mode 100644 index 0000000000..f6a3681fbf --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/List/examples/basic-list.example.tsx @@ -0,0 +1,20 @@ +import { + reactExtension, + List, + ListItem, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + 100% organic cotton + Made in Canada + Machine washable + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.tsx new file mode 100644 index 0000000000..56e18f61f6 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + List, + ListItem, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + 100% organic cotton + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Map/examples/basic-map.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Map/examples/basic-map.example.tsx new file mode 100644 index 0000000000..e7bb2cc93d --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Map/examples/basic-map.example.tsx @@ -0,0 +1,21 @@ +import { + reactExtension, + Map, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.tsx new file mode 100644 index 0000000000..55943f749f --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.tsx @@ -0,0 +1,28 @@ +import { + reactExtension, + Map, + MapMarker, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.tsx new file mode 100644 index 0000000000..27562f8f85 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.tsx @@ -0,0 +1,34 @@ +import { + reactExtension, + Map, + MapMarker, + MapPopover, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Blue Mountains National Park store + + } + /> + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.tsx new file mode 100644 index 0000000000..06cdbf0148 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.tsx @@ -0,0 +1,52 @@ +import { + reactExtension, + useApi, + Button, + Link, + Modal, + TextBlock, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + const {ui} = useApi(); + + return ( + + + We have a 30-day return policy, which + means you have 30 days after receiving + your item to request a return. + + + To be eligible for a return, your item + must be in the same condition that you + received it, unworn or unused, with + tags, and in its original packaging. + You’ll also need the receipt or proof + of purchase. + + + + } + > + Return policy + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.tsx new file mode 100644 index 0000000000..84f3a83815 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + PaymentIcon, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.tsx new file mode 100644 index 0000000000..091603bc7b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + PhoneField, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.tsx new file mode 100644 index 0000000000..1f77beca94 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.tsx @@ -0,0 +1,41 @@ +import { + reactExtension, + Pressable, + Popover, + View, + TextBlock, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + + A thoughtful way to pay + + Tap don’t type + + Shop Pay remembers your important + details, so you can fill carts, not + forms. And everything is encrypted + so you can speed safely through + checkout. + + + + } + > + More info + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.tsx new file mode 100644 index 0000000000..0f4ea8b827 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.tsx @@ -0,0 +1,27 @@ +import { + reactExtension, + Icon, + InlineLayout, + Pressable, + Text, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Details + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.tsx new file mode 100644 index 0000000000..76e714261c --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + ProductThumbnail, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.tsx new file mode 100644 index 0000000000..1f70769795 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.tsx @@ -0,0 +1,15 @@ +import { + reactExtension, + Progress, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.tsx new file mode 100644 index 0000000000..8ffc4ca350 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.tsx @@ -0,0 +1,26 @@ +import { + reactExtension, + Link, + QRCode, + TextBlock, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + <> + + + + Scan to visit{' '} + + Shopify.com + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.tsx new file mode 100644 index 0000000000..4b4387f822 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.tsx @@ -0,0 +1,52 @@ +import { + reactExtension, + ScrollView, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + View + + + View + + + View + + + View + + + View + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Select/examples/basic-select.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Select/examples/basic-select.example.tsx new file mode 100644 index 0000000000..f6e97cfcaa --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Select/examples/basic-select.example.tsx @@ -0,0 +1,44 @@ +import { + reactExtension, + Select, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.tsx new file mode 100644 index 0000000000..f7b6414b9e --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.tsx @@ -0,0 +1,33 @@ +import { + reactExtension, + Link, + Sheet, + TextBlock, +} from '@shopify/ui-extensions-react/customer-account'; + +// This component requires access to Customer Privacy API to be rendered. + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + Basic Sheet Content + + + } + > + Open sheet + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.tsx new file mode 100644 index 0000000000..5734f9e61c --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.tsx @@ -0,0 +1,18 @@ +import { + reactExtension, + SkeletonImage, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.tsx new file mode 100644 index 0000000000..d1a738aef7 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + SkeletonText, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.tsx new file mode 100644 index 0000000000..51ed9625c2 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + SkeletonTextBlock, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.tsx new file mode 100644 index 0000000000..e373970af7 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Spinner, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.tsx new file mode 100644 index 0000000000..51b42d446b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Stepper, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.tsx new file mode 100644 index 0000000000..26218780fb --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.tsx @@ -0,0 +1,15 @@ +import { + reactExtension, + Switch, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.tsx new file mode 100644 index 0000000000..d827ac139b --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + Tag, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return SPRING; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Text/examples/basic-text.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Text/examples/basic-text.example.tsx new file mode 100644 index 0000000000..493039f444 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Text/examples/basic-text.example.tsx @@ -0,0 +1,23 @@ +import { + reactExtension, + Text, + BlockStack, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + Total + Total + Total + Total + Total + Total + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.tsx new file mode 100644 index 0000000000..5d55316e2d --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.tsx @@ -0,0 +1,29 @@ +import { + reactExtension, + TextBlock, + BlockStack, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + + We have a 30-day return policy, which + means you have 30 days after receiving + your item to request a return. + + + To be eligible for a return, your item + must be in the same condition that you + received it, unworn or unused, with tags, + and in its original packaging. You’ll also + need the receipt or proof of purchase. + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.tsx new file mode 100644 index 0000000000..c425e76e02 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.tsx @@ -0,0 +1,13 @@ +import { + reactExtension, + TextField, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.tsx new file mode 100644 index 0000000000..9246000cd3 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.tsx @@ -0,0 +1,25 @@ +import { + reactExtension, + ToggleButton, + ToggleButtonGroup, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + None + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.tsx new file mode 100644 index 0000000000..e0d0513857 --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.tsx @@ -0,0 +1,72 @@ +import { + reactExtension, + BlockStack, + InlineLayout, + Text, + ToggleButton, + ToggleButtonGroup, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + { + console.log( + `onChange event with value: ${value}`, + ); + }} + > + + + + None + + + + + 100 + + points + + + + + + 200 + + points + + + + + + 300 + + points + + + + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.tsx new file mode 100644 index 0000000000..22de26c56e --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.tsx @@ -0,0 +1,26 @@ +import { + reactExtension, + Icon, + Pressable, + Tooltip, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + In case we need to contact you about + your order + + } + > + + + ); +} diff --git a/packages/ui-extensions-react/src/surfaces/customer-account/components/View/examples/basic-view.example.tsx b/packages/ui-extensions-react/src/surfaces/customer-account/components/View/examples/basic-view.example.tsx new file mode 100644 index 0000000000..5965b263db --- /dev/null +++ b/packages/ui-extensions-react/src/surfaces/customer-account/components/View/examples/basic-view.example.tsx @@ -0,0 +1,17 @@ +import { + reactExtension, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension( + 'customer-account.page.render', + () => , +); + +function Extension() { + return ( + + View + + ); +} diff --git a/packages/ui-extensions/docs/surfaces/build-doc-shared.mjs b/packages/ui-extensions/docs/surfaces/build-doc-shared.mjs new file mode 100644 index 0000000000..4d8e594b7f --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/build-doc-shared.mjs @@ -0,0 +1,72 @@ +/* eslint-disable no-undef, no-console */ +import childProcess from 'child_process'; +import fs from 'fs/promises'; +import {existsSync} from 'fs'; +import path from 'path'; + +export const replaceFileContent = async ({ + filePaths, + searchValue, + replaceValue, +}) => { + const files = Array.isArray(filePaths) ? filePaths : [filePaths]; + for (const filePath of files) { + const content = await fs.readFile(filePath, 'utf8'); + // @ts-ignore -- TS should know this is a string but it doesn't + const replacedContent = content.replaceAll(searchValue, replaceValue); + await fs.writeFile(filePath, replacedContent); + } +}; + +export const generateFiles = async ({ + scripts, + outputDir, + rootPath, + generatedDocsDataFile, + generatedStaticPagesFile, + transformJson, +}) => { + scripts.forEach((script) => childProcess.execSync(script, {stdio: 'pipe'})); + + const srcFiles = await fs.readdir(rootPath, {recursive: true}); + const builtFiles = srcFiles.filter((file) => file.endsWith('.ts')); + await Promise.all( + builtFiles.map((file) => { + const jsFilePath = path.join(rootPath, file.replace('.ts', '.js')); + return existsSync(jsFilePath) ? fs.rm(jsFilePath) : Promise.resolve(); + }), + ); + + const generatedFiles = [path.join(outputDir, generatedDocsDataFile)]; + if (generatedStaticPagesFile) { + generatedFiles.push(path.join(outputDir, generatedStaticPagesFile)); + } + + // Make sure https://shopify.dev URLs are relative so they work in Spin. + // See https://github.com/Shopify/generate-docs/issues/181 + await replaceFileContent({ + filePaths: generatedFiles, + searchValue: 'https://shopify.dev', + replaceValue: '', + }); + + if (transformJson) { + await transformJson(path.join(outputDir, generatedDocsDataFile)); + } +}; + +export const copyGeneratedToShopifyDev = async ({ + generatedDocsPath, + shopifyDevPath, + shopifyDevDBPath, +}) => { + const shopifyDevExists = existsSync(shopifyDevPath); + if (!shopifyDevExists) { + console.log( + `Not copying docs to shopify-dev because it was not found at ${shopifyDevPath}.`, + ); + process.exit(); + } + + await fs.cp(generatedDocsPath, shopifyDevDBPath, {recursive: true}); +}; diff --git a/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs b/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs new file mode 100644 index 0000000000..5825f71acb --- /dev/null +++ b/packages/ui-extensions/docs/surfaces/customer-account/build-docs.mjs @@ -0,0 +1,288 @@ +/* eslint-disable no-undef, no-console */ +import {exec as execCb, execSync} from 'child_process'; +import fs from 'fs/promises'; +import {existsSync} from 'fs'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import {promisify} from 'util'; + +import { + copyGeneratedToShopifyDev, + replaceFileContent, +} from '../build-doc-shared.mjs'; + +const execAsync = promisify(execCb); + +const EXTENSIONS_API_VERSION = process.argv[2] || 'unstable'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const rootPath = path.join(__dirname, '../../..'); +const docsRelativePath = 'docs/surfaces/customer-account'; +const docsGeneratedRelativePath = 'docs/surfaces/customer-account/generated'; +const srcRelativePath = 'src/surfaces/customer-account'; +const reactSrcRelativePath = `../ui-extensions-react/${srcRelativePath}`; +const checkoutSrcRelativePath = 'src/surfaces/checkout'; +const checkoutComponentsRelativePath = `${checkoutSrcRelativePath}/components`; +const docsPath = path.join(rootPath, docsRelativePath); +const srcPath = path.join(rootPath, srcRelativePath); +const checkoutSrcPath = path.join(rootPath, checkoutSrcRelativePath); +const checkoutComponentsDir = path.join(checkoutSrcPath, 'components'); +const generatedDocsPath = path.join(docsPath, 'generated'); +const shopifyDevPath = path.join(rootPath, '../../../shopify-dev'); +const shopifyDevDBPath = path.join( + shopifyDevPath, + 'areas/platforms/shopify-dev/db/data/docs/templated_apis', +); + +const generatedDocsDataFile = 'generated_docs_data.json'; +const generatedStaticPagesFile = 'generated_static_pages.json'; + +const componentDefs = path.join(srcPath, 'components.d.ts'); +const tempComponentDefs = path.join(srcPath, 'components.ts'); + +const tsconfig = 'tsconfig.docs.json'; + +const maxBuffer = 50 * 1024 * 1024; + +const copyCheckoutTypesToTemp = async () => { + const files = await fs.readdir(checkoutComponentsDir); + return Promise.all( + files + .filter( + (file) => file.endsWith('.d.ts') && file !== 'components-shared.d.ts', + ) + .map(async (file) => { + const srcFile = path.join(checkoutComponentsDir, file); + const tempFile = path.join( + checkoutComponentsDir, + file.replace('.d.ts', '.ts'), + ); + await fs.copyFile(srcFile, tempFile); + return tempFile; + }), + ); +}; + +const cleanupTempFiles = async (tempFiles) => { + await Promise.all( + tempFiles + .filter((file) => existsSync(file)) + .map((file) => fs.rm(file)), + ); +}; + +const cleanupGeneratedJsFiles = async (directories) => { + await Promise.all( + directories.map(async (dir) => { + if (!existsSync(dir)) return; + const files = await fs.readdir(dir, {recursive: true}); + await Promise.all( + files + .filter((file) => file.endsWith('.js')) + .map((file) => { + const jsPath = path.join(dir, file); + const tsPath = path.join(dir, file.replace(/\.js$/, '.ts')); + return existsSync(tsPath) ? fs.rm(jsPath) : Promise.resolve(); + }), + ); + }), + ); +}; + +const generateExtensionsDocs = async () => { + console.log( + `Building Customer Account UI Extensions docs for ${EXTENSIONS_API_VERSION} version`, + ); + + if (EXTENSIONS_API_VERSION === 'unstable') { + console.log( + "You can add a calver version argument (e.g. 'yarn docs:customer-account 2024-07') to generate the docs for a stable version.", + ); + } + + const outputDir = `${docsGeneratedRelativePath}/customer_account_ui_extensions/${EXTENSIONS_API_VERSION}`; + const tempRefOutputDir = `${outputDir}/_temp_ref`; + const tempCompOutputDir = `${outputDir}/_temp_comp`; + + await fs.mkdir(outputDir, {recursive: true}); + await fs.mkdir(tempRefOutputDir, {recursive: true}); + await fs.mkdir(tempCompOutputDir, {recursive: true}); + + // Single tsc step — tsconfig.docs.json already covers all .doc.ts files + // (reference, staticPages, categories, and component docs) + console.log('Compiling TypeScript...'); + execSync( + `yarn tsc --project ${docsRelativePath}/${tsconfig} --moduleResolution node --target esNext --module CommonJS`, + {stdio: 'pipe'}, + ); + + // Split generate-docs into independent parallel commands. + // Internally, generate-docs creates a TypeScript program for every + // --typesInput directory × every --input directory. Splitting reference + // docs from component docs avoids redundant type parsing: + // - Reference docs (APIs/targets) only need customer-account types + // - Component docs only need checkout component types + // (customer-account types are included automatically as the base path) + console.log('Generating docs in parallel...'); + const overridePath = `./${docsRelativePath}/typeOverride.json`; + await Promise.all([ + execAsync( + `yarn generate-docs --overridePath ${overridePath} --input ./${docsRelativePath}/reference --typesInput ./${srcRelativePath} ./${reactSrcRelativePath} --output ./${tempRefOutputDir}`, + {maxBuffer}, + ), + execAsync( + `yarn generate-docs --overridePath ${overridePath} --input ./${srcRelativePath} --typesInput ./${srcRelativePath} ./${checkoutSrcRelativePath} --output ./${tempCompOutputDir}`, + {maxBuffer}, + ), + execAsync( + `yarn generate-docs --isLandingPage --input ./${docsRelativePath}/staticPages --output ./${outputDir}`, + {maxBuffer}, + ), + ]); + + // Merge the two generated_docs_data.json files + const [refData, compData] = await Promise.all([ + fs + .readFile(path.join(tempRefOutputDir, generatedDocsDataFile), 'utf8') + .then(JSON.parse), + fs + .readFile(path.join(tempCompOutputDir, generatedDocsDataFile), 'utf8') + .then(JSON.parse), + ]); + const mergedData = [...refData, ...compData].filter(Boolean); + await fs.writeFile( + path.join(outputDir, generatedDocsDataFile), + JSON.stringify(mergedData, null, 2), + ); + + // Clean up temp directories + await Promise.all([ + fs.rm(tempRefOutputDir, {recursive: true}), + fs.rm(tempCompOutputDir, {recursive: true}), + ]); + + // Clean up .js files only in directories where tsc output lands + await cleanupGeneratedJsFiles([ + path.join(rootPath, docsRelativePath), + path.join(rootPath, srcRelativePath), + path.join(rootPath, 'src/docs/shared'), + ]); + + const generatedFiles = [path.join(outputDir, generatedDocsDataFile)]; + if (generatedStaticPagesFile) { + generatedFiles.push(path.join(outputDir, generatedStaticPagesFile)); + } + + // Make sure https://shopify.dev URLs are relative so they work in Spin + await replaceFileContent({ + filePaths: generatedFiles, + searchValue: 'https://shopify.dev', + replaceValue: '', + }); + + // Replace 'unstable' with the exact API version in relative doc links + await replaceFileContent({ + filePaths: path.join(outputDir, generatedDocsDataFile), + searchValue: '/docs/api//unstable/', + replaceValue: `/docs/api/customer-account-ui-extensions/${EXTENSIONS_API_VERSION}`, + }); + + await fs.cp( + path.join(docsPath, 'screenshots'), + path.join( + shopifyDevPath, + 'areas/platforms/shopify-dev/content/assets/images/templated-apis-screenshots/customer-account-ui-extensions', + EXTENSIONS_API_VERSION, + ), + {recursive: true}, + ); +}; + +const surfaceFiles = [ + path.join(rootPath, 'src/surfaces/checkout.ts'), + path.join(rootPath, 'src/surfaces/admin.ts'), + path.join(rootPath, 'src/surfaces/point-of-sale.ts'), + path.join(rootPath, '../ui-extensions-react/src/surfaces/checkout.ts'), + path.join(rootPath, '../ui-extensions-react/src/surfaces/admin.ts'), + path.join(rootPath, '../ui-extensions-react/src/surfaces/point-of-sale.ts'), +]; + +const blankSurfaces = async () => { + const originals = new Map(); + for (const file of surfaceFiles) { + if (existsSync(file)) { + originals.set(file, await fs.readFile(file, 'utf8')); + await fs.writeFile(file, 'export {}\n'); + } + } + return originals; +}; + +const restoreSurfaces = async (originals) => { + for (const [file, content] of originals) { + await fs.writeFile(file, content); + } +}; + +let checkoutTempFiles = []; +let surfaceOriginals = new Map(); +try { + if (existsSync(generatedDocsPath)) { + await fs.rm(generatedDocsPath, {recursive: true}); + } + if (existsSync(componentDefs)) { + await fs.copyFile(componentDefs, tempComponentDefs); + await replaceFileContent({ + filePaths: tempComponentDefs, + searchValue: /typeof globalThis\.HTMLElement/g, + replaceValue: 'any', + }); + } + + console.log('Blanking other surface files to avoid type conflicts...'); + surfaceOriginals = await blankSurfaces(); + + console.log('Copying checkout .d.ts files to temporary .ts files...'); + checkoutTempFiles = await copyCheckoutTypesToTemp(); + + await generateExtensionsDocs(); + + // Generate targets.json + console.log('Generating targets.json...'); + try { + execSync(`node ${path.join(docsPath, 'build-docs-targets-json.mjs')} ${EXTENSIONS_API_VERSION}`, { + stdio: 'inherit', + cwd: rootPath, + }); + console.log('✅ Generated targets.json'); + } catch (targetsError) { + console.warn( + 'Warning: Failed to generate targets.json:', + targetsError.message, + ); + } + + await copyGeneratedToShopifyDev({ + generatedDocsPath, + shopifyDevPath, + shopifyDevDBPath, + }); + + if (existsSync(tempComponentDefs)) { + await fs.rm(tempComponentDefs); + } + await cleanupTempFiles(checkoutTempFiles); + await restoreSurfaces(surfaceOriginals); +} catch (error) { + await cleanupTempFiles(checkoutTempFiles); + if (existsSync(tempComponentDefs)) { + await fs.rm(tempComponentDefs); + } + await restoreSurfaces(surfaceOriginals); + console.error(error); + console.log(error.stdout?.toString?.() ?? ''); + console.log(error.stderr?.toString?.() ?? ''); + process.exit(1); +} diff --git a/packages/ui-extensions/docs/surfaces/customer-account/categories/components.doc.ts b/packages/ui-extensions/docs/surfaces/customer-account/categories/components.doc.ts deleted file mode 100644 index b5494702d1..0000000000 --- a/packages/ui-extensions/docs/surfaces/customer-account/categories/components.doc.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {CategoryTemplateSchema} from '@shopify/generate-docs'; - -const data: CategoryTemplateSchema = { - category: 'components', - sections: [ - { - type: 'Generic', - anchorLink: 'additional-components', - title: 'Additional components', - sectionContent: - 'In addition to the components below, you can also use checkout components to build customer account UI extensions.', - sectionCard: [ - { - type: 'blocks', - name: 'Checkout components', - subtitle: 'More components', - url: '/docs/api/checkout-ui-extensions/components', - }, - ], - }, - ], -}; - -export default data; diff --git a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_docs_data.json b/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2025-07/generated_docs_data.json similarity index 80% rename from packages/ui-extensions/docs/surfaces/customer-account/generated/generated_docs_data.json rename to packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2025-07/generated_docs_data.json index 52ad7fdce1..d1b0493ec0 100644 --- a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_docs_data.json +++ b/packages/ui-extensions/docs/surfaces/customer-account/generated/customer_account_ui_extensions/2025-07/generated_docs_data.json @@ -64,7 +64,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -86,7 +86,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -531,7 +531,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -594,7 +594,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -690,7 +690,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -712,7 +712,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -1392,7 +1392,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -1536,7 +1536,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -1571,7 +1571,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -4203,7 +4203,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -4232,7 +4232,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -4261,7 +4261,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -4335,7 +4335,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -4431,7 +4431,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -4741,7 +4741,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -4770,7 +4770,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -4799,7 +4799,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -4873,7 +4873,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -4969,7 +4969,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -5281,7 +5281,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -5310,7 +5310,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -5339,7 +5339,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -5413,7 +5413,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -5509,7 +5509,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -5819,7 +5819,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -5848,7 +5848,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -5877,7 +5877,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -5951,7 +5951,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -6047,7 +6047,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -6588,7 +6588,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -6658,7 +6658,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -6687,7 +6687,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -6758,7 +6758,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -6828,7 +6828,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -6857,7 +6857,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -9292,7 +9292,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -9314,7 +9314,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -9338,7 +9338,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -9401,7 +9401,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -9497,7 +9497,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -9519,7 +9519,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -9957,7 +9957,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -11349,7 +11349,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -11378,7 +11378,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -11407,7 +11407,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -11546,7 +11546,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -11704,7 +11704,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -11800,7 +11800,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -12371,7 +12371,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -12393,7 +12393,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -12417,7 +12417,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -12480,7 +12480,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -12576,7 +12576,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -12598,7 +12598,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -13036,7 +13036,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -13514,7 +13514,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -13536,7 +13536,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -13560,7 +13560,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -13623,7 +13623,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -13719,7 +13719,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -13741,7 +13741,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -14179,7 +14179,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -15570,7 +15570,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -15599,7 +15599,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -15628,7 +15628,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -15767,7 +15767,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -15925,7 +15925,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -16021,7 +16021,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -16592,7 +16592,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -16614,7 +16614,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -16638,7 +16638,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -16701,7 +16701,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -16797,7 +16797,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -16819,7 +16819,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -17257,7 +17257,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -18601,7 +18601,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -18630,7 +18630,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -18659,7 +18659,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -18798,7 +18798,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -18956,7 +18956,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -19052,7 +19052,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -19623,7 +19623,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -19645,7 +19645,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -19669,7 +19669,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -19732,7 +19732,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -19828,7 +19828,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -19850,7 +19850,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -20288,7 +20288,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -20774,7 +20774,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -20803,7 +20803,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -20832,7 +20832,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -20906,7 +20906,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -21002,7 +21002,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -22165,7 +22165,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -22194,7 +22194,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -22223,7 +22223,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -22362,7 +22362,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -22520,7 +22520,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -22616,7 +22616,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -23187,7 +23187,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -23209,7 +23209,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -23233,7 +23233,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -23296,7 +23296,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -23392,7 +23392,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -23414,7 +23414,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -23852,7 +23852,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -25189,7 +25189,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -25218,7 +25218,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -25247,7 +25247,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -25386,7 +25386,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -25544,7 +25544,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -25640,7 +25640,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -26211,7 +26211,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -26233,7 +26233,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -26257,7 +26257,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -26320,7 +26320,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -26416,7 +26416,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -26438,7 +26438,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -26876,7 +26876,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -28213,7 +28213,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -28242,7 +28242,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -28271,7 +28271,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -28410,7 +28410,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -28568,7 +28568,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -28664,7 +28664,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -29235,7 +29235,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -29257,7 +29257,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -29281,7 +29281,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -29344,7 +29344,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -29440,7 +29440,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -29462,7 +29462,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -29900,7 +29900,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -31237,7 +31237,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -31266,7 +31266,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -31295,7 +31295,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -31434,7 +31434,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -31592,7 +31592,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -31688,7 +31688,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -32259,7 +32259,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -32281,7 +32281,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -32305,7 +32305,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -32368,7 +32368,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -32464,7 +32464,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -32486,7 +32486,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -32924,7 +32924,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -34283,7 +34283,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -34312,7 +34312,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -34341,7 +34341,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -34480,7 +34480,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -34638,7 +34638,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -34734,7 +34734,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -35305,7 +35305,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -35327,7 +35327,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -35351,7 +35351,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -35414,7 +35414,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -35510,7 +35510,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -35532,7 +35532,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -35970,7 +35970,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -37307,7 +37307,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -37336,7 +37336,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -37365,7 +37365,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -37504,7 +37504,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -37662,7 +37662,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -37758,7 +37758,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -38329,7 +38329,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -38351,7 +38351,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -38375,7 +38375,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -38438,7 +38438,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -38534,7 +38534,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -38556,7 +38556,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -38994,7 +38994,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -40331,7 +40331,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -40360,7 +40360,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -40389,7 +40389,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -40528,7 +40528,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -40686,7 +40686,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -40782,7 +40782,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -41353,7 +41353,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -41375,7 +41375,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -41399,7 +41399,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -41462,7 +41462,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -41558,7 +41558,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -41580,7 +41580,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -42018,7 +42018,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -42536,7 +42536,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -42558,7 +42558,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -42582,7 +42582,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -42645,7 +42645,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -42741,7 +42741,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -42763,7 +42763,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -43201,7 +43201,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -43482,7 +43482,7 @@ "filePath": "src/surfaces/customer-account/api/docs.ts", "syntaxKind": "PropertySignature", "name": "appearance", - "value": "Extract", + "value": "'critical' | 'monochrome'", "description": "Specify the color treatment of the Button.", "isOptional": true }, @@ -43529,13 +43529,6 @@ } ], "value": "export interface Docs_OrderActionMenu_Button\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n | 'appearance'\n > {\n /**\n * Destination URL to link to.\n *\n * E.g. `extension:/` to navigate to the Full-page extension.\n */\n to: ButtonProps['to'];\n}" - }, - "Appearance": { - "filePath": "src/surfaces/checkout/components/shared.ts", - "syntaxKind": "TypeAliasDeclaration", - "name": "Appearance", - "value": "'base' | 'accent' | 'decorative' | 'interactive' | 'subdued' | 'info' | 'success' | 'warning' | 'critical' | 'monochrome'", - "description": "" } } } @@ -43794,7 +43787,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -43816,7 +43809,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -43840,7 +43833,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -43903,7 +43896,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -43999,7 +43992,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -44021,7 +44014,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -44459,7 +44452,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -45907,7 +45900,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"code\"", + "value": "'code'", "description": "The type of the code discount" } ], @@ -45936,7 +45929,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"automatic\"", + "value": "'automatic'", "description": "The type of the automatic discount" } ], @@ -45965,7 +45958,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"custom\"", + "value": "'custom'", "description": "The type of the custom discount" } ], @@ -46104,7 +46097,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -46262,7 +46255,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"bundle\"", + "value": "'bundle'", "description": "" } ], @@ -46358,7 +46351,7 @@ "filePath": "src/surfaces/customer-account/api/order-status/order-status.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"variant\"", + "value": "'variant'", "description": "" } ] @@ -46929,7 +46922,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -46951,7 +46944,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -46975,7 +46968,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -47038,7 +47031,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -47134,7 +47127,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -47156,7 +47149,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -47594,7 +47587,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -48193,7 +48186,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -48215,7 +48208,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -48239,7 +48232,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -48302,7 +48295,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -48398,7 +48391,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -48420,7 +48413,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -48858,7 +48851,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -49327,7 +49320,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -49349,7 +49342,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -49373,7 +49366,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -49436,7 +49429,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -49532,7 +49525,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -49554,7 +49547,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -49992,7 +49985,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -50516,7 +50509,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -50538,7 +50531,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -50562,7 +50555,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -50625,7 +50618,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -50721,7 +50714,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -50743,7 +50736,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -51181,7 +51174,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -51657,7 +51650,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -51679,7 +51672,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -51703,7 +51696,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -51766,7 +51759,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -51862,7 +51855,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -51884,7 +51877,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -52322,7 +52315,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -52791,7 +52784,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -52813,7 +52806,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -52837,7 +52830,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -52900,7 +52893,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -52996,7 +52989,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -53018,7 +53011,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -53456,7 +53449,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -53947,7 +53940,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -53969,7 +53962,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -53993,7 +53986,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -54056,7 +54049,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -54152,7 +54145,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -54174,7 +54167,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -54612,7 +54605,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -55103,7 +55096,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -55125,7 +55118,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -55149,7 +55142,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -55212,7 +55205,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -55308,7 +55301,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -55330,7 +55323,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -55768,7 +55761,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -56259,7 +56252,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "Indicates that the visitor information was validated and submitted." } ], @@ -56281,7 +56274,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "Indicates that the visitor information is invalid and wasn't submitted. Examples are using the wrong data type or missing a required property." } ], @@ -56305,7 +56298,7 @@ "name": "Promise", "value": "Promise" }, - "value": "export type ApplyTrackingConsentChangeType = (\n visitorConsent: VisitorConsentChange,\n) => Promise;" + "value": "(\n visitorConsent: VisitorConsentChange,\n) => Promise" }, "VisitorConsentChange": { "filePath": "src/surfaces/customer-account/api/shared.ts", @@ -56368,7 +56361,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"changeVisitorConsent\"", + "value": "'changeVisitorConsent'", "description": "" } ], @@ -56464,7 +56457,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"success\"", + "value": "'success'", "description": "The type of the `TrackingConsentChangeResultSuccess` API." } ], @@ -56486,7 +56479,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"error\"", + "value": "'error'", "description": "The type of the `TrackingConsentChangeResultError` API." } ], @@ -56924,7 +56917,7 @@ "filePath": "src/surfaces/customer-account/api/shared.ts", "syntaxKind": "PropertySignature", "name": "type", - "value": "\"checkout\"", + "value": "'checkout'", "description": "Indicates whether the extension is rendering in the checkout editor." } ], @@ -57248,7 +57241,7 @@ "filePath": "src/surfaces/customer-account/components/Avatar/Avatar.ts", "syntaxKind": "PropertySignature", "name": "size", - "value": "Extract", + "value": "", "description": "Size of the avatar.", "isOptional": true, "defaultValue": "'base'" @@ -57263,18 +57256,12 @@ } ], "value": "export interface AvatarProps extends IdProps {\n /**\n * Initials to display in the avatar.\n */\n initials?: string;\n\n /**\n * The URL or path to the image.\n *\n * Initials will be rendered as a fallback if `src` is not provided, fails to load or does not load quickly.\n */\n src?: string;\n\n /**\n * Invoked when load of provided image completes successfully.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload\n */\n onLoad?(): void;\n\n /**\n * Invoked on load error of provided image.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror\n */\n onError?(): void;\n\n /**\n * Size of the avatar.\n *\n * @default 'base'\n */\n size?: Extract;\n\n /**\n * An alternative text description that describe the image for the reader\n * to understand what it is about or identify the user the avatar belongs to.\n */\n alt?: string;\n}" - }, - "Size": { - "filePath": "src/surfaces/checkout/components/shared.ts", - "syntaxKind": "TypeAliasDeclaration", - "name": "Size", - "value": "'extraSmall' | 'small' | 'base' | 'large' | 'extraLarge' | 'fill'", - "description": "" } } } ], - "category": "components", + "category": "UI components", + "subCategory": "Media and visuals", "defaultExample": { "image": "avatar-preview.png", "altText": "An example of the avatar with two variants: one with initials and the other with an icon.", @@ -57305,347 +57292,257 @@ "related": [] }, { - "name": "Card", - "description": "Group related content and functionality together in a familiar and consistent style, for customers to scan, read, and get things done.", - "thumbnail": "card-thumbnail.png", - "requires": "", + "name": "Badge", + "description": "Use badges to highlight contextual information, like a label or a status, about an object. An object can be anything that has a status or label attributed to it, like an order or subscription.", "isVisualComponent": true, - "type": "", - "definitions": [ - { - "title": "CardProps", - "description": "", - "type": "CardProps", - "typeDefinitions": { - "CardProps": { - "filePath": "src/surfaces/customer-account/components/Card/Card.ts", - "name": "CardProps", - "description": "", - "members": [ - { - "filePath": "src/surfaces/customer-account/components/Card/Card.ts", - "syntaxKind": "PropertySignature", - "name": "padding", - "value": "boolean", - "description": "Adjust the padding of all edges.\n\n`true` applies a default padding that is appropriate for the component.", - "isOptional": true - } - ], - "value": "export interface CardProps {\n /**\n * Adjust the padding of all edges.\n *\n * `true` applies a default padding that is appropriate for the component.\n */\n padding?: boolean;\n}" - } - } - } - ], - "category": "components", - "defaultExample": { - "image": "card-preview.png", - "altText": "An example of the card component shows a header that says \"Addresses\", and a button in the upper-right corner that says \"+Add\". Under the header, there is a full mailing address labeled as the default address, with a pencil icon for editing it.", - "codeblock": { - "title": "Basic Card", - "tabs": [ - { - "title": "React", - "code": "import {\n Card,\n Grid,\n BlockStack,\n Heading,\n Text,\n TextBlock,\n View,\n Icon,\n InlineLayout,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <Card padding>\n <Grid\n columns={['fill', 'auto']}\n spacing=\"base\"\n minInlineSize=\"fill\"\n blockAlignment=\"start\"\n >\n <BlockStack spacing=\"loose\">\n <Heading>Addresses</Heading>\n <BlockStack spacing=\"base\">\n <Text appearance=\"subdued\">\n Default address\n </Text>\n <BlockStack spacing=\"extraTight\">\n <TextBlock>\n Kristin Watson\n </TextBlock>\n <TextBlock>\n 1655 Island Pkwy\n </TextBlock>\n <TextBlock>\n Kamloops BC M7G 672\n </TextBlock>\n <TextBlock>Canada</TextBlock>\n </BlockStack>\n </BlockStack>\n </BlockStack>\n <BlockStack spacing=\"loose\">\n <InlineLayout blockAlignment=\"center\">\n <Icon\n source=\"plus\"\n size=\"small\"\n appearance=\"accent\"\n />\n <Text appearance=\"accent\">Add</Text>\n </InlineLayout>\n <View inlineAlignment=\"end\">\n <Icon\n source=\"pen\"\n size=\"small\"\n appearance=\"accent\"\n />\n </View>\n </BlockStack>\n </Grid>\n </Card>\n );\n}\n", - "language": "tsx" - }, - { - "title": "JS", - "code": "import {\n Card,\n Grid,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n const card = root.createComponent(\n Card,\n {padding: true},\n [\n root.createComponent(Grid, {columns: ['1fr', 'auto'],\n spacing: \"base\",\n minInlineSize: \"fill\",\n blockAlignment: \"start\"}, [\n root.createComponent('BlockStack', {spacing: 'loose'}, [\n root.createComponent('Heading', undefined, 'Addresses'),\n root.createComponent('BlockStack', {spacing: 'base'}, [\n root.createComponent('Text', {appearance: \"subdued\"}, 'Default address'),\n root.createComponent('BlockStack', {spacing: 'extraTight'}, [\n root.createComponent('TextBlock',{}, 'Kristin Watson'),\n root.createComponent('TextBlock', {}, '1655 Island Pkwy'),\n root.createComponent('TextBlock', {}, 'Kamloops BC M7G 672'),\n root.createComponent('TextBlock', {}, 'Canada'),\n ]),\n ]),\n ]),\n root.createComponent('BlockStack', {spacing: 'loose'}, [\n root.createComponent('InlineLayout', {blockAlignment: \"center\"}, [\n root.createComponent('Icon', {source: \"plus\", size: \"small\", appearance: \"accent\"}),\n root.createComponent('Text', {appearance: \"accent\"}, 'Add'),\n ]),\n root.createComponent('View', {inlineAlignment: \"end\"}, [\n root.createComponent('Icon', {source: \"pen\", size: \"small\", appearance: \"accent\"}),\n ]),\n ]),\n ]),\n ])\n root.append(card);\n}\n", - "language": "js" - } - ] - } - }, - "subSections": [ - { - "type": "Generic", - "anchorLink": "best-practices", - "title": "Best Practices", - "sectionContent": "\n- Group related information.\n- Use headings that set clear expectations about the card’s purpose.\n- Display information in a way that emphasizes and prioritizes what the customer needs to know first.\n" - } - ], - "related": [] - }, - { - "name": "CustomerAccountAction", - "description": "A modal to complete an order action flow. This component can only be used to populate the [customer-account.order.action.render](/docs/api/customer-account-ui-extensions/unstable/targets/order-action-menu/customer-account-order-action-render) extension target, which renders as a result of the customer clicking the order action button rendered via the [customer-account.order.action.menu-item.render](/docs/api/customer-account-ui-extensions/unstable/targets/order-action-menu/customer-account-order-action-menu-item-render) extension target.", - "thumbnail": "customeraccountaction-thumbnail.png", + "thumbnail": "badge-thumbnail.png", "requires": "", - "isVisualComponent": true, "type": "", "definitions": [ { - "title": "CustomerAccountActionProps", + "title": "BadgeProps", "description": "", - "type": "CustomerAccountActionProps", + "type": "BadgeProps", "typeDefinitions": { - "CustomerAccountActionProps": { - "filePath": "src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.ts", - "name": "CustomerAccountActionProps", + "BadgeProps": { + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", + "name": "BadgeProps", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "primaryAction", - "value": "RemoteFragment", - "description": "Sets the Primary action button of the container. This component must be a button component.", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will announced to buyers using assistive technologies.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "secondaryAction", - "value": "RemoteFragment", - "description": "Sets the Secondary action button of the container. This component must be a button component.", + "name": "accessibilityVisibility", + "value": "AccessibilityVisibility", + "description": "Changes the visibility of the element to assistive technologies.\n\n`hidden` hides the component from assistive technology (for example, a screen reader) but remains visually visible.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.ts", - "syntaxKind": "PropertySignature", - "name": "title", - "value": "string", - "description": "Sets the title of the Action container." - } - ], - "value": "export interface CustomerAccountActionProps {\n /**\n * Sets the title of the Action container.\n */\n title: string;\n /**\n * Sets the Primary action button of the container. This component must be a button component.\n */\n primaryAction?: RemoteFragment;\n /**\n * Sets the Secondary action button of the container. This component must be a button component.\n */\n secondaryAction?: RemoteFragment;\n}" - } - } - }, - { - "title": "ButtonProps primaryAction", - "description": "Supported props for Buttons used inside CustomerAccountAction `primaryAction` prop.

`children` only support text.", - "type": "Docs_CustomerAccountAction_Button_PrimaryAction", - "typeDefinitions": { - "Docs_CustomerAccountAction_Button_PrimaryAction": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_CustomerAccountAction_Button_PrimaryAction", - "description": "", - "members": [ - { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "name": "icon", + "value": "IconSource", + "description": "The name of the icon to be displayed in the badge.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityRole", - "value": "ButtonAccessibilityRole", - "description": "The role of the button that will be rendered.\n\n`button`: renders a regular button.\n\n`submit`: renders a button that submits a form.", + "name": "iconPosition", + "value": "'start' | 'end'", + "description": "The position of the icon in relation to the text.", "isOptional": true, - "defaultValue": "'button'" + "defaultValue": "'start'" }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "disabled", - "value": "boolean", - "description": "Disables the button, disallowing any interaction.", + "name": "size", + "value": "'small' | 'base'", + "description": "The size of the badge being rendered.", "isOptional": true, - "defaultValue": "false" + "defaultValue": "'base'" }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Replaces content with a loading indicator.", + "name": "tone", + "value": "Tone", + "description": "The tone of the badge being rendered. Indicates its level of importance, where subdued provides the least emphasis, while critical indicates the highest level of urgency.", "isOptional": true, - "defaultValue": "false" + "defaultValue": "'default'" }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", "syntaxKind": "PropertySignature", - "name": "loadingLabel", - "value": "string", - "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", - "isOptional": true - }, - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", + "name": "visibility", + "value": "Visibility", + "description": "Changes the visibility of the element.\n\n`hidden` visually hides the component while keeping it accessible to assistive technology, such as screen readers. Hidden elements don't take any visual space contrary to CSS visibility: hidden;", "isOptional": true } ], - "value": "export interface Docs_CustomerAccountAction_Button_PrimaryAction\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n | 'accessibilityRole'\n > {}" + "value": "export interface BadgeProps extends VisibilityProps {\n /**\n * The tone of the badge being rendered. Indicates its level of importance,\n * where subdued provides the least emphasis, while critical indicates the highest level of urgency.\n *\n * @default 'default'\n */\n tone?: Tone;\n /**\n * The size of the badge being rendered.\n *\n * @default 'base'\n */\n size?: Extract;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will announced to buyers using assistive technologies.\n */\n accessibilityLabel?: string;\n /**\n * The name of the icon to be displayed in the badge.\n */\n icon?: IconSource;\n /**\n * The position of the icon in relation to the text.\n *\n * @default 'start'\n */\n iconPosition?: 'start' | 'end';\n}" }, - "ButtonAccessibilityRole": { + "AccessibilityVisibility": { "filePath": "src/surfaces/checkout/components/shared.ts", "syntaxKind": "TypeAliasDeclaration", - "name": "ButtonAccessibilityRole", - "value": "'button' | 'submit'", + "name": "AccessibilityVisibility", + "value": "'hidden'", + "description": "" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + }, + "Tone": { + "filePath": "src/surfaces/checkout/components/Badge/Badge.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Tone", + "value": "'default' | 'critical' | 'subdued'", + "description": "" + }, + "Visibility": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Visibility", + "value": "'hidden'", "description": "" - } - } - }, - { - "title": "ButtonProps secondaryAction", - "description": "Supported props for Button used inside CustomerAccountAction `secondaryAction` prop.

`children` only support text.", - "type": "Docs_CustomerAccountAction_Button_SecondaryAction", - "typeDefinitions": { - "Docs_CustomerAccountAction_Button_SecondaryAction": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_CustomerAccountAction_Button_SecondaryAction", - "description": "", - "members": [ - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", - "isOptional": true - }, - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "PropertySignature", - "name": "disabled", - "value": "boolean", - "description": "Disables the button, disallowing any interaction.", - "isOptional": true, - "defaultValue": "false" - }, - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Replaces content with a loading indicator.", - "isOptional": true, - "defaultValue": "false" - }, - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "PropertySignature", - "name": "loadingLabel", - "value": "string", - "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", - "isOptional": true - }, - { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", - "isOptional": true - } - ], - "value": "export interface Docs_CustomerAccountAction_Button_SecondaryAction\n extends Pick<\n ButtonProps,\n 'onPress' | 'loading' | 'loadingLabel' | 'disabled' | 'accessibilityLabel'\n > {}" } } } ], - "category": "components", + "category": "UI components", + "subCategory": "Feedback and status indicators", "defaultExample": { - "image": "customeraccountaction-preview.png", - "altText": "An example of the CustomerAccountAction component shows a dismissible modal with a header that says \"Edit order\", a field for adjusting quantities, and a Save button.", + "image": "badge-default.png", "codeblock": { - "title": "Basic CustomerAccountAction", + "title": "Basic Badge", "tabs": [ { "title": "React", - "code": "import {\n Button,\n CustomerAccountAction,\n TextBlock,\n reactExtension,\n useApi,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension('customer-account.order.action.render', () => (\n <App />\n));\n\nfunction App() {\n const api = useApi<'customer-account.order.action.render'>();\n\n return (\n <CustomerAccountAction\n title=\"Extension title\"\n primaryAction={\n <Button\n onPress={() => {\n api.close();\n }}\n >\n Click to close\n </Button>\n }\n >\n <TextBlock>Extension content</TextBlock>\n </CustomerAccountAction>\n );\n}\n", + "code": "import {\n reactExtension,\n Badge,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Badge>Available</Badge>;\n}\n", "language": "tsx" }, { "title": "JS", - "code": "import {\n Button,\n CustomerAccountAction,\n extension\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.order.action.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nasync function renderApp(root, api) {\n const primaryAction = root.createFragment();\n await primaryAction.append(root.createComponent(Button, {onPress: () => {api.close()}}, 'Click to close'));\n\n const customerAccountAction = root.createComponent(\n CustomerAccountAction,\n {\n title: 'Extension title',\n primaryAction,\n },\n root.createComponent('TextBlock', {}, 'Extension content')\n );\n root.append(customerAccountAction);\n}\n", + "code": "import {extension, Badge} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const badge = root.createComponent(Badge, undefined, 'Available');\n\n root.appendChild(badge);\n});\n", "language": "js" } ] } }, + "examples": { + "description": "", + "examples": [ + { + "image": "badge-status.png", + "codeblock": { + "title": "Using the Badge component as a status indicator", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Badge,\n BlockStack,\n Text,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <BlockStack\n border=\"base\"\n padding=\"large200\"\n spacing=\"base\"\n borderRadius=\"large\"\n >\n <BlockStack spacing=\"none\">\n <Text size=\"large\" emphasis=\"bold\">\n Subscription\n </Text>\n <Text>Mini garden seeds</Text>\n </BlockStack>\n <BlockStack\n spacing=\"none\"\n inlineAlignment=\"start\"\n >\n <Text emphasis=\"bold\">\n $35.00 monthly\n </Text>\n <Badge tone=\"subdued\">Paused</Badge>\n </BlockStack>\n </BlockStack>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Badge,\n BlockStack,\n Text,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const container = root.createComponent(\n BlockStack,\n {\n border: 'base',\n padding: 'large200',\n spacing: 'base',\n borderRadius: 'large',\n },\n [\n root.createComponent(BlockStack, {spacing: 'none'}, [\n root.createComponent(\n Text,\n {size: 'large', emphasis: 'bold'},\n 'Subscription',\n ),\n root.createComponent(Text, undefined, 'Mini garden seeds'),\n ]),\n\n root.createComponent(\n BlockStack,\n {spacing: 'none', inlineAlignment: 'start'},\n [\n root.createComponent(Text, {emphasis: 'bold'}, '$35.00 monthly'),\n root.createComponent(Badge, {tone: 'subdued'}, 'Paused'),\n ],\n ),\n ],\n );\n\n root.appendChild(container);\n});\n", + "language": "js" + } + ] + } + } + ] + }, "subSections": [ { "type": "Generic", "anchorLink": "best-practices", "title": "Best Practices", - "sectionContent": "\n- Use CustomerAccountAction to shift focus toward information and functionality needed to confirm or complete an order action.\n- If the order action experience you’re building requires complex forms or large amounts of information, consider building a full-page extension instead.\n- See Polaris for more best practices and content guidelines for designing [Modals](https://polaris.shopify.com/components/overlays/modal#best-practices).\n" + "sectionContent": "- Aim for one word per badge.\n\n- For complex states that require 2 words, use sentence case.\n\n- For status badge labels, use an adjective (for example, \"Available\" or \"Complete\") or a verb in the past tense (for example, \"Delivered\" or \"Delayed\")\n\n- Use the tone prop to indicate the level of importance. `subdued` provides the least emphasis, while `critical` indicates the highest level of urgency.\n\n- Write a useful `accessibilityLabel` so that customers using assistive technology can access the full meaning of the badge in context. For badges with the `critical` tone, include information that conveys the urgency of the badge (for example, \"Warning\" or \"Alert\").\n\n- A badge should always be attributed to an object on the page." } ], "related": [] }, { - "name": "ImageGroup", - "description": "Display up to 4 images in a grid or stacked layout. For example, images of products in a wishlist or subscription. When there are more than 4 images, the component indicates how many more images are not displayed.", - "thumbnail": "imagegroup-thumbnail.png", - "requires": "", + "name": "Banner", + "description": "Use banners to communicate important messages to customers in a prominent way.", "isVisualComponent": true, + "thumbnail": "banner-thumbnail.png", + "requires": "", "type": "", "definitions": [ { - "title": "ImageGroupProps", + "title": "BannerProps", "description": "", - "type": "ImageGroupProps", + "type": "BannerProps", "typeDefinitions": { - "ImageGroupProps": { - "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", - "name": "ImageGroupProps", + "BannerProps": { + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", + "name": "BannerProps", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", - "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label that describes the purpose or contents of the image group. When set, it will be announced to users using assistive technologies and will provide them with more context.", - "isOptional": true - }, - { - "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", "syntaxKind": "PropertySignature", - "name": "loading", + "name": "collapsible", "value": "boolean", - "description": "Indicates that the image group is in a loading state.\n\nWhen `true`, the image group show a loading indicator.", + "description": "Makes the content collapsible. A collapsible banner will conceal child elements initially, but allow the user to expand the banner to see them.", "isOptional": true, "defaultValue": "false" }, { - "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", "syntaxKind": "PropertySignature", - "name": "totalItems", - "value": "number", - "description": "Indicates the total number of items that could be displayed in the image group. It is used to determine the remaining number to show when all the available image slots have been filled.", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", + "syntaxKind": "MethodSignature", + "name": "onDismiss", + "value": "() => void", + "description": "Callback when banner is dismissed. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), so you must manage the visibility of the banner in state by using the onDismiss callback.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", "syntaxKind": "PropertySignature", - "name": "variant", - "value": "'grid' | 'inline-stack'", - "description": "Changes the layout of the images.", + "name": "status", + "value": "Status", + "description": "Sets the status of the banner.", "isOptional": true, - "defaultValue": "\"grid\"" + "defaultValue": "'info'" + }, + { + "filePath": "src/surfaces/checkout/components/Banner/Banner.ts", + "syntaxKind": "PropertySignature", + "name": "title", + "value": "string", + "description": "Banners have an optional title. Use a title to grab the buyer’s attention with a short, concise message. Banners with no title should have child elements to convey the banner’s purpose to the buyer.", + "isOptional": true } ], - "value": "export interface ImageGroupProps {\n /**\n * Changes the layout of the images.\n *\n * @default \"grid\"\n */\n variant?: 'grid' | 'inline-stack';\n\n /**\n * A label that describes the purpose or contents of the image group. When set,\n * it will be announced to users using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n\n /**\n * Indicates that the image group is in a loading state.\n *\n * When `true`, the image group show a loading indicator.\n *\n * @defaultValue false\n */\n loading?: boolean;\n\n /**\n * Indicates the total number of items that could be displayed in the image group. It is used to determine the remaining number to show when all the available image slots have been filled.\n */\n totalItems?: number;\n}" + "value": "export interface BannerProps extends IdProps {\n /**\n * Banners have an optional title. Use a title to grab the buyer’s attention\n * with a short, concise message. Banners with no title should have child elements\n * to convey the banner’s purpose to the buyer.\n */\n title?: string;\n /**\n * Sets the status of the banner.\n *\n * @defaultValue 'info'\n */\n status?: Status;\n /**\n * Makes the content collapsible. A collapsible banner will conceal child\n * elements initially, but allow the user to expand the banner to see them.\n *\n * @defaultValue false\n */\n collapsible?: boolean;\n /**\n * Callback when banner is dismissed. This component is\n * [controlled](https://reactjs.org/docs/forms.html#controlled-components),\n * so you must manage the visibility of the banner in state by using\n * the onDismiss callback.\n */\n onDismiss?(): void;\n}" + }, + "Status": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Status", + "value": "'info' | 'success' | 'warning' | 'critical'", + "description": "" } } } ], - "category": "components", + "category": "UI components", + "subCategory": "Feedback and status indicators", "defaultExample": { - "image": "imagegroup-preview.png", - "altText": "An example of the ImageGroup component shows 3 circular images of plants displayed in a row, each one slightly overlapping the previous image—in a horizontal stacked pattern. To the right, there is another group of 3 images of plants, arranged in a 2x2 grid. There is one square image in the upper-left quadrant, one square image in the lower-left quadrant, and the entire right half of the grid is occupied by one image.", + "image": "banner-default.png", "codeblock": { - "title": "Basic ImageGroup", + "title": "Basic Banner", "tabs": [ { "title": "React", - "code": "import {\n Image,\n ImageGroup,\n View,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension('customer-account.page.render', () => <App />);\n\nfunction App() {\n return (\n <View maxInlineSize={300}>\n <ImageGroup>\n <Image source=\"../assets/flower.jpg\" />\n <Image source=\"../assets/flower.jpg\" />\n <Image source=\"../assets/flower.jpg\" />\n </ImageGroup>\n </View>\n );\n}\n", + "code": "import {\n reactExtension,\n Banner,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Banner\n status=\"critical\"\n title=\"Your payment details couldn’t be verified. Check your card details and try again.\"\n />\n );\n}\n", "language": "tsx" }, { "title": "JS", - "code": "import {\n Image,\n ImageGroup,\n View,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n const firstImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const secondeImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const thirdImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const imageGroup = root.createComponent(ImageGroup);\n\n imageGroup.append(firstImage);\n imageGroup.append(secondeImage);\n imageGroup.append(thirdImage);\n\n const view = root.createComponent(View, {maxInlineSize: 300});\n view.append(imageGroup);\n\n root.append(view);\n}\n", + "code": "import {extension, Banner} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const banner = root.createComponent(Banner, {\n status: 'critical',\n title:\n 'Your payment details couldn’t be verified. Check your card details and try again.',\n });\n\n root.appendChild(banner);\n});\n", "language": "js" } ] @@ -57656,129 +57553,112 @@ "type": "Generic", "anchorLink": "best-practices", "title": "Best Practices", - "sectionContent": "\n- Use with the [ResourceItem](/docs/api/customer-account-ui-extension/unstable/components/resourceitem) component\n- Optimize image file sizes and consider lazy loading for performance.\n" + "sectionContent": "- Use banners thoughtfully and sparingly, and only for the most important information. Too many banners distract customers from completing checkout.\n\n- Banners are typically displayed at the top of a page or a section, if they relate to specific content. Place banners below the relevant page or section header.\n\n- Include a Button component with next steps when possible.\n\n- Make banners dismissible, unless they contain critical information or an important step that customers need to take.\n\n- Use the `info` banner to update customers about a change or to give them advice.\n\n- Use the `warning` banner to display information that needs attention or that customers need to take action on. Warning banners can be stressful for customers, so be cautious about using them.\n\n- Use the `critical` banner to communicate problems that customers need to resolve immediately to complete checkout." + }, + { + "type": "Generic", + "anchorLink": "status", + "title": "Status", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"info\" | Convey general information or actions that aren’t critical or tied to a particular action.. |\n| \"success\" | Use rarely, only if you need additional visual confirmation that a non-standard action has been completed successfully, for example adding an item to an order as an upsell. |\n| \"warning\" | Display information that needs attention or that customers should take action on. Seeing these banners can be stressful for customers so be cautious about using them. Should not block progress to next step. |\n| \"critical\" | Communicate problems that have to be resolved immediately for customers to complete a task. For example, using a different payment method if card details couldn’t be processed. Seeing these banners can be stressful for customers so be cautious about using them. |" } ], "related": [] }, { - "name": "Menu", - "description": "Use a menu to display a list of actions in a popover. Actions can open a modal, trigger an event, or link to an external page.", - "thumbnail": "menu-thumbnail.png", - "requires": "", + "name": "BlockLayout", + "description": "BlockLayout is used to lay out content over multiple rows.\n\nBy default, all rows fill the available block space, sharing it equally.", + "thumbnail": "blocklayout-thumbnail.png", "isVisualComponent": true, + "requires": "", "type": "", "definitions": [ { - "title": "MenuProps", + "title": "BlockLayoutProps", "description": "", - "type": "MenuProps", + "type": "BlockLayoutProps", "typeDefinitions": { - "MenuProps": { - "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", - "name": "MenuProps", + "BlockLayoutProps": { + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", + "name": "BlockLayoutProps", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", "name": "accessibilityLabel", "value": "string", - "description": "A label to describe the purpose of the menu that is announced by screen readers.", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "id", - "value": "string", - "description": "A unique identifier for the component.", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "onClose", - "value": "() => void", - "description": "Callback to run when the Menu is closed", - "isOptional": true + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" }, { - "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", - "syntaxKind": "PropertySignature", - "name": "onOpen", - "value": "() => void", - "description": "Callback to run when the Menu is opened", - "isOptional": true - } - ], - "value": "export interface MenuProps extends IdProps {\n /**\n * A label to describe the purpose of the menu that is announced by screen readers.\n */\n accessibilityLabel?: string;\n /**\n * Callback to run when the Menu is opened\n */\n onOpen?: () => void;\n /**\n * Callback to run when the Menu is closed\n */\n onClose?: () => void;\n}" - } - } - }, - { - "title": "ButtonProps children", - "description": "The Menu component exclusively accepts Button elements with restricted props as its children. The `appearance` prop will always be set to monochrome by default.", - "type": "Docs_Menu_Button_Action", - "typeDefinitions": { - "Docs_Menu_Button_Action": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_Menu_Button_Action", - "description": "", - "members": [ - { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the cross axis.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityRole", - "value": "ButtonAccessibilityRole", - "description": "The role of the button that will be rendered.\n\n`button`: renders a regular button.\n\n`submit`: renders a button that submits a form.", - "isOptional": true, - "defaultValue": "'button'" + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "activateAction", - "value": "'auto' | 'copy'", - "description": "Sets the action the `activateTarget` should take when this pressable is activated.\n\nSupported actions by component:\n\n| Component | Supported Actions | Default ('auto') |\n|---------------|-------------------|-------------------|\n| [`ClipboardItem`](/docs/api/checkout-ui-extensions/latest/clipboarditem) | 'copy' | 'copy' |", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", "isOptional": true, - "defaultValue": "'auto' - a default action for the target component." + "isPrivate": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "activateTarget", - "value": "string", - "description": "ID of a component that should respond to activations (e.g. clicks) on this pressable.\n\nSee `activateAction` for how to control the behavior of the target.", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "appearance", - "value": "Extract", - "description": "Specify the color treatment of the Button.", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "disabled", - "value": "boolean", - "description": "Disables the button, disallowing any interaction.", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", "isOptional": true, - "defaultValue": "false" + "defaultValue": "'auto'" }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", "name": "id", "value": "string", @@ -57786,536 +57666,13053 @@ "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Replaces content with a loading indicator.", - "isOptional": true, - "defaultValue": "false" + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis.", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "loadingLabel", - "value": "string", - "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "overlay", - "value": "RemoteFragment", - "description": "An overlay component to render when the user interacts with the component.", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "submit", - "value": "boolean", - "description": "Allows the button to submit a form.", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", "isOptional": true, - "deprecationMessage": "use `accessibilityRole=\"submit\"` instead" + "defaultValue": "'visible'" }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "to", - "value": "string", - "description": "Destination URL to link to.", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", "syntaxKind": "PropertySignature", - "name": "toggles", - "value": "string", - "description": "The component's identifier whose visibility will be toggled when this component is actioned.", - "isOptional": true + "name": "rows", + "value": "MaybeResponsiveConditionalStyle", + "description": "Sizes for each row of the layout.\n\n\n`auto`: intrinsic size of the element.\n\n`fill`: fills the remaining available space. When multiple elements are set to `fill`, the remaining space is shared equally.\n\n`` `${number}%` ``: size in percentages.\n\n`` `${number}fr` ``: size in fractions.\n\n`number`: size in pixels.\n\n\n- When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n\n- When the size of an element is not explicitly set, it will fill the remaining space available.\n\n- When only one size is set and outside of an array, all elements of the layout will take that size.", + "isOptional": true, + "defaultValue": "'fill'" + }, + { + "filePath": "src/surfaces/checkout/components/BlockLayout/BlockLayout.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between children.\n\n- `base` means the space between rows and columns is `base`.\n\n- [`base`, `none`] means the space between rows is `base`, space between columns is `none`.", + "isOptional": true, + "defaultValue": "'none'" } ], - "value": "export interface Docs_Menu_Button_Action\n extends Omit<\n ButtonProps,\n 'kind' | 'textDecoration' | 'inlineAlignment' | 'inlineSize' | 'size'\n > {}" + "value": "export interface BlockLayoutProps extends Omit {\n /**\n * Sizes for each row of the layout.\n *\n *\n * `auto`: intrinsic size of the element.\n *\n * `fill`: fills the remaining available space. When multiple elements are set to `fill`, the remaining space is shared equally.\n *\n * `` `${number}%` ``: size in percentages.\n *\n * `` `${number}fr` ``: size in fractions.\n *\n * `number`: size in pixels.\n *\n *\n * - When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n *\n * - When the size of an element is not explicitly set, it will fill the remaining space available.\n *\n * - When only one size is set and outside of an array, all elements of the layout will take that size.\n *\n *\n * @defaultValue 'fill'\n */\n rows?: MaybeResponsiveConditionalStyle;\n}" }, - "ButtonAccessibilityRole": { + "ViewLikeAccessibilityRole": { "filePath": "src/surfaces/checkout/components/shared.ts", "syntaxKind": "TypeAliasDeclaration", - "name": "ButtonAccessibilityRole", - "value": "'button' | 'submit'", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", "description": "" }, - "Appearance": { + "NonPresentationalAccessibilityRole": { "filePath": "src/surfaces/checkout/components/shared.ts", "syntaxKind": "TypeAliasDeclaration", - "name": "Appearance", - "value": "'base' | 'accent' | 'decorative' | 'interactive' | 'subdued' | 'info' | 'success' | 'warning' | 'critical' | 'monochrome'", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", "description": "" - } - } - } - ], - "category": "components", - "defaultExample": { - "image": "menu-default.png", - "altText": "An example of a Menu with three actions.", - "codeblock": { - "title": "Basic Menu", - "tabs": [ - { - "title": "React", - "code": "import {\n reactExtension,\n Button,\n Menu,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <Button\n overlay={\n <Menu>\n <Button\n onPress={() =>\n console.log('Submit problem')\n }\n >\n Submit problem\n </Button>\n <Button to=\"https://shopify.com\">\n Request return\n </Button>\n <Button appearance=\"critical\">\n Cancel order\n </Button>\n </Menu>\n }\n >\n Manage\n </Button>\n );\n}\n", - "language": "tsx" }, - { - "title": "JS", - "code": "import {Menu, Button, extension} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root, api) => {\n renderApp(root, api);\n});\n\nasync function renderApp(root, api) {\n const menuFragment = root.createFragment();\n const menu = root.createComponent(Menu, {}, [\n root.createComponent(\n Button,\n {onPress: () => console.log('Submit problem')},\n 'Submit problem',\n ),\n root.createComponent(Button, {to: 'https://shopify.com'}, 'Request return'),\n root.createComponent(Button, {appearance: 'critical'}, 'Cancel order'),\n ]);\n menuFragment.appendChild(menu);\n const button = root.createComponent(\n Button,\n {overlay: menuFragment},\n 'Manage',\n );\n\n root.appendChild(button);\n}\n", - "language": "js" - } - ] - } - }, - "subSections": [ - { - "type": "Generic", - "anchorLink": "best-practices", - "title": "Best Practices", - "sectionContent": "\n### Consolidate actions into one menu\n\n- Use the menu component in the upper-right corner of full-page extensions, to be consistent with the **Order status** page.\n- Use menus to consolidate page-level actions, instead of adding multiple buttons around the page.\n\n![The “Don’t do” example shows 3 separate action buttons on a subscription page. The “Do” example shows the same 3 actions consolidated into one menu.](/assets/templated-apis-screenshots/customer-account-ui-extensions/unstable/menu-dont-do.png)\n\n### Content guidelines\n\nWhen writing button labels:\n- Aim for 2 words (verb and noun).\n- Lead with a strong verb that encourages action.\n- Avoid unnecessary words and articles such as “the,” “an,” or “a.”\n- Use sentence case.\n\n![A button that follows the content guidelines says “Skip order”. A button that does not meet the content guidelines says “Skip this order”.](/assets/templated-apis-screenshots/customer-account-ui-extensions/unstable/menu-labels.png)\n" - } - ], - "related": [ - { - "name": "Popover", - "subtitle": "Component", - "url": "../../../checkout-ui-extensions/unstable/components/overlays/popover", - "type": "Component" - } - ] - }, - { - "name": "Page", - "description": "The outer wrapper of the page—including the page title, subtitle, and page-level actions—displayed in a familiar and consistent style that sets expectations about the purpose of the page.", - "thumbnail": "page-thumbnail.png", - "requires": "", - "isVisualComponent": true, - "type": "", - "definitions": [ - { - "title": "PageProps", - "description": "", - "type": "PageProps", - "typeDefinitions": { - "PageProps": { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", - "name": "PageProps", + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Indicates that the page is in a loading state.\n\nWhen `true`, the page shows loading indicators for the UI elements that it is owns. The page is not responsible for the loading indicators of any content that is passed as `children`.", - "isOptional": true, - "defaultValue": "false" + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." }, { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "primaryAction", - "value": "RemoteFragment", - "description": "The action grouping, provided as button(s), that is placed in the primary position of the page.", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", "isOptional": true - }, + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "primaryActionAccessibilityLabel", - "value": "string", - "description": "Accessibility label for the primary action grouping. If an accessibility label is not provided, default text is used.", - "isOptional": true, - "defaultValue": "\"More actions\"" + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." }, { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "primaryActionLabel", - "value": "string", - "description": "Label for the primary action grouping. If a label is not provided, default text is used.", - "isOptional": true, - "defaultValue": "\"More actions\"" - }, + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "secondaryAction", - "value": "RemoteFragment", - "description": "The action grouping, provided as button(s), that is placed in the secondary position of the page.", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + }, + "Rows": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Rows", + "value": "GridItemSize[] | GridItemSize", + "description": "" + }, + "GridItemSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "GridItemSize", + "value": "'auto' | 'fill' | number | `${number}fr` | `${number}%`", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "blocklayout-default.png", + "codeblock": { + "title": "Basic BlockLayout", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n BlockLayout,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <BlockLayout rows={[60, 'fill']}>\n <View border=\"base\" padding=\"base\">\n 60\n </View>\n <View border=\"base\" padding=\"base\">\n fill\n </View>\n </BlockLayout>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, BlockLayout, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const blockLayout = root.createComponent(\n BlockLayout,\n {\n rows: [60, 'fill'],\n },\n [\n root.createComponent(View, {border: 'base', padding: 'base'}, '60'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'fill'),\n ],\n );\n\n root.appendChild(blockLayout);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "BlockSpacer", + "description": "BlockSpacer is used to create empty block space, typically when variable spacing is needed between multiple elements.\n\nNote that you should favor BlockStack when spacing between all elements is the same.", + "isVisualComponent": true, + "thumbnail": "blockspacer-thumbnail.png", + "requires": "", + "type": "", + "definitions": [ + { + "title": "BlockSpacerProps", + "description": "", + "type": "BlockSpacerProps", + "typeDefinitions": { + "BlockSpacerProps": { + "filePath": "src/surfaces/checkout/components/BlockSpacer/BlockSpacer.ts", + "name": "BlockSpacerProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/BlockSpacer/BlockSpacer.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/components/BlockSpacer/BlockSpacer.ts", "syntaxKind": "PropertySignature", - "name": "subtitle", - "value": "string", - "description": "The text to be used as subtitle.", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust size of the spacer", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface BlockSpacerProps extends IdProps {\n /**\n * Adjust size of the spacer\n *\n * @defaultValue 'base'\n **/\n spacing?: MaybeResponsiveConditionalStyle;\n}" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." }, { - "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "title", - "value": "string", - "description": "The text to be used as title." + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." } ], - "value": "export interface PageProps {\n /**\n * The text to be used as title.\n */\n title: string;\n\n /**\n * The text to be used as subtitle.\n */\n subtitle?: string;\n\n /**\n * The action grouping, provided as button(s), that is placed in the primary position of the page.\n */\n primaryAction?: RemoteFragment;\n\n /**\n * Label for the primary action grouping. If a label is not provided, default text is used.\n *\n * @defaultValue \"More actions\"\n */\n primaryActionLabel?: string;\n\n /**\n * Accessibility label for the primary action grouping. If an accessibility label is not provided,\n * default text is used.\n *\n * @defaultValue \"More actions\"\n */\n primaryActionAccessibilityLabel?: string;\n\n /**\n * The action grouping, provided as button(s), that is placed in the secondary position of the page.\n */\n secondaryAction?: RemoteFragment;\n\n /**\n * Indicates that the page is in a loading state.\n *\n * When `true`, the page shows loading indicators for the UI elements that it is owns.\n * The page is not responsible for the loading indicators of any content that is passed as `children`.\n *\n * @defaultValue false\n */\n loading?: boolean;\n}" + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" } } }, { - "title": "ButtonProps primaryAction", - "description": "Supported props for Buttons used inside Page `primaryAction` prop.

    `children` only support text.", - "type": "Docs_Page_Button_PrimaryAction", + "title": "StyleHelper", + "description": "Style is a helper for authoring conditional values for prop styles.\n\nWrite complex conditional styles based on one or more conditions, such as viewport sizes and interactive states, in a concise and expressive way.", + "type": "DocsStyle", "typeDefinitions": { - "Docs_Page_Button_PrimaryAction": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_Page_Button_PrimaryAction", + "DocsStyle": { + "filePath": "src/surfaces/checkout/style/style.ts", + "name": "DocsStyle", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/style.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", - "isOptional": true + "name": "default", + "value": "(defaultValue: T) => StylesConditionalStyle", + "description": "Sets an optional default value to use when no other condition is met." }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/style.ts", "syntaxKind": "PropertySignature", - "name": "disabled", - "value": "boolean", - "description": "Disables the button, disallowing any interaction.", - "isOptional": true, - "defaultValue": "false" + "name": "when", + "value": "(conditions: StylesConditions, value: T) => StylesConditionalStyle", + "description": "Adjusts the style based on different conditions. All conditions, expressed as a literal object, must be met for the associated value to be applied.\n\nThe `when` method can be chained together to build more complex styles." + } + ], + "value": "export interface DocsStyle {\n /**\n * Sets an optional default value to use when no other condition is met.\n *\n * @param defaultValue The default value\n * @returns The chainable condition style\n */\n default: (defaultValue: T) => StylesConditionalStyle;\n /**\n * Adjusts the style based on different conditions. All conditions, expressed\n * as a literal object, must be met for the associated value to be applied.\n *\n * The `when` method can be chained together to build more complex styles.\n *\n * @param conditions The condition(s)\n * @param value The conditional value that can be applied if the conditions are met\n * @returns The chainable condition style\n */\n when: (\n conditions: StylesConditions,\n value: T,\n ) => StylesConditionalStyle;\n}" + }, + "StylesConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "StylesConditionalValue[]", + "description": "An array of conditional values." }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Replaces content with a loading indicator.", - "isOptional": true, - "defaultValue": "false" + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface StylesConditionalStyle<\n T,\n AcceptedConditions extends StylesBaseConditions = StylesBaseConditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: StylesConditionalValue[];\n}" + }, + "StylesConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "loadingLabel", - "value": "string", - "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface StylesConditionalValue<\n T,\n AcceptedConditions extends StylesBaseConditions = StylesBaseConditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "StylesBaseConditions": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesBaseConditions", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "focus", + "value": "true", + "description": "", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "hover", + "value": "true", + "description": "", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "overlay", - "value": "RemoteFragment", - "description": "An overlay component to render when the user interacts with the component.", + "name": "resolution", + "value": "1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4", + "description": "", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "to", - "value": "string", - "description": "Destination URL to link to.", + "name": "viewportInlineSize", + "value": "{ min: ViewportInlineSize; }", + "description": "", "isOptional": true } ], - "value": "export interface Docs_Page_Button_PrimaryAction\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'overlay'\n | 'to'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n > {}" - } - } - }, - { - "title": "ButtonProps secondaryAction", - "description": "Supported props for Button used inside Page `secondaryAction` prop.

    `children` are not supported.
    Use `accessibilityLabel` instead.", - "type": "Docs_Page_Button_SecondaryAction", - "typeDefinitions": { - "Docs_Page_Button_SecondaryAction": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_Page_Button_SecondaryAction", + "value": "export interface StylesBaseConditions {\n viewportInlineSize?: {min: ViewportInlineSize};\n hover?: true;\n focus?: true;\n resolution?: 1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4;\n}" + }, + "ViewportInlineSize": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewportInlineSize", + "value": "'extraSmall' | 'small' | 'medium' | 'large'", + "description": "" + }, + "StylesConditions": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditions", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", - "value": "string", - "description": "A label used for buyers using assistive technologies. Needed because `children` passed to this component will be discarded." + "name": "focus", + "value": "true", + "description": "", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "hover", + "value": "true", + "description": "", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/style/types.ts", "syntaxKind": "PropertySignature", - "name": "to", - "value": "string", - "description": "Destination URL to link to.", + "name": "viewportInlineSize", + "value": "{ min: ViewportInlineSize; }", + "description": "", "isOptional": true } ], - "value": "export interface Docs_Page_Button_SecondaryAction\n extends Pick {\n /**\n * A label used for buyers using assistive technologies. Needed because `children` passed to this component will be discarded.\n */\n accessibilityLabel: ButtonProps['accessibilityLabel'];\n}" + "value": "export interface StylesConditions {\n viewportInlineSize?: {min: ViewportInlineSize};\n hover?: true;\n focus?: true;\n}" } } } ], - "category": "components", + "category": "UI components", + "subCategory": "Layout and structure", "defaultExample": { - "image": "page-preview.png", - "altText": "An example of how the Page component is used to structure the page title, description, order action buttons on the Order status page.", + "image": "blockspacer-default.png", "codeblock": { - "title": "Basic Page", + "title": "Basic BlockSpacer", "tabs": [ { "title": "React", - "code": "import {\n Page,\n Button,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension('customer-account.page.render', () => <App />);\n\nfunction App() {\n return (\n <Page\n title=\"Order #1411\"\n subtitle=\"Confirmed Oct 5\"\n secondaryAction={<Button accessibilityLabel=\"Button\" onPress={() => {}}/>}\n primaryActionLabel=\"Manage\"\n primaryAction={\n <>\n <Button onPress={() => {}}>Buy again</Button>\n <Button onPress={() => {}}>Second action</Button>\n <Button onPress={() => {}}>Third action</Button>\n </>\n }\n >\n Content\n </Page>\n );\n}\n", + "code": "import {\n reactExtension,\n BlockSpacer,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <BlockSpacer spacing=\"loose\" />\n <View border=\"base\" padding=\"base\">\n View\n </View>\n </>\n );\n}\n", "language": "tsx" }, { "title": "JS", - "code": "import {\n Page,\n Button,\n extension\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nasync function renderApp(root, api) {\n const primaryAction = root.createFragment();\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 1\")}}, 'Buy again primary 1'));\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 2\")}}, 'Buy again primary 2'));\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 3\")}}, 'Buy again primary 3'));\n\n const secondaryAction = root.createFragment();\n await secondaryAction.append(root.createComponent(Button, {accessibilityLabel: 'Button', onPress: () => {}}))\n\n const page = root.createComponent(\n Page,\n {\n title: \"Order #1411\",\n subtitle: \"Confirmed Oct 5\",\n primaryAction,\n primaryActionLabel: \"Manage\",\n secondaryAction,\n },\n root.createComponent('View', {}, \"Content\")\n )\n root.append(page);\n}\n", + "code": "import {extension, BlockSpacer, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const blockSpacer = root.createComponent(View, undefined, [\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(BlockSpacer, {spacing: 'loose'}),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n ]);\n\n root.appendChild(blockSpacer);\n});\n", "language": "js" } ] } }, - "subSections": [ - { - "type": "Generic", - "anchorLink": "best-practices", - "title": "Best Practices", - "sectionContent": "\n**Title**\n- Set clear expectations about the purpose and main topic of the page.\n- Aim for 1-3 words.\n- Use sentence case.\n\n**Subtitle**\n- Use to provide additional context or information that enhances the customer’s understanding of the page.\n- Use subtitles sparingly and only when they add useful information that is distinct from the title.\n\n**Buttons**\n- Use for page-level actions only.\n- If there is a single primary action for the page, display it as a primary button. Display all other page-level actions as secondary buttons.\n- See [UX guidelines](/docs/apps/customer-accounts/order-action-menu-extensions/ux-guidelines) to learn more about the button logic for order actions.\n" - } - ], "related": [] }, { - "name": "ResourceItem", - "description": "Use to represent a specific object within a collection, that a customer can take action on. For example, a list of active subscriptions or redeemable offers, in a style consistent with the order index page.", - "thumbnail": "resourceitem-thumbnail.png", + "name": "BlockStack", + "description": "BlockStack is used to vertically stack elements.", + "thumbnail": "blockstack-thumbnail.png", "requires": "", "isVisualComponent": true, "type": "", "definitions": [ { - "title": "ResourceItemProps", + "title": "BlockStackProps", "description": "", - "type": "ResourceItemProps", + "type": "BlockStackProps", "typeDefinitions": { - "ResourceItemProps": { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", - "name": "ResourceItemProps", + "BlockStackProps": { + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", + "name": "BlockStackProps", "description": "", "members": [ { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", "name": "accessibilityLabel", "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "action", - "value": "RemoteFragment", - "description": "The action grouping for the item, provided as buttons.", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "actionAccessibilityLabel", - "value": "string", - "description": "Accessibility label for the action grouping. If an accessibility label is not provided, default text is used.", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", "isOptional": true, - "defaultValue": "\"More actions\"" + "defaultValue": "'transparent'" }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "actionLabel", - "value": "string", - "description": "Label for the action grouping. If a label is not provided, default text is used.", - "isOptional": true, - "defaultValue": "\"More actions\"" + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Indicates that the item is in a loading state.\n\nWhen `true`, the item shows loading indicators for the UI elements that it is owns. The item is not responsible for the loading indicators of any content that is passed as `children`.", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", "isOptional": true, - "defaultValue": "false" + "isPrivate": true }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback when pressed. If `to` is set, it will execute the callback and then navigate to the location specified by `to`.", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "to", - "value": "string", - "description": "Destination to navigate to. You must provide either this property, `onPress`, or both.", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", "isOptional": true - } - ], - "value": "export interface ResourceItemProps\n extends Pick {\n /**\n * The action grouping for the item, provided as buttons.\n */\n action?: RemoteFragment;\n\n /**\n * Label for the action grouping. If a label is not provided, default text is used.\n *\n * @defaultValue \"More actions\"\n */\n actionLabel?: string;\n\n /**\n * Accessibility label for the action grouping. If an accessibility label is not provided,\n * default text is used.\n *\n * @defaultValue \"More actions\"\n */\n actionAccessibilityLabel?: string;\n\n /**\n * Indicates that the item is in a loading state.\n *\n * When `true`, the item shows loading indicators for the UI elements that it is owns.\n * The item is not responsible for the loading indicators of any content that is passed as `children`.\n *\n * @defaultValue false\n */\n loading?: boolean;\n}" - } - } - }, - { - "title": "ButtonProps action", - "description": "Supported props for Buttons used inside ResourceItem `action` prop.

    `children` only support text.", - "type": "Docs_ResourceItem_Button_Action", - "typeDefinitions": { - "Docs_ResourceItem_Button_Action": { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "name": "Docs_ResourceItem_Button_Action", - "description": "", - "members": [ + }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "accessibilityLabel", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", + "syntaxKind": "PropertySignature", + "name": "id", "value": "string", - "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "description": "A unique identifier for the component.", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "disabled", - "value": "boolean", - "description": "Disables the button, disallowing any interaction.", - "isOptional": true, - "defaultValue": "false" + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "kind", - "value": "'primary' | 'secondary' | 'plain'", - "description": "The type of button that will be rendered. The visual presentation of the button type is controlled by merchants through the Branding API.\n\n\n`primary`: button used for main actions. For example: \"Continue to next step\".\n\n`secondary`: button used for secondary actions not blocking user progress. For example: \"Download Shop app\".\n\n`plain`: renders a button that visually looks like a link.", - "isOptional": true, - "defaultValue": "'primary'" + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "loading", - "value": "boolean", - "description": "Replaces content with a loading indicator.", - "isOptional": true, - "defaultValue": "false" + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "loadingLabel", - "value": "string", - "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", - "syntaxKind": "MethodSignature", - "name": "onPress", - "value": "() => void", - "description": "Callback that is run when the button is pressed.", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "overlay", - "value": "RemoteFragment", - "description": "An overlay component to render when the user interacts with the component.", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", "isOptional": true }, { - "filePath": "src/surfaces/customer-account/api/docs.ts", + "filePath": "src/surfaces/checkout/components/BlockStack/BlockStack.ts", "syntaxKind": "PropertySignature", - "name": "to", - "value": "string", - "description": "Destination URL to link to.", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between children", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface BlockStackProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n SizingProps,\n SpacingProps {\n /**\n * Position children along the main axis\n */\n inlineAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Adjust spacing between children\n *\n * @defaultValue 'base'\n */\n spacing?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n *\n *\n * For example:\n *\n * - In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n *\n * - In an HTML host a `listItem` string will render: `
  • `\n */\n accessibilityRole?: ViewLikeAccessibilityRole;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n /**\n * Changes the display of the component.\n *\n * `auto` the component's initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle<'auto' | 'none'>;\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", "isOptional": true } ], - "value": "export interface Docs_ResourceItem_Button_Action\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'overlay'\n | 'to'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n | 'kind'\n > {}" + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" } } } ], - "category": "components", + "category": "UI components", + "subCategory": "Layout and structure", "defaultExample": { - "image": "resourceitem-preview.png", - "altText": "An example of how the ResourceItem component is used to represent one order in the grid view of the Order index page.", + "image": "blockstack-default.png", "codeblock": { - "title": "ResourceItem", + "title": "Basic BlockStack", "tabs": [ { "title": "React", - "code": "import {\n ResourceItem,\n Button,\n Text,\n View,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <View maxInlineSize={300}>\n <ResourceItem\n accessibilityLabel=\"Resource Item\"\n onPress={() => {}}\n actionLabel=\"Manage\"\n action={\n <>\n <Button\n kind=\"primary\"\n onPress={() => {}}\n >\n Pay now\n </Button>\n <Button onPress={() => {}}>\n Second action\n </Button>\n <Button onPress={() => {}}>\n Third action\n </Button>\n </>\n }\n >\n Resource item content\n </ResourceItem>\n </View>\n );\n}\n", + "code": "import {\n reactExtension,\n BlockStack,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <BlockStack>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n </BlockStack>\n );\n}\n", "language": "tsx" }, { "title": "JS", - "code": "import {\n ResourceItem,\n Button,\n View,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n\n const actionFragment = root.createFragment();\n\n const primaryButton = root.createComponent(Button, {\n kind: 'primary',\n onPress: () => {},\n });\n\n primaryButton.append(root.createText('Pay now'))\n\n const secondButton = root.createComponent(Button, {\n kind: 'secondary',\n onPress: () => {},\n });\n\n secondButton.append(root.createText('Second button'))\n\n const thirdButton = root.createComponent(Button, {\n kind: 'secondary',\n onPress: () => {},\n });\n\n thirdButton.append(root.createText('Third button'))\n\n actionFragment.append(primaryButton);\n actionFragment.append(secondButton);\n actionFragment.append(thirdButton);\n\n const resourceItem = root.createComponent(\n ResourceItem,\n {\n accessibilityLabel: 'Resource Item',\n onPress: () => {},\n actionLabel: 'Manage',\n action: actionFragment,\n },\n 'Content',\n );\n\n const view = root.createComponent(View, {maxInlineSize: 300});\n view.append(resourceItem);\n\n root.append(view);\n}\n", + "code": "import {extension, BlockStack, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const blockStack = root.createComponent(BlockStack, undefined, [\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n ]);\n\n root.appendChild(blockStack);\n});\n", "language": "js" } ] } }, + "examples": { + "description": "", + "examples": [ + { + "description": "Use the Disclosure component to simplify the user experience and reveal interfaces only when the customer requests it. It also demonstrates how a combination of inline and block layout components can improve the readability of information. By employing these strategies, users can easily scan and comprehend the content, making for a better user experience overall.", + "image": "disclosure-and-alignment.gif", + "codeblock": { + "title": "Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.", + "tabs": [ + { + "code": "import {\n reactExtension,\n View,\n Image,\n Icon,\n Pressable,\n Disclosure,\n InlineLayout,\n BlockStack,\n Text,\n Form,\n TextField,\n Button,\n Divider,\n InlineStack,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <DisclosureAndAlignment />,\n);\n\nexport const DisclosureAndAlignment = () => {\n const openIds = ['one'];\n return (\n <View\n maxInlineSize={400}\n cornerRadius=\"large\"\n border=\"base\"\n >\n <BlockStack spacing=\"none\">\n <Disclosure\n defaultOpen=\"one\"\n onToggle={(open) =>\n console.log('onToggle event', open)\n }\n >\n <Pressable toggles=\"one\" padding=\"base\">\n <InlineLayout\n blockAlignment=\"center\"\n spacing=\"base\"\n columns={['auto', 'fill', 'auto']}\n >\n <Icon\n source=\"gift\"\n appearance=\"subdued\"\n />\n Gift message\n <Icon\n source={\n openIds.includes('one')\n ? 'chevronUp'\n : 'chevronDown'\n }\n appearance=\"subdued\"\n />\n </InlineLayout>\n </Pressable>\n <View\n id=\"one\"\n padding={[\n 'none',\n 'base',\n 'base',\n 'base',\n ]}\n >\n <Form\n onSubmit={() =>\n console.log('onSubmit event')\n }\n >\n <BlockStack>\n <InlineLayout\n columns={['fill', 'fill']}\n spacing=\"base\"\n >\n <TextField\n label=\"From\"\n name=\"from0\"\n id=\"from0\"\n />\n <TextField\n label=\"To\"\n name=\"to0\"\n id=\"to0\"\n />\n </InlineLayout>\n <TextField\n label=\"Message\"\n name=\"message0\"\n id=\"message0\"\n />\n <View>\n <Button\n accessibilityRole=\"submit\"\n kind=\"secondary\"\n >\n Save\n </Button>\n </View>\n </BlockStack>\n </Form>\n </View>\n </Disclosure>\n <Divider />\n <InlineLayout\n blockAlignment=\"baseline\"\n spacing=\"base\"\n columns={['auto', 'fill', 'auto']}\n padding=\"base\"\n >\n <Icon\n source=\"profile\"\n appearance=\"subdued\"\n />\n <BlockStack spacing=\"none\">\n <InlineStack blockAlignment=\"center\">\n <Text>Verify with</Text>\n <Image source=\"https://via.placeholder.com/50x15\" />\n </InlineStack>\n <Text\n appearance=\"subdued\"\n size=\"small\"\n >\n 15% savings for students and\n military\n </Text>\n </BlockStack>\n <Pressable to=\"https://www.shopify.com\">\n <Icon\n source=\"external\"\n appearance=\"subdued\"\n />\n </Pressable>\n </InlineLayout>\n </BlockStack>\n </View>\n );\n};\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n View,\n InlineLayout,\n InlineStack,\n Image,\n Pressable,\n Icon,\n Text,\n TextField,\n Form,\n Button,\n Disclosure,\n Divider,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const openIds = ['one'];\n\n const pressable = root.createComponent(\n Pressable,\n {\n toggles: 'one',\n padding: 'base',\n },\n [\n root.createComponent(\n InlineLayout,\n {\n blockAlignment: 'center',\n spacing: 'base',\n columns: ['auto', 'fill', 'auto'],\n },\n [\n root.createComponent(Icon, {\n source: 'gift',\n appearance: 'subdued',\n }),\n 'Gift message',\n root.createComponent(Icon, {\n source: openIds.includes('one')\n ? 'chevronUp'\n : 'chevronDown',\n size: 'small',\n }),\n ],\n ),\n ],\n );\n\n const disclosureView = root.createComponent(\n View,\n {\n id: 'one',\n padding: ['none', 'base', 'base', 'base'],\n },\n [\n root.createComponent(\n Form,\n {\n onSubmit: () =>\n console.log('onSubmit event'),\n },\n [\n root.createComponent(BlockStack, {}, [\n root.createComponent(\n InlineLayout,\n {\n columns: ['fill', 'fill'],\n spacing: 'base',\n },\n [\n root.createComponent(\n TextField,\n {\n label: 'From',\n name: 'from0',\n id: 'from0',\n },\n ),\n root.createComponent(\n TextField,\n {\n label: 'To',\n name: 'to0',\n id: 'to0',\n },\n ),\n ],\n ),\n root.createComponent(TextField, {\n label: 'Message',\n name: 'message0',\n id: 'message0',\n }),\n root.createComponent(View, {}, [\n root.createComponent(\n Button,\n {\n accessibilityRole: 'submit',\n kind: 'secondary',\n },\n 'Save',\n ),\n ]),\n ]),\n ],\n ),\n ],\n );\n\n const disclosure = root.createComponent(\n Disclosure,\n {\n defaultOpen: 'one',\n onToggle: (open) =>\n console.log('onToggle event', open),\n },\n [pressable, disclosureView],\n );\n\n const inlineLayout = root.createComponent(\n InlineLayout,\n {\n blockAlignment: 'baseline',\n spacing: 'base',\n columns: ['auto', 'fill', 'auto'],\n padding: 'base',\n },\n [\n root.createComponent(Icon, {\n source: 'profile',\n appearance: 'subdued',\n }),\n root.createComponent(\n BlockStack,\n {\n spacing: 'none',\n },\n [\n root.createComponent(\n InlineStack,\n {\n blockAlignment: 'center',\n },\n [\n root.createComponent(\n Text,\n {},\n 'Verify with',\n ),\n root.createComponent(Image, {\n source:\n 'https://via.placeholder.com/50x15',\n }),\n ],\n ),\n root.createComponent(\n Text,\n {\n appearance: 'subdued',\n size: 'small',\n },\n '15% savings for students and military',\n ),\n ],\n ),\n root.createComponent(\n Pressable,\n {\n to: 'https://www.shopify.com',\n },\n [\n root.createComponent(Icon, {\n source: 'external',\n appearance: 'subdued',\n }),\n ],\n ),\n ],\n );\n const view = root.createComponent(\n View,\n {\n maxInlineSize: 400,\n cornerRadius: 'large',\n border: 'base',\n },\n [\n root.createComponent(\n BlockStack,\n {\n spacing: 'none',\n },\n [\n disclosure,\n root.createComponent(Divider),\n inlineLayout,\n ],\n ),\n ],\n );\n\n root.appendChild(view);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, "subSections": [ { "type": "Generic", - "anchorLink": "best-practices", - "title": "Best Practices", - "sectionContent": "\n- Group related information.\n- Structure your content so it’s easy for customers to scan to the most important information.\n- Use images to complement text content.\n- If there is a single primary action for the object, display it as a primary button. Display other object-level actions as secondary buttons.\n- See [UX guidelines](/docs/apps/customer-accounts/order-action-menu-extensions/ux-guidelines) to learn more about the button logic for order actions.\n" + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" } ], - "related": [] + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "Button", + "description": "Buttons are used for actions, such as “Add”, “Continue”, “Pay now”, or “Save”.", + "thumbnail": "button-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ButtonProps", + "description": "", + "type": "ButtonProps", + "typeDefinitions": { + "ButtonProps": { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "name": "ButtonProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ButtonAccessibilityRole", + "description": "The role of the button that will be rendered.\n\n`button`: renders a regular button.\n\n`submit`: renders a button that submits a form.", + "isOptional": true, + "defaultValue": "'button'" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "activateAction", + "value": "'auto' | 'copy'", + "description": "Sets the action the `activateTarget` should take when this pressable is activated.\n\nSupported actions by component:\n\n| Component | Supported Actions | Default ('auto') |\n|---------------|-------------------|-------------------|\n| [`ClipboardItem`](/docs/api/checkout-ui-extensions/latest/clipboarditem) | 'copy' | 'copy' |", + "isOptional": true, + "defaultValue": "'auto' - a default action for the target component." + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "activateTarget", + "value": "string", + "description": "ID of a component that should respond to activations (e.g. clicks) on this pressable.\n\nSee `activateAction` for how to control the behavior of the target.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'critical' | 'monochrome'", + "description": "Specify the color treatment of the Button.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "InlineAlignment", + "description": "Specifies the inline alignment of the content.", + "isOptional": true, + "defaultValue": "'center'" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "kind", + "value": "'primary' | 'secondary' | 'plain'", + "description": "The type of button that will be rendered. The visual presentation of the button type is controlled by merchants through the Branding API.\n\n\n`primary`: button used for main actions. For example: \"Continue to next step\".\n\n`secondary`: button used for secondary actions not blocking user progress. For example: \"Download Shop app\".\n\n`plain`: renders a button that visually looks like a link.", + "isOptional": true, + "defaultValue": "'primary'" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Replaces content with a loading indicator.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "loadingLabel", + "value": "string", + "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "submit", + "value": "boolean", + "description": "Allows the button to submit a form.", + "isOptional": true, + "deprecationMessage": "use `accessibilityRole=\"submit\"` instead" + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Button/Button.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + } + ], + "value": "export interface ButtonProps\n extends OverlayActivatorProps,\n DisclosureActivatorProps,\n InteractionProps,\n IdProps {\n /**\n * The type of button that will be rendered. The visual presentation of the button type\n * is controlled by merchants through the Branding API.\n *\n *\n * `primary`: button used for main actions. For example: \"Continue to next step\".\n *\n * `secondary`: button used for secondary actions not blocking user progress. For example: \"Download Shop app\".\n *\n * `plain`: renders a button that visually looks like a link.\n *\n *\n * @defaultValue 'primary'\n */\n kind?: 'primary' | 'secondary' | 'plain';\n /**\n * Specify the color treatment of the Button.\n */\n appearance?: Extract;\n /**\n * Allows the button to submit a form.\n * @deprecated use `accessibilityRole=\"submit\"` instead\n */\n submit?: boolean;\n /**\n * Destination URL to link to.\n */\n to?: string;\n /**\n * Specifies the inline alignment of the content.\n *\n * @defaultValue 'center'\n */\n inlineAlignment?: InlineAlignment;\n /**\n * Replaces content with a loading indicator.\n *\n * @defaultValue false\n */\n loading?: boolean;\n /**\n * Accessible label for the loading indicator when user prefers reduced motion. This value is\n * only used if `loading` is true.\n */\n loadingLabel?: string;\n /**\n * A label used for buyers using assistive technologies. When set, any\n * `children` supplied to this component will not be announced to screen reader users.\n */\n accessibilityLabel?: string;\n /**\n * The role of the button that will be rendered.\n *\n * `button`: renders a regular button.\n *\n * `submit`: renders a button that submits a form.\n *\n * @defaultValue 'button'\n */\n accessibilityRole?: ButtonAccessibilityRole;\n /**\n * Disables the button, disallowing any interaction.\n *\n * @defaultValue false\n */\n disabled?: boolean;\n /**\n * Callback that is run when the button is pressed.\n */\n onPress?(): void;\n}" + }, + "ButtonAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ButtonAccessibilityRole", + "value": "'button' | 'submit'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Actions", + "defaultExample": { + "image": "button-default.png", + "codeblock": { + "title": "Basic Button", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Button,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Button\n onPress={() => {\n console.log('onPress event');\n }}\n >\n Pay now\n </Button>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Button} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const button = root.createComponent(\n Button,\n {onPress: () => console.log('onPress event')},\n 'Pay now',\n );\n\n root.appendChild(button);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"critical\" | Conveys a problem has arisen. |\n| \"monochrome\" | Takes the color of its parent.|" + }, + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "**Content Best Practices**\n\n- Clearly label each button to accurately represent the action associated with it.\n\n- Use strong actionable verbs at the beginning of button text to make it clear to the user what action will occur when the button is clicked.\n\n**Hierarchy Best Practices**\n\n- Establish a visual hierarchy between buttons to minimize confusion and help users understand which actions are most important.\n\n- Use only one high-emphasis button (primary button) per context to make it clear that other buttons have less importance.\n\n- Use lower-emphasis buttons for secondary calls to action.\n\n- Use primary buttons for actions that progress users through checkout such as “Pay now” or for concluding an action in a modal such as “Apply”.\n\n- Use secondary buttons to provide alternative actions to the primary button, without disrupting the primary flow such as “Track your order”.\n\n- Use plain buttons for least prominent, non-critical actions such as “Login to your account”.\n\n**When to Use Buttons**\n\n- Use buttons to communicate actions the user can take.\n\n- Use buttons to allow users to interact with the page.\n\n**When Not to Use Buttons**\n\n- Don’t use buttons as navigational elements. Use links instead when the desired action is to take the user to a new page." + } + ], + "related": [ + { + "name": "Link", + "subtitle": "Component", + "url": "link", + "type": "Component" + } + ] + }, + { + "name": "Card", + "description": "Group related content and functionality together in a familiar and consistent style, for customers to scan, read, and get things done.", + "thumbnail": "card-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "CardProps", + "description": "", + "type": "CardProps", + "typeDefinitions": { + "CardProps": { + "filePath": "src/surfaces/customer-account/components/Card/Card.ts", + "name": "CardProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/components/Card/Card.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "boolean", + "description": "Adjust the padding of all edges.\n\n`true` applies a default padding that is appropriate for the component.", + "isOptional": true + } + ], + "value": "export interface CardProps {\n /**\n * Adjust the padding of all edges.\n *\n * `true` applies a default padding that is appropriate for the component.\n */\n padding?: boolean;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "card-preview.png", + "altText": "An example of the card component shows a header that says \"Addresses\", and a button in the upper-right corner that says \"+Add\". Under the header, there is a full mailing address labeled as the default address, with a pencil icon for editing it.", + "codeblock": { + "title": "Basic Card", + "tabs": [ + { + "title": "React", + "code": "import {\n Card,\n Grid,\n BlockStack,\n Heading,\n Text,\n TextBlock,\n View,\n Icon,\n InlineLayout,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <Card padding>\n <Grid\n columns={['fill', 'auto']}\n spacing=\"base\"\n minInlineSize=\"fill\"\n blockAlignment=\"start\"\n >\n <BlockStack spacing=\"loose\">\n <Heading>Addresses</Heading>\n <BlockStack spacing=\"base\">\n <Text appearance=\"subdued\">\n Default address\n </Text>\n <BlockStack spacing=\"extraTight\">\n <TextBlock>\n Kristin Watson\n </TextBlock>\n <TextBlock>\n 1655 Island Pkwy\n </TextBlock>\n <TextBlock>\n Kamloops BC M7G 672\n </TextBlock>\n <TextBlock>Canada</TextBlock>\n </BlockStack>\n </BlockStack>\n </BlockStack>\n <BlockStack spacing=\"loose\">\n <InlineLayout blockAlignment=\"center\">\n <Icon\n source=\"plus\"\n size=\"small\"\n appearance=\"accent\"\n />\n <Text appearance=\"accent\">Add</Text>\n </InlineLayout>\n <View inlineAlignment=\"end\">\n <Icon\n source=\"pen\"\n size=\"small\"\n appearance=\"accent\"\n />\n </View>\n </BlockStack>\n </Grid>\n </Card>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n Card,\n Grid,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n const card = root.createComponent(\n Card,\n {padding: true},\n [\n root.createComponent(Grid, {columns: ['1fr', 'auto'],\n spacing: \"base\",\n minInlineSize: \"fill\",\n blockAlignment: \"start\"}, [\n root.createComponent('BlockStack', {spacing: 'loose'}, [\n root.createComponent('Heading', undefined, 'Addresses'),\n root.createComponent('BlockStack', {spacing: 'base'}, [\n root.createComponent('Text', {appearance: \"subdued\"}, 'Default address'),\n root.createComponent('BlockStack', {spacing: 'extraTight'}, [\n root.createComponent('TextBlock',{}, 'Kristin Watson'),\n root.createComponent('TextBlock', {}, '1655 Island Pkwy'),\n root.createComponent('TextBlock', {}, 'Kamloops BC M7G 672'),\n root.createComponent('TextBlock', {}, 'Canada'),\n ]),\n ]),\n ]),\n root.createComponent('BlockStack', {spacing: 'loose'}, [\n root.createComponent('InlineLayout', {blockAlignment: \"center\"}, [\n root.createComponent('Icon', {source: \"plus\", size: \"small\", appearance: \"accent\"}),\n root.createComponent('Text', {appearance: \"accent\"}, 'Add'),\n ]),\n root.createComponent('View', {inlineAlignment: \"end\"}, [\n root.createComponent('Icon', {source: \"pen\", size: \"small\", appearance: \"accent\"}),\n ]),\n ]),\n ]),\n ])\n root.append(card);\n}\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n- Group related information.\n- Use headings that set clear expectations about the card’s purpose.\n- Display information in a way that emphasizes and prioritizes what the customer needs to know first.\n" + } + ], + "related": [] + }, + { + "name": "Chat", + "description": "\nUse the Chat component to create real-time chat applications.\n", + "thumbnail": "chat-thumbnail.png", + "requires": "access to the **Chat in checkout extensions** scope. Request access in the Partner Dashboard.", + "isVisualComponent": true, + "type": "component", + "definitions": [ + { + "title": "ChatProps", + "description": "", + "type": "ChatProps", + "typeDefinitions": { + "ChatProps": { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "name": "ChatProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the component. When set, it will be announced to users using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "blockSize", + "value": "number", + "description": "Adjust the block size.\n\nCheckout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set may not be the actual size rendered.\n\n`number`: size in pixels.\n\nLearn more about [block size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "inlineSize", + "value": "number", + "description": "Adjust the inline size.\n\nCheckout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set may not be the actual size rendered.\n\n`number`: size in pixels.\n\nLearn more about [inline size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "onMessage", + "value": "(event: MessageEvent) => void", + "description": "Callback when the embedded page sends a message.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "onReady", + "value": "(event: ReadyEvent) => void", + "description": "Callback when the embedded page is ready and a message port has been created to communicate with the host page.", + "isOptional": true + } + ], + "value": "export interface ChatProps extends IdProps {\n /**\n * Adjust the inline size.\n *\n * Checkout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set\n * may not be the actual size rendered.\n *\n * `number`: size in pixels.\n *\n * Learn more about [inline size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/inline-size).\n */\n inlineSize?: number;\n\n /**\n * Adjust the block size.\n *\n * Checkout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set\n * may not be the actual size rendered.\n *\n * `number`: size in pixels.\n *\n * Learn more about [block size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/block-size).\n */\n blockSize?: number;\n\n /**\n * A label that describes the purpose or contents of the component. When set,\n * it will be announced to users using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n\n /**\n * Callback when the embedded page sends a message.\n */\n onMessage?: (event: MessageEvent) => void;\n\n /**\n * Callback when the embedded page is ready and a message port has been created to\n * communicate with the host page.\n */\n onReady?: (event: ReadyEvent) => void;\n}" + }, + "MessageEvent": { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "name": "MessageEvent", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "data", + "value": "any", + "description": "The data sent by the message emitter (the embedded page).\n\nLearn more about [MessageEvent data on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "origin", + "value": "string", + "description": "A string representing the origin of the message emitter (the embedded page).\n\nLearn more about [MessageEvent origin on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/origin)." + } + ], + "value": "interface MessageEvent {\n /**\n * The data sent by the message emitter (the embedded page).\n *\n * Learn more about [MessageEvent data on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data).\n */\n data?: any;\n\n /**\n * A string representing the origin of the message emitter (the embedded page).\n *\n * Learn more about [MessageEvent origin on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/origin).\n */\n origin: string;\n}" + }, + "ReadyEvent": { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "name": "ReadyEvent", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/Chat.ts", + "syntaxKind": "PropertySignature", + "name": "postMessage", + "value": "(message: any) => void", + "description": "A function to send messages to the embedded page.\n\nLearn more about [postMessage on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage)." + } + ], + "value": "export interface ReadyEvent {\n /**\n * A function to send messages to the embedded page.\n *\n * Learn more about [postMessage on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage).\n */\n postMessage: (message: any) => void;\n}" + } + } + }, + { + "title": "App Bridge for checkout", + "description": "\nThe App Bridge script for checkout provides APIs that enables a secure communication channel between the Shopify checkout and the embedded application within the Chat iframe. It also offers convenient methods to perform common actions like resizing the iframe from within the application.\n\nAfter App Bridge is [set up](#about-app-bridge) in your app, you have access to the `shopify` global variable. This variable exposes the following App Bridge functionalities and configuration information:\n ", + "type": "AppBridge", + "typeDefinitions": { + "AppBridge": { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "name": "AppBridge", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "config", + "value": "Config", + "description": "The static configuration values that will not change during runtime.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "extension", + "value": "Extension", + "description": "The references and APIs to the UI extension that helped bootstrap the iframe.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "idToken", + "value": "() => Promise", + "description": "The ID token providing a set of claims as a signed [JSON Web Token (JWT)](https://openid.net/specs/openid-connect-core-1_0.html#IDToken%5C) with a TTL of 5 minutes. It can be used to ensure that requests came from a Shopify authenticated user. See the [ID Token documentation](/docs/apps/build/authentication-authorization/session-tokens) for more information.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "platform", + "value": "'browser' | 'shop-app' | 'pos'", + "description": "The platform or application that the app is embedded within.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "surface", + "value": "'checkout'", + "description": "The Shopify surface that the app is embedded within.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "visitor", + "value": "() => Promise", + "description": "Information about the current visitor.", + "isOptional": true + } + ], + "value": "interface AppBridge {\n /**\n * The static configuration values that will not change during runtime.\n */\n config?: Config;\n\n /**\n * The Shopify surface that the app is embedded within.\n */\n surface?: 'checkout';\n\n /**\n * The platform or application that the app is embedded within.\n */\n platform?: 'browser' | 'shop-app' | 'pos';\n\n /**\n * The ID token providing a set of claims as a signed [JSON Web Token (JWT)](https://openid.net/specs/openid-connect-core-1_0.html#IDToken%5C)\n * with a TTL of 5 minutes. It can be used to ensure that requests came from a Shopify authenticated user.\n * See the [ID Token documentation](/docs/apps/build/authentication-authorization/session-tokens) for more information.\n *\n * @see /docs/api/checkout-ui-extensions/latest/apis/session-token\n * @see /docs/apps/build/authentication-authorization/session-tokens\n */\n idToken?: () => Promise;\n\n /**\n * The references and APIs to the UI extension that helped bootstrap the iframe.\n */\n extension?: Extension;\n\n /**\n * Information about the current visitor.\n *\n * @ignore async via our RPC endpoints to ensure a secure handshake between\n * host and client is established.\n */\n visitor?: () => Promise;\n}" + }, + "Config": { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "name": "Config", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "locale", + "value": "string", + "description": "The locale of the shop that’s embedding the app.", + "isOptional": true + } + ], + "value": "interface Config {\n /**\n * The locale of the shop that’s embedding the app.\n */\n locale?: string;\n}" + }, + "Extension": { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "name": "Extension", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "handle", + "value": "string", + "description": "The unique handle name of the UI extension as defined by the developer.\n\nLearn more about [extension configuration](/docs/api/checkout-ui-extensions/latest/configuration#how-it-works).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "port", + "value": "MessagePort", + "description": "A MessagePort instance for communicating directly to and from the UI Extension that created the iframe. It will need to be started to begin receiving messages.\n\nLearn more about [MessagePort on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "resizeTo", + "value": "(width: number, height: number) => void", + "description": "Set an iframe’s size. Depending on the context, the host page may decide to apply or ignore the new sizes. For example, if the iframe is meant to fill its parent container the host would ignore the request. Conversely, if the parent container allows the iframe to fill it the host would apply the new size.\n\nAlias to `window.resizeTo()`, available here for feature discovery by the embedding app.\n\nLearn more about [resizeTo() on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo).", + "isOptional": true + } + ], + "value": "interface Extension {\n /**\n * The unique handle name of the UI extension as defined by the developer.\n *\n * Learn more about [extension configuration](/docs/api/checkout-ui-extensions/latest/configuration#how-it-works).\n */\n handle?: string;\n\n /**\n * A MessagePort instance for communicating directly to and from the UI\n * Extension that created the iframe. It will need to be started to begin\n * receiving messages.\n *\n * Learn more about [MessagePort on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort).\n */\n port?: MessagePort;\n\n /**\n * Set an iframe’s size. Depending on the context, the host page may decide\n * to apply or ignore the new sizes. For example, if the iframe is meant to\n * fill its parent container the host would ignore the request. Conversely,\n * if the parent container allows the iframe to fill it the host would\n * apply the new size.\n *\n * Alias to `window.resizeTo()`, available here for feature discovery by the\n * embedding app.\n *\n * Learn more about [resizeTo() on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo).\n */\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n resizeTo?: Window['resizeTo'];\n}" + }, + "Visitor": { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "name": "Visitor", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Chat/AppBridge.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "The unique token of a given user across all surfaces in a shop, present if processing permission is provided.", + "isOptional": true + } + ], + "value": "interface Visitor {\n /**\n * The unique token of a given user across all surfaces in a shop,\n * present if processing permission is provided.\n *\n * @ignore this maps to the _shopify_y cookie which Trekkie refers to as a\n * uniqToken.\n */\n id?: string;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Overlays", + "defaultExample": { + "image": "chat-component-minimized.png", + "codeblock": { + "title": "Basic Chat", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Chat,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\n// This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file.\n// Its value will be used as the `src` attribute of the Chat component.\n\nfunction Extension() {\n return <Chat inlineSize={100} blockSize={50} />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Chat} from '@shopify/ui-extensions/customer-account';\n\n// This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file.\n// Its value will be used as the `src` attribute of the Chat component.\n\nexport default extension('customer-account.page.render', (root) => {\n const chat = root.createComponent(Chat, {\n inlineSize: 100,\n blockSize: 50,\n });\n\n root.appendChild(chat);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "src-and-query-parameters", + "title": "Chat source and query parameters", + "sectionContent": "\nThe `src` of the iframe rendered by Chat is provided by the `preloads` `chat` key in the extension configuration file. Shopify automatically appends query parameters to the URL which allows developers to verify the authenticity of the request and the identity of the merchant. We guarantee these tokens are valid and signed by Shopify.\n\n#### id_token\nThe ID token providing a set of claims as a signed [JSON Web Token (JWT)](https://openid.net/specs/openid-connect-core-1_0.html#IDToken%5C) with a TTL of 5 minutes. It can be used to retrieve merchants information on the backend as well as ensure that requests came from a Shopify authenticated source. See the [ID Token documentation](/docs/apps/build/authentication-authorization/session-tokens) for more information.\n\n#### locale\nThe locale of the shop that's embedding the app, i.e. `en-CA`. This information is also available in the `shopify` global variable under `config`.\n\n#### handle\nThe unique handle name of the UI extension as defined by the developer. This information is also available in the `shopify` global variable under `extension`.\n", + "codeblock": { + "title": "Chat source", + "tabs": [ + { + "title": "shopify.extension.toml", + "code": "[[extensions.targeting]]\ntarget = \"purchase.checkout.chat.render\"\n\n [extensions.targeting.preloads]\n chat = \"https://my-chat-application.com\"\n", + "language": "toml" + } + ] + } + }, + { + "type": "Generic", + "anchorLink": "chat-dimensions", + "title": "Chat dimensions", + "image": "chat-component-iframe-clipping.png", + "sectionContent": "\nTo provide developers with the most flexibility when it comes to responsive changes, the iframe rendered in the page by `Chat` takes the full width and height of the browser window. Only a specific part of the iframe is visible, the rest is clipped.\n\nThe `inlineSize` and `blockSize` values set on the Chat component or changed through the App Bridge `resizeTo()` method dictates the bounding box of the visible part. That box is fixed and positioned in the bottom right corner of the iframe.\n\nYour application can rely on the window's dimension to change styles or apply specific behaviors to different window sizes. This allow developers to style their app as if as if the application would be outside an iframe. For example, CSS media queries can now work within the iframe.\n" + }, + { + "type": "Generic", + "anchorLink": "about-app-bridge", + "title": "Getting started with App Bridge for checkout", + "sectionContent": "\nYou must add App Bridge to your hosted chat application by including the script tag pointing to the `app-bridge-checkout.js` as the first script in the `` section as seen in the example. The script loads directly from Shopify and keeps itself up-to-date.\n ", + "codeblock": { + "title": "Hosted chat application", + "tabs": [ + { + "code": "<head>\n <script src=\"https://cdn.shopify.com/shopifycloud/checkout-web/assets/app-bridge-checkout.js\"></script>\n</head>\n", + "language": "html" + } + ] + } + }, + { + "type": "Generic", + "anchorLink": "global-variable", + "title": "App Bridge’s global variable", + "sectionContent": "\nAfter App Bridge is set up in your app, you have access to the `shopify` global variable. This variable exposes various App Bridge functionalities, such as resizing the iframe or retrieving details of the shop.\n\nThe [reference](#app%20bridge%20for%20checkout) above list all the available methods and properties.\n\nAlternatively, to explore all the functionality available on the `shopify` global variable:\n\n* Open the Chrome developer console while in checkout.\n* Switch the frame context to your app's iframe.\n* Enter `shopify` in the console.\n", + "codeblock": { + "title": "shopify", + "tabs": [ + { + "title": "config", + "code": "shopify.config.locale;\n// => 'en-CA'\n", + "language": "js" + } + ] + } + }, + { + "type": "Generic", + "anchorLink": "app-bridge-css-api", + "title": "App Bridge’s CSS API", + "sectionContent": "\nSince the Chat iframe is clipped and fills the whole window as seen in the previous section, using percentage based sizes for its UI elements will most likely resolves in clipped content. As mentioned in the UX guidelines, Chat is constraint to specific [maximum sizes on large and small screens](/docs/apps/build/checkout/chat/ux-for-chat#build-within-the-chat-component-dimensions) set by Shopify. Setting a 100% width on an element will not be constraint to the visible size of the iframe, but to the whole window.\n\nTo remediate this issue, through App Bridge we offer a set of [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) with all the maximum dimensions defined in our UX guidelines. You can use these custom properties whether in Javascript or in the CSS of you application to set protections against overflowing content while using percentage based sizes. Using these properties will also reduce regressions if Shopify ever changes the maximum dimensions.\n", + "codeblock": { + "title": "App Bridge CSS API", + "tabs": [ + { + "title": "Custom properties", + "code": ":root {\n --shopify-checkout-chat-minimized-max-inline-size: 224px;\n --shopify-checkout-chat-minimized-max-block-size: 72px;\n --shopify-checkout-chat-maximized-max-inline-size: 415px;\n --shopify-checkout-chat-maximized-max-block-size: 700px;\n\n @media screen and (max-width: 569px) {\n --shopify-checkout-chat-maximized-max-inline-size: 100dvi;\n --shopify-checkout-chat-maximized-max-block-size: 93dvb;\n\n @supports not (inline-size: 100dvi) {\n --shopify-checkout-chat-maximized-max-inline-size: 100vi;\n --shopify-checkout-chat-maximized-max-block-size: 93vb;\n }\n }\n}\n", + "language": "css" + }, + { + "title": "style.css", + "code": ".activator {\n inline-size: 100%;\n max-inline-size: var(--shopify-checkout-chat-minimized-max-inline-size);\n}\n\n.dialog {\n inline-size: 100%;\n max-inline-size: var(--shopify-checkout-chat-maximized-max-inline-size);\n}\n", + "language": "css" + } + ] + } + } + ], + "examples": { + "description": "", + "examples": [ + { + "description": "A very common action in your application will be to request a resize of the iframe. This is done through the App Bridge `resizeTo()` method. The following example resizes the iframe following the click of an activator button to show a dialog window.", + "codeblock": { + "title": "Resize the Chat iframe from the hosted application", + "tabs": [ + { + "title": "UI Extension", + "code": "import {reactExtension, Chat} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension('customer-account.page.render', () => (\n <Extension />\n));\n\nfunction Extension() {\n return <Chat inlineSize={150} blockSize={50} />;\n}\n", + "language": "tsx" + }, + { + "title": "Hosted chat application", + "code": "<!doctype html>\n<html lang=\"en\">\n <head>\n <script src=\"https://cdn.shopify.com/shopifycloud/checkout-web/assets/app-bridge-checkout.js\"></script>\n <style>\n .dialog {\n display: none;\n }\n .visible {\n display: block;\n }\n </style>\n </head>\n <body>\n <dialog class=\"dialog\">\n How can we help you today?\n <button class=\"btn-close\">Close</button>\n </dialog>\n <button class=\"btn-activator\">Chat with us</button>\n\n <script type=\"text/javascript\">\n const btnActivator = document.querySelector('.btn-activator');\n const btnClose = document.querySelector('.btn-close');\n const dialog = document.querySelector('.dialog');\n\n // bind actions to the buttons\n btnActivator.addEventListener('click', toggleDialog);\n btnClose.addEventListener('click', toggleDialog);\n\n function toggleDialog() {\n // if the dialog is visible,\n // - hide the dialog\n // - resize the iframe to the button's size\n if (dialog.classList.contains('visible')) {\n dialog.classList.remove('visible');\n shopify !== undefined && window.resizeTo(150, 50);\n\n // if the dialog is not visible,\n // - resize the iframe to the desired dialog's size\n // - then show the dialog\n } else {\n shopify !== undefined && window.resizeTo(415, 700);\n dialog.classList.add('visible');\n }\n }\n </script>\n </body>\n</html>\n", + "language": "html" + } + ] + } + }, + { + "description": "\nInformation can be passed between the hosted application and the UI extension through App Bridge. [Extensions API](/docs/api/customer-account-ui-extensions/unstable#extension-apis) are available in the UI extension and can be shared through that method.\n ", + "codeblock": { + "title": "Communicate information between the hosted application and the UI extension", + "tabs": [ + { + "title": "UI Extension", + "code": "import {\n reactExtension,\n Chat,\n} from '@shopify/ui-extensions-react/customer-account';\nimport {retain} from '@remote-ui/rpc';\nimport type {ReadyEvent} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension('customer-account.page.render', () => (\n <Extension />\n));\n\nfunction Extension() {\n let postMessage;\n\n return (\n <Chat\n inlineSize={150}\n blockSize={50}\n onReady={({postMessage: postMessageParam}: ReadyEvent) => {\n postMessage = postMessageParam;\n retain(postMessage);\n\n postMessage({\n action: 'ping',\n });\n }}\n onMessage={(event: Event) => {\n if (event.data.action === 'pong') {\n console.log('Messaging channel successful');\n }\n }}\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "Hosted chat application", + "code": "// Create a variable to store the buyer's first name.\n// We'll be able to use this to personalize the chat experience.\nlet buyerFirstName;\n\n// In the hosted application Javascript, listen for messages from the UI extension.\nshopify.extension.port.onmessage = async (event) => {\n // if the message's data has a ping action, respond with a pong\n if (event.data.action === 'ping') {\n buyerFirstName = event.data.buyer.firstName;\n\n await shopify.extension.port.postMessage({\n action: 'pong',\n });\n }\n};\n\n// Ensure the messagePort is ready to start sending and receiving messages.\nshopify.extension.port.start();\n", + "language": "js" + } + ] + } + } + ] + }, + "related": [] + }, + { + "name": "Checkbox", + "description": "Use checkboxes to give customers a single binary option, such as signing up for marketing, or agreeing to terms and conditions.", + "thumbnail": "checkbox-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "CheckboxProps", + "description": "", + "type": "CheckboxProps", + "typeDefinitions": { + "CheckboxProps": { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "name": "CheckboxProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "checked", + "value": "boolean", + "description": "Whether the checkbox is active.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the checkbox can be changed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "error", + "value": "string", + "description": "Indicate an error to the user. The field will be given a specific stylistic treatment to communicate problems that have to be resolved immediately.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the field. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: boolean) => void", + "description": "A callback that is run whenever the checkbox is changed. This callback is called with a boolean indicating whether the checkbox should now be active or inactive. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), so you must store this value in state and reflect it back in the `checked` or `value` props.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Checkbox/Checkbox.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "boolean", + "description": "Whether the checkbox is active. This prop is an alias for `checked`, and can be useful in form libraries that provide a normalized API for dealing with both `boolean` and `string` values. If both `value` and `checked` are set, `checked` takes precedence.", + "isOptional": true + } + ], + "value": "export interface CheckboxProps extends DisclosureActivatorProps {\n /**\n * A unique identifier for the field. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n\n /**\n * Whether the checkbox is active. This prop is an alias for `checked`,\n * and can be useful in form libraries that provide a normalized API for\n * dealing with both `boolean` and `string` values. If both `value` and\n * `checked` are set, `checked` takes precedence.\n */\n value?: boolean;\n\n /**\n * Whether the checkbox is active.\n */\n checked?: boolean;\n\n /**\n * Whether the checkbox can be changed.\n */\n disabled?: boolean;\n\n /**\n * Indicate an error to the user. The field will be given a specific stylistic treatment\n * to communicate problems that have to be resolved immediately.\n */\n error?: string;\n\n /**\n * A label used for buyers using assistive technologies. When set, any\n * `children` supplied to this component will not be announced to screen reader users.\n */\n accessibilityLabel?: string;\n\n /**\n * A callback that is run whenever the checkbox is changed. This callback\n * is called with a boolean indicating whether the checkbox should now be\n * active or inactive. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components),\n * so you must store this value in state and reflect it back in the\n * `checked` or `value` props.\n */\n onChange?(value: boolean): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "checkbox-default.png", + "codeblock": { + "title": "Basic Checkbox", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Checkbox,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Checkbox id=\"checkbox\" name=\"checkbox\">\n Save this information for next time\n </Checkbox>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Checkbox} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const checkbox = root.createComponent(\n Checkbox,\n {id: 'checkbox', name: 'checkbox'},\n 'Save this information for next time',\n );\n\n root.appendChild(checkbox);\n});\n", + "language": "js" + } + ] + } + }, + "examples": { + "description": "", + "examples": [ + { + "description": "To provide buyers with additional information or references, couple it with link components seamlessly within checkbox components. This can be done by including links as part of the checkbox label in the checkbox. This will provide an easy way to access relevant content that buyers may need.", + "image": "checkbox-links.png", + "codeblock": { + "title": "Embedding links in checkbox components", + "tabs": [ + { + "code": "import {\n reactExtension,\n Checkbox,\n Link,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <CheckBoxLinks />,\n);\n\nexport const CheckBoxLinks = () => {\n return (\n <Checkbox\n id=\"checkbox1\"\n name=\"checkboxchoices\"\n >\n I agree to the{' '}\n <Link to=\"https://www.shopify.com\">\n terms and conditions\n </Link>{' '}\n and{' '}\n <Link to=\"https://www.shopify.com\">\n privacy policy\n </Link>{' '}\n of the store related to pricing, payment,\n shipping, returns, and liability set forth\n by Ride Sports\n </Checkbox>\n );\n};\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Checkbox,\n Link,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const checkbox = root.createComponent(\n Checkbox,\n {\n id: 'checkbox1',\n name: 'checkboxchoices',\n },\n [\n ' I agree to the ',\n root.createComponent(\n Link,\n {to: 'https://www.shopify.com'},\n 'terms and conditions',\n ),\n ' and ',\n root.createComponent(\n Link,\n {to: 'https://www.shopify.com'},\n 'privacy policy',\n ),\n ' of the store related to pricing, payment, shipping, returns, and liability set forth by Ride Sports.',\n ],\n );\n\n root.appendChild(checkbox);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [] + }, + { + "name": "Choice", + "description": "Options inside a `ChoiceList`.\n\nThe wrapping `ChoiceList` component will dictate if the choice renders as radio buttons or checkboxes.", + "thumbnail": "choice-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ChoiceProps", + "description": "", + "type": "ChoiceProps", + "typeDefinitions": { + "ChoiceProps": { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "name": "ChoiceProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "syntaxKind": "PropertySignature", + "name": "details", + "value": "string | RemoteFragment", + "description": "Additional content to be revealed when selected.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the choice can be changed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the choice." + }, + { + "filePath": "src/surfaces/checkout/components/Choice/Choice.ts", + "syntaxKind": "PropertySignature", + "name": "primaryContent", + "value": "string | RemoteFragment", + "description": "The primary content for a choice. Rendered below `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the cross axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "columns", + "value": "MaybeResponsiveConditionalStyle", + "description": "Sizes for each column of the layout.\n\n\n`auto`: intrinsic size of the content.\n\n`fill`: fills the remaining available space. When multiple columns are set to `fill`, the remaining space is shared equally.\n\n`` `${number}%` ``: size in percentages.\n\n`` `${number}fr` ``: size in fractions.\n\n`number`: size in pixels.\n\n\n- When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n- Except when in scrollview, where the grid will fill the space with the defined sizes.\n\n- When only one size is set and outside of an array, the grid will have one column of that size.", + "isOptional": true, + "defaultValue": "'fill'" + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "rows", + "value": "MaybeResponsiveConditionalStyle", + "description": "Sizes for each row of the layout.\n\n\n`auto`: intrinsic size of the content.\n\n`fill`: fills the remaining available space. When multiple rows are set to `fill`, the remaining space is shared equally.\n\n`` `${number}%` ``: size in percentages.\n\n`` `${number}fr` ``: size in fractions.\n\n`number`: size in pixels.\n\n\n- When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n\n- When only one size is set and outside of an array, the grid will have one row of that size.", + "isOptional": true, + "defaultValue": "'fill'" + }, + { + "filePath": "src/surfaces/checkout/components/Grid/Grid.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between children.\n\n- `base` means the space between rows and columns is `base`.\n\n- [`base`, `none`] means the space between rows is `base`, space between columns is `none`.", + "isOptional": true, + "defaultValue": "'none'" + } + ], + "value": "export interface GridProps\n extends Pick,\n IdProps,\n BorderProps,\n CornerProps,\n SizingProps,\n SpacingProps {\n /**\n * Sizes for each column of the layout.\n *\n *\n * `auto`: intrinsic size of the content.\n *\n * `fill`: fills the remaining available space. When multiple columns are set to `fill`, the remaining space is shared equally.\n *\n * `` `${number}%` ``: size in percentages.\n *\n * `` `${number}fr` ``: size in fractions.\n *\n * `number`: size in pixels.\n *\n *\n * - When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n * - Except when in scrollview, where the grid will fill the space with the defined sizes.\n *\n * - When only one size is set and outside of an array, the grid will have one column of that size.\n *\n * @defaultValue 'fill'\n */\n columns?: MaybeResponsiveConditionalStyle;\n /**\n * Sizes for each row of the layout.\n *\n *\n * `auto`: intrinsic size of the content.\n *\n * `fill`: fills the remaining available space. When multiple rows are set to `fill`, the remaining space is shared equally.\n *\n * `` `${number}%` ``: size in percentages.\n *\n * `` `${number}fr` ``: size in fractions.\n *\n * `number`: size in pixels.\n *\n *\n * - When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n *\n * - When only one size is set and outside of an array, the grid will have one row of that size.\n *\n * @defaultValue 'fill'\n */\n rows?: MaybeResponsiveConditionalStyle;\n /**\n * Adjust spacing between children.\n *\n * - `base` means the space between rows and columns is `base`.\n *\n * - [`base`, `none`] means the space between rows is `base`, space between columns is `none`.\n *\n * @defaultValue 'none'\n **/\n spacing?: MaybeResponsiveConditionalStyle;\n /**\n * Position children along the cross axis.\n */\n blockAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Position children along the main axis.\n */\n inlineAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n *\n *\n * For example:\n *\n * - In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n *\n * - In an HTML host a `listItem` string will render: `
  • `\n */\n accessibilityRole?: ViewLikeAccessibilityRole;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n /**\n * Changes the display of the component.\n *\n *\n * `auto` the component's initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle<'auto' | 'none'>;\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Columns": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Columns", + "value": "GridItemSize[] | GridItemSize", + "description": "" + }, + "GridItemSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "GridItemSize", + "value": "'auto' | 'fill' | number | `${number}fr` | `${number}%`", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + }, + "Rows": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Rows", + "value": "GridItemSize[] | GridItemSize", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "grid-default.png", + "codeblock": { + "title": "Basic Grid", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Grid,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Grid\n columns={['20%', 'fill', 'auto']}\n rows={[300, 'auto']}\n spacing=\"loose\"\n >\n <View border=\"base\" padding=\"base\">\n 20% / 300\n </View>\n <View border=\"base\" padding=\"base\">\n fill / 300\n </View>\n <View border=\"base\" padding=\"base\">\n auto / 300\n </View>\n <View border=\"base\" padding=\"base\">\n 20% / auto\n </View>\n <View border=\"base\" padding=\"base\">\n fill / auto\n </View>\n <View border=\"base\" padding=\"base\">\n auto / auto\n </View>\n </Grid>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Grid, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const grid = root.createComponent(\n Grid,\n {\n columns: ['20%', 'fill', 'auto'],\n rows: [300, 'auto'],\n },\n [\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n '20% / 300',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'fill / 300',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'auto / 300',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n '20% / auto',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'fill / auto',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'auto / auto',\n ),\n ],\n );\n\n root.appendChild(grid);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "name": "GridItem", + "subtitle": "Component", + "url": "grid", + "type": "Component" + }, + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "GridItem", + "description": "GridItem can be used as children of Grid.\n\nIt offers a way to span the element across a number of columns and rows.", + "thumbnail": "griditem-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "GridItemProps", + "description": "", + "type": "GridItemProps", + "typeDefinitions": { + "GridItemProps": { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "name": "GridItemProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "columnSpan", + "value": "MaybeResponsiveConditionalStyle", + "description": "Number of columns the item will span across", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/GridItem/GridItem.ts", + "syntaxKind": "PropertySignature", + "name": "rowSpan", + "value": "MaybeResponsiveConditionalStyle", + "description": "Number of rows the item will span across", + "isOptional": true + } + ], + "value": "export interface GridItemProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n SizingProps,\n SpacingProps {\n /**\n * Number of columns the item will span across\n */\n columnSpan?: MaybeResponsiveConditionalStyle;\n /**\n * Number of rows the item will span across\n */\n rowSpan?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n *\n *\n * For example:\n *\n * - In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n *\n * - In an HTML host a `listItem` string will render: `
  • `\n */\n accessibilityRole?: ViewLikeAccessibilityRole;\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n /**\n * Changes the display of the component.\n *\n *\n * `auto` the component's initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle<'auto' | 'none'>;\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "griditem-default.png", + "codeblock": { + "title": "Basic GridItem", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Grid,\n GridItem,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Grid\n columns={['20%', 'fill', 'auto']}\n rows={[300, 'auto']}\n spacing=\"loose\"\n >\n <View border=\"base\" padding=\"base\">\n 20% / 300\n </View>\n <View border=\"base\" padding=\"base\">\n fill / 300\n </View>\n <View border=\"base\" padding=\"base\">\n auto / 300\n </View>\n <GridItem columnSpan={2}>\n <View border=\"base\" padding=\"base\">\n 20% + fill / auto\n </View>\n </GridItem>\n <View border=\"base\" padding=\"base\">\n auto / auto\n </View>\n </Grid>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Grid, GridItem, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const grid = root.createComponent(\n Grid,\n {\n columns: ['20%', 'fill', 'auto'],\n rows: [300, 'auto'],\n },\n [\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n '20% / 300',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'fill / 300',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'auto / 300',\n ),\n root.createComponent(GridItem, {columnSpan: 2}, [\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n '20% + fill / auto',\n ),\n ]),\n root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'auto / auto',\n ),\n ],\n );\n\n root.appendChild(grid);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "name": "Grid", + "subtitle": "Component", + "url": "grid", + "type": "Component" + }, + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "Heading", + "description": "Headings control the visual style of headings. Use headings to introduce major sections, like Contact information, Shipping address, or Shipping method.\n\nUnlike HTML headings, you don’t explicitly specify the position of the heading in the document outline. Nest headings within the heading group component to control the document outline structure used by assistive technologies.", + "thumbnail": "heading-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "HeadingProps", + "description": "", + "type": "HeadingProps", + "typeDefinitions": { + "HeadingProps": { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "name": "HeadingProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "'presentation'", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "Unique identifier. Typically used to make the heading a target that another component can refer to in order to provide an alternative accessibility label.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "InlineAlignment", + "description": "Align text along the main axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "syntaxKind": "PropertySignature", + "name": "level", + "value": "Level", + "description": "The visual level of the heading. When not set, the heading will use its “automatic” heading level, which is determined by the level of nesting within ancestor `HeadingGroup`s. No matter what value you provide here, the semantic level (e.g., how the heading contributes to the document outline) is determined exclusively by the “automatic” heading level.", + "isOptional": true + } + ], + "value": "export interface HeadingProps {\n /**\n * Unique identifier.\n * Typically used to make the heading a target that another component\n * can refer to in order to provide an alternative accessibility label.\n */\n id?: string;\n /**\n * The visual level of the heading. When not set, the heading will use\n * its “automatic” heading level, which is determined by the level of nesting\n * within ancestor `HeadingGroup`s. No matter what value you provide here,\n * the semantic level (e.g., how the heading contributes to the document outline)\n * is determined exclusively by the “automatic” heading level.\n */\n level?: Level;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n */\n accessibilityRole?: Extract;\n /**\n * Align text along the main axis.\n */\n inlineAlignment?: InlineAlignment;\n}" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Level": { + "filePath": "src/surfaces/checkout/components/Heading/Heading.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Level", + "value": "1 | 2 | 3 | 4", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "heading-default.png", + "codeblock": { + "title": "Basic Heading", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Heading,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Heading>Store name</Heading>;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Heading} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const heading = root.createComponent(Heading, undefined, 'Store name');\n\n root.appendChild(heading);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Add a heading at the top of each section that clearly describe what’s below.\n\n- Use the heading to highlight the most important concepts or pieces of information that customers need to know." + } + ], + "related": [ + { + "name": "HeadingGroup", + "subtitle": "Component", + "url": "headinggroup", + "type": "Component" + }, + { + "name": "Text", + "subtitle": "Component", + "url": "text", + "type": "Component" + }, + { + "name": "TextBlock", + "subtitle": "Component", + "url": "textblock", + "type": "Component" + } + ] + }, + { + "name": "HeadingGroup", + "description": "Heading group controls the heading level of headings nested within it, like H1, H2, H3.\n\nUse a heading group whenever you use a heading to ensure the experience is the same for screen reader users. When using a heading, any children related to that heading should be nested within the same heading group.", + "thumbnail": "headinggroup-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "headinggroup-default.png", + "codeblock": { + "title": "Basic HeadingGroup", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n HeadingGroup,\n Heading,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <>\n <Heading>Heading <h1></Heading>\n\n <HeadingGroup>\n <Heading>Heading <h2></Heading>\n\n <HeadingGroup>\n <Heading>Heading <h3></Heading>\n </HeadingGroup>\n </HeadingGroup>\n </>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n HeadingGroup,\n Heading,\n View,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const headingGroup = root.createComponent(View, undefined, [\n root.createComponent(Heading, undefined, 'Heading <h1>'),\n root.createComponent(HeadingGroup, undefined, [\n root.createComponent(Heading, undefined, 'Heading <h2>'),\n root.createComponent(HeadingGroup, undefined, [\n root.createComponent(Heading, undefined, 'Heading <h3>'),\n ]),\n ]),\n ]);\n\n root.appendChild(headingGroup);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use this component to create a content hierarchy within the document outline." + } + ], + "related": [ + { + "name": "Heading", + "subtitle": "Component", + "url": "heading", + "type": "Component" + }, + { + "name": "Text", + "subtitle": "Component", + "url": "text", + "type": "Component" + }, + { + "name": "TextBlock", + "subtitle": "Component", + "url": "textblock", + "type": "Component" + } + ] + }, + { + "name": "Icon", + "description": "Icons are pictograms or graphic symbols. They can act as wayfinding tools or as a means of communicating functionality.", + "thumbnail": "icon-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "IconProps", + "description": "", + "type": "IconProps", + "typeDefinitions": { + "IconProps": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "name": "IconProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the icon. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "Appearance", + "description": "Sets the appearance (color) of the icon.", + "isOptional": true, + "defaultValue": "'base'" + }, + { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "'extraSmall' | 'small' | 'large' | 'base' | 'fill'", + "description": "Adjusts the size of the icon.", + "isOptional": true, + "defaultValue": "'base'" + }, + { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "PropertySignature", + "name": "source", + "value": "IconSource", + "description": "Specifies which icon to display\n\nCheck the list of available icons [here](/docs/api/checkout-ui-extensions/components/media/icon#icons)" + } + ], + "value": "export interface IconProps extends IdProps {\n /**\n * A label that describes the purpose or contents of the icon. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n\n /**\n * Sets the appearance (color) of the icon.\n *\n * @defaultValue 'base'\n */\n appearance?: Appearance;\n\n /**\n * Adjusts the size of the icon.\n *\n * @defaultValue 'base'\n */\n size?: Extract;\n\n /**\n * Specifies which icon to display\n *\n * Check the list of available icons [here](/docs/api/checkout-ui-extensions/components/media/icon#icons)\n */\n source: IconSource;\n}" + }, + "Appearance": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Appearance", + "value": "'base' | 'accent' | 'decorative' | 'interactive' | 'subdued' | 'info' | 'success' | 'warning' | 'critical' | 'monochrome'", + "description": "" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "icon-default.png", + "codeblock": { + "title": "Basic Icon", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Icon,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Icon source=\"discount\" />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Icon} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const icon = root.createComponent(Icon, {source: 'discount'});\n\n root.appendChild(icon);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "icons", + "title": "Icons", + "sectionContent": "" + }, + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"accent\" | Conveys emphasis and draws attention to the element. |\n| \"interactive\" | Conveys that the element is pressable, hoverable or otherwise interactive. |\n| \"subdued\" | Conveys a subdued or disabled state for the element. |\n| \"info\" | Conveys that the element is informative or has information. |\n| \"success\" | Convey a successful interaction. |\n| \"warning\" | Convey something needs attention or an action needs to be taken. |\n| \"critical\" | Conveys a problem has arisen. |\n| \"monochrome\" | Takes the color of its parent.|" + } + ], + "related": [] + }, + { + "name": "Image", + "description": "Image is used for large format, responsive images.", + "thumbnail": "image-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ImageProps", + "description": "", + "type": "ImageProps", + "typeDefinitions": { + "ImageProps": { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "name": "ImageProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityDescription", + "value": "string", + "description": "An alternative text description that describe the image for the reader to understand what it is about. It is extremely useful for both buyers using assistive technology and sighted buyers. A well written `description` provides people with visual impairments the ability to participate in consuming non-text content. When a screen readers encounters an `Image`, the description is read and announced aloud. If an image fails to load, potentially due to a poor connection, the `description` is displayed on screen instead. This has the benefit of letting a sighted buyer know an image was meant to load here, but as an alternative, they’re still able to consume the text content. Read [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204) to learn more.", + "isOptional": true, + "defaultValue": "''" + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "'decorative'", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "aspectRatio", + "value": "number", + "description": "Displays the image at the specified aspect ratio (fills the width of the parent container and sets the height accordingly) and creates an invisible placeholder to prevent content jumping when the image loads. Use along with `fit` if the specified aspect ratio does not match the intrinsic aspect ratio to prevent the image from stretching.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "fit", + "value": "MaybeResponsiveConditionalStyle", + "description": "Indicates how the image fits in its frame. Use if the image is not displayed at its intrinsic size to maintain the aspect ratio.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "Loading", + "description": "Indicates how the browser should load the image, either eager or lazy.\n\nUses native browser behavior and is not supported by all browsers. If no value is provided then the image is loaded immediately, regardless of whether or not the image is currently within the visible viewport.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "PropertySignature", + "name": "source", + "value": "Required<\n MaybeConditionalStyle<\n string,\n AtLeastOne\n >\n >", + "description": "The URL of the image. Supports the `resolution` and `viewportInlineSize` conditional styles only." + } + ], + "value": "export interface ImageProps extends BorderProps, CornerProps, IdProps {\n /**\n * The URL of the image. Supports the `resolution` and `viewportInlineSize` conditional styles only.\n */\n source: Required<\n MaybeConditionalStyle<\n string,\n AtLeastOne\n >\n >;\n /**\n * An alternative text description that describe the image for the reader to\n * understand what it is about. It is extremely useful for both buyers using\n * assistive technology and sighted buyers. A well written `description`\n * provides people with visual impairments the ability to participate in\n * consuming non-text content. When a screen readers encounters an `Image`,\n * the description is read and announced aloud. If an image fails to load,\n * potentially due to a poor connection, the `description` is displayed on\n * screen instead. This has the benefit of letting a sighted buyer know an\n * image was meant to load here, but as an alternative, they’re still able to\n * consume the text content. Read\n * [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204)\n * to learn more.\n *\n * @defaultValue ''\n */\n accessibilityDescription?: string;\n /**\n * Indicates how the browser should load the image, either eager or lazy.\n *\n * Uses native browser behavior and is not supported by all browsers.\n * If no value is provided then the image is loaded immediately, regardless of\n * whether or not the image is currently within the visible viewport.\n */\n loading?: Loading;\n /**\n * Displays the image at the specified aspect ratio (fills the width of the\n * parent container and sets the height accordingly) and creates an invisible\n * placeholder to prevent content jumping when the image loads. Use along\n * with `fit` if the specified aspect ratio does not match the intrinsic\n * aspect ratio to prevent the image from stretching.\n */\n aspectRatio?: number;\n /**\n * Indicates how the image fits in its frame.\n * Use if the image is not displayed at its intrinsic size to maintain\n * the aspect ratio.\n */\n fit?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n */\n accessibilityRole?: Extract;\n}" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Fit": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Fit", + "value": "'cover' | 'contain'", + "description": "" + }, + "Loading": { + "filePath": "src/surfaces/checkout/components/Image/Image.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Loading", + "value": "'eager' | 'lazy'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "AtLeastOne": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AtLeastOne", + "value": "Partial & U[keyof U]", + "description": "" + }, + "ResolutionCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ResolutionCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "resolution", + "value": "Resolution", + "description": "" + } + ], + "value": "export interface ResolutionCondition {\n resolution: Resolution;\n}" + }, + "Resolution": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Resolution", + "value": "1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "image-default.png", + "codeblock": { + "title": "Basic Image", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Image,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Image source=\"https://cdn.shopify.com/YOUR_IMAGE_HERE\" />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Image} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const image = root.createComponent(Image, {\n source: 'https://cdn.shopify.com/YOUR_IMAGE_HERE',\n });\n\n root.appendChild(image);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "loading", + "title": "Loading", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"eager\" | Image is loaded immediately, regardless of whether or not the image is currently within the visible viewport. |\n| \"lazy\" | Image is loaded when it’s within the visible viewport. |" + } + ], + "related": [] + }, + { + "name": "ImageGroup", + "description": "Display up to 4 images in a grid or stacked layout. For example, images of products in a wishlist or subscription. When there are more than 4 images, the component indicates how many more images are not displayed.", + "thumbnail": "imagegroup-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ImageGroupProps", + "description": "", + "type": "ImageGroupProps", + "typeDefinitions": { + "ImageGroupProps": { + "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "name": "ImageGroupProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the image group. When set, it will be announced to users using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Indicates that the image group is in a loading state.\n\nWhen `true`, the image group show a loading indicator.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "syntaxKind": "PropertySignature", + "name": "totalItems", + "value": "number", + "description": "Indicates the total number of items that could be displayed in the image group. It is used to determine the remaining number to show when all the available image slots have been filled.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/ImageGroup/ImageGroup.ts", + "syntaxKind": "PropertySignature", + "name": "variant", + "value": "'grid' | 'inline-stack'", + "description": "Changes the layout of the images.", + "isOptional": true, + "defaultValue": "\"grid\"" + } + ], + "value": "export interface ImageGroupProps {\n /**\n * Changes the layout of the images.\n *\n * @default \"grid\"\n */\n variant?: 'grid' | 'inline-stack';\n\n /**\n * A label that describes the purpose or contents of the image group. When set,\n * it will be announced to users using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n\n /**\n * Indicates that the image group is in a loading state.\n *\n * When `true`, the image group show a loading indicator.\n *\n * @defaultValue false\n */\n loading?: boolean;\n\n /**\n * Indicates the total number of items that could be displayed in the image group. It is used to determine the remaining number to show when all the available image slots have been filled.\n */\n totalItems?: number;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "imagegroup-preview.png", + "altText": "An example of the ImageGroup component shows 3 circular images of plants displayed in a row, each one slightly overlapping the previous image—in a horizontal stacked pattern. To the right, there is another group of 3 images of plants, arranged in a 2x2 grid. There is one square image in the upper-left quadrant, one square image in the lower-left quadrant, and the entire right half of the grid is occupied by one image.", + "codeblock": { + "title": "Basic ImageGroup", + "tabs": [ + { + "title": "React", + "code": "import {\n Image,\n ImageGroup,\n View,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension('customer-account.page.render', () => <App />);\n\nfunction App() {\n return (\n <View maxInlineSize={300}>\n <ImageGroup>\n <Image source=\"../assets/flower.jpg\" />\n <Image source=\"../assets/flower.jpg\" />\n <Image source=\"../assets/flower.jpg\" />\n </ImageGroup>\n </View>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n Image,\n ImageGroup,\n View,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n const firstImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const secondeImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const thirdImage = root.createComponent(Image, {\n source: \"../assets/flower.jpg\"\n });\n\n const imageGroup = root.createComponent(ImageGroup);\n\n imageGroup.append(firstImage);\n imageGroup.append(secondeImage);\n imageGroup.append(thirdImage);\n\n const view = root.createComponent(View, {maxInlineSize: 300});\n view.append(imageGroup);\n\n root.append(view);\n}\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n- Use with the [ResourceItem](/docs/api/customer-account-ui-extension/unstable/components/resourceitem) component\n- Optimize image file sizes and consider lazy loading for performance.\n" + } + ], + "related": [] + }, + { + "name": "InlineLayout", + "description": "InlineLayout is used to lay out content over multiple columns.\n\nBy default, all columns are of equal size and fill the available inline space. Content does not wrap on new rows when not enough columns have been explicitly set, instead they are added as new column and fill the remaining inline space.", + "thumbnail": "inlinelayout-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "InlineLayoutProps", + "description": "", + "type": "InlineLayoutProps", + "typeDefinitions": { + "InlineLayoutProps": { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "name": "InlineLayoutProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the cross axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "columns", + "value": "MaybeResponsiveConditionalStyle", + "description": "Sizes for each column of the layout.\n\n\n`auto`: intrinsic size of the element.\n\n`fill`: fills the remaining available space. When multiple elements are set to `fill`, the remaining space is shared equally.\n\n`` `${number}%` ``: size in percentages.\n\n`` `${number}fr` ``: size in fractions.\n\n`number`: size in pixels.\n\n\n- When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n\n- When the size of an element is not explicitly set, it will fill the remaining space available.\n\n- When only one size is set and outside of an array, all elements of the layout will take that size.", + "isOptional": true, + "defaultValue": "'fill'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineLayout/InlineLayout.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between children.\n\n- `base` means the space between rows and columns is `base`.\n\n- [`base`, `none`] means the space between rows is `base`, space between columns is `none`.", + "isOptional": true, + "defaultValue": "'none'" + } + ], + "value": "export interface InlineLayoutProps\n extends Omit,\n BorderProps,\n CornerProps,\n SizingProps,\n SpacingProps {\n /**\n * Sizes for each column of the layout.\n *\n *\n * `auto`: intrinsic size of the element.\n *\n * `fill`: fills the remaining available space. When multiple elements are set to `fill`, the remaining space is shared equally.\n *\n * `` `${number}%` ``: size in percentages.\n *\n * `` `${number}fr` ``: size in fractions.\n *\n * `number`: size in pixels.\n *\n *\n * - When the sum of the defined sizes is larger than the available space, elements will shrink to avoid overflow.\n *\n * - When the size of an element is not explicitly set, it will fill the remaining space available.\n *\n * - When only one size is set and outside of an array, all elements of the layout will take that size.\n *\n *\n * @defaultValue 'fill'\n */\n columns?: MaybeResponsiveConditionalStyle;\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Columns": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Columns", + "value": "GridItemSize[] | GridItemSize", + "description": "" + }, + "GridItemSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "GridItemSize", + "value": "'auto' | 'fill' | number | `${number}fr` | `${number}%`", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "inlinelayout-default.png", + "codeblock": { + "title": "Basic InlineLayout", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n InlineLayout,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <InlineLayout columns={['20%', 'fill']}>\n <View border=\"base\" padding=\"base\">\n 20%\n </View>\n <View border=\"base\" padding=\"base\">\n fill\n </View>\n </InlineLayout>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, InlineLayout, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const inlineLayout = root.createComponent(\n InlineLayout,\n {\n columns: ['20%', 'fill'],\n },\n [\n root.createComponent(View, {border: 'base', padding: 'base'}, '20%'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'fill'),\n ],\n );\n\n root.appendChild(inlineLayout);\n});\n", + "language": "js" + } + ] + } + }, + "examples": { + "description": "", + "examples": [ + { + "description": "Use the Disclosure component to simplify the user experience and reveal interfaces only when the customer requests it. It also demonstrates how a combination of inline and block layout components can improve the readability of information. By employing these strategies, users can easily scan and comprehend the content, making for a better user experience overall.", + "image": "disclosure-and-alignment.gif", + "codeblock": { + "title": "Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.", + "tabs": [ + { + "code": "import {\n reactExtension,\n View,\n Image,\n Icon,\n Pressable,\n Disclosure,\n InlineLayout,\n BlockStack,\n Text,\n Form,\n TextField,\n Button,\n Divider,\n InlineStack,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <DisclosureAndAlignment />,\n);\n\nexport const DisclosureAndAlignment = () => {\n const openIds = ['one'];\n return (\n <View\n maxInlineSize={400}\n cornerRadius=\"large\"\n border=\"base\"\n >\n <BlockStack spacing=\"none\">\n <Disclosure\n defaultOpen=\"one\"\n onToggle={(open) =>\n console.log('onToggle event', open)\n }\n >\n <Pressable toggles=\"one\" padding=\"base\">\n <InlineLayout\n blockAlignment=\"center\"\n spacing=\"base\"\n columns={['auto', 'fill', 'auto']}\n >\n <Icon\n source=\"gift\"\n appearance=\"subdued\"\n />\n Gift message\n <Icon\n source={\n openIds.includes('one')\n ? 'chevronUp'\n : 'chevronDown'\n }\n appearance=\"subdued\"\n />\n </InlineLayout>\n </Pressable>\n <View\n id=\"one\"\n padding={[\n 'none',\n 'base',\n 'base',\n 'base',\n ]}\n >\n <Form\n onSubmit={() =>\n console.log('onSubmit event')\n }\n >\n <BlockStack>\n <InlineLayout\n columns={['fill', 'fill']}\n spacing=\"base\"\n >\n <TextField\n label=\"From\"\n name=\"from0\"\n id=\"from0\"\n />\n <TextField\n label=\"To\"\n name=\"to0\"\n id=\"to0\"\n />\n </InlineLayout>\n <TextField\n label=\"Message\"\n name=\"message0\"\n id=\"message0\"\n />\n <View>\n <Button\n accessibilityRole=\"submit\"\n kind=\"secondary\"\n >\n Save\n </Button>\n </View>\n </BlockStack>\n </Form>\n </View>\n </Disclosure>\n <Divider />\n <InlineLayout\n blockAlignment=\"baseline\"\n spacing=\"base\"\n columns={['auto', 'fill', 'auto']}\n padding=\"base\"\n >\n <Icon\n source=\"profile\"\n appearance=\"subdued\"\n />\n <BlockStack spacing=\"none\">\n <InlineStack blockAlignment=\"center\">\n <Text>Verify with</Text>\n <Image source=\"https://via.placeholder.com/50x15\" />\n </InlineStack>\n <Text\n appearance=\"subdued\"\n size=\"small\"\n >\n 15% savings for students and\n military\n </Text>\n </BlockStack>\n <Pressable to=\"https://www.shopify.com\">\n <Icon\n source=\"external\"\n appearance=\"subdued\"\n />\n </Pressable>\n </InlineLayout>\n </BlockStack>\n </View>\n );\n};\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n View,\n InlineLayout,\n InlineStack,\n Image,\n Pressable,\n Icon,\n Text,\n TextField,\n Form,\n Button,\n Disclosure,\n Divider,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const openIds = ['one'];\n\n const pressable = root.createComponent(\n Pressable,\n {\n toggles: 'one',\n padding: 'base',\n },\n [\n root.createComponent(\n InlineLayout,\n {\n blockAlignment: 'center',\n spacing: 'base',\n columns: ['auto', 'fill', 'auto'],\n },\n [\n root.createComponent(Icon, {\n source: 'gift',\n appearance: 'subdued',\n }),\n 'Gift message',\n root.createComponent(Icon, {\n source: openIds.includes('one')\n ? 'chevronUp'\n : 'chevronDown',\n size: 'small',\n }),\n ],\n ),\n ],\n );\n\n const disclosureView = root.createComponent(\n View,\n {\n id: 'one',\n padding: ['none', 'base', 'base', 'base'],\n },\n [\n root.createComponent(\n Form,\n {\n onSubmit: () =>\n console.log('onSubmit event'),\n },\n [\n root.createComponent(BlockStack, {}, [\n root.createComponent(\n InlineLayout,\n {\n columns: ['fill', 'fill'],\n spacing: 'base',\n },\n [\n root.createComponent(\n TextField,\n {\n label: 'From',\n name: 'from0',\n id: 'from0',\n },\n ),\n root.createComponent(\n TextField,\n {\n label: 'To',\n name: 'to0',\n id: 'to0',\n },\n ),\n ],\n ),\n root.createComponent(TextField, {\n label: 'Message',\n name: 'message0',\n id: 'message0',\n }),\n root.createComponent(View, {}, [\n root.createComponent(\n Button,\n {\n accessibilityRole: 'submit',\n kind: 'secondary',\n },\n 'Save',\n ),\n ]),\n ]),\n ],\n ),\n ],\n );\n\n const disclosure = root.createComponent(\n Disclosure,\n {\n defaultOpen: 'one',\n onToggle: (open) =>\n console.log('onToggle event', open),\n },\n [pressable, disclosureView],\n );\n\n const inlineLayout = root.createComponent(\n InlineLayout,\n {\n blockAlignment: 'baseline',\n spacing: 'base',\n columns: ['auto', 'fill', 'auto'],\n padding: 'base',\n },\n [\n root.createComponent(Icon, {\n source: 'profile',\n appearance: 'subdued',\n }),\n root.createComponent(\n BlockStack,\n {\n spacing: 'none',\n },\n [\n root.createComponent(\n InlineStack,\n {\n blockAlignment: 'center',\n },\n [\n root.createComponent(\n Text,\n {},\n 'Verify with',\n ),\n root.createComponent(Image, {\n source:\n 'https://via.placeholder.com/50x15',\n }),\n ],\n ),\n root.createComponent(\n Text,\n {\n appearance: 'subdued',\n size: 'small',\n },\n '15% savings for students and military',\n ),\n ],\n ),\n root.createComponent(\n Pressable,\n {\n to: 'https://www.shopify.com',\n },\n [\n root.createComponent(Icon, {\n source: 'external',\n appearance: 'subdued',\n }),\n ],\n ),\n ],\n );\n const view = root.createComponent(\n View,\n {\n maxInlineSize: 400,\n cornerRadius: 'large',\n border: 'base',\n },\n [\n root.createComponent(\n BlockStack,\n {\n spacing: 'none',\n },\n [\n disclosure,\n root.createComponent(Divider),\n inlineLayout,\n ],\n ),\n ],\n );\n\n root.appendChild(view);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "InlineSpacer", + "description": "InlineSpacer is used to create empty inline space, typically when variable spacing is needed between multiple elements.\n\nNote that you should favor InlineStack when spacing between all elements is the same.", + "isVisualComponent": true, + "thumbnail": "inlinespacer-thumbnail.png", + "requires": "", + "type": "", + "definitions": [ + { + "title": "InlineSpacerProps", + "description": "", + "type": "InlineSpacerProps", + "typeDefinitions": { + "InlineSpacerProps": { + "filePath": "src/surfaces/checkout/components/InlineSpacer/InlineSpacer.ts", + "name": "InlineSpacerProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/InlineSpacer/InlineSpacer.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineSpacer/InlineSpacer.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust size of the spacer", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface InlineSpacerProps extends IdProps {\n /**\n * Adjust size of the spacer\n *\n * @defaultValue 'base'\n **/\n spacing?: MaybeResponsiveConditionalStyle>;\n}" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "inlinespacer-default.png", + "codeblock": { + "title": "Basic InlineSpacer", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n InlineSpacer,\n InlineStack,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <InlineStack spacing=\"none\">\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <InlineSpacer spacing=\"loose\" />\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <InlineSpacer spacing=\"tight\" />\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <InlineSpacer spacing=\"base\" />\n <View border=\"base\" padding=\"base\">\n View\n </View>\n </InlineStack>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n InlineSpacer,\n InlineStack,\n View,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const inlineSpacer = root.createComponent(InlineStack, {spacing: 'none'}, [\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(InlineSpacer, {spacing: 'loose'}),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(InlineSpacer, {spacing: 'tight'}),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(InlineSpacer, {spacing: 'base'}),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n ]);\n\n root.appendChild(inlineSpacer);\n});\n", + "language": "js" + } + ] + } + }, + "related": [] + }, + { + "name": "InlineStack", + "description": "InlineStack is used to lay out a horizontal row of elements. Elements always wrap.", + "isVisualComponent": true, + "thumbnail": "inlinestack-thumbnail.png", + "requires": "", + "type": "", + "definitions": [ + { + "title": "InlineStackProps", + "description": "", + "type": "InlineStackProps", + "typeDefinitions": { + "InlineStackProps": { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "name": "InlineStackProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `'listItem'` string will render: `
  • `\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the cross axis", + "isOptional": true, + "defaultValue": "'start'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis", + "isOptional": true, + "defaultValue": "'start'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/InlineStack/InlineStack.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between children\n\n- `base` means the space between rows and columns is `base`.\n\n- [`base`, `none`] means the space between rows is `base`, space between columns is `none`.", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface InlineStackProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n SizingProps,\n SpacingProps {\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n *\n *\n * For example:\n *\n * - In an HTML host a `'listItem'` string will render: `
  • `\n *\n * - In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n */\n accessibilityRole?: ViewLikeAccessibilityRole;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n /**\n * Position children along the cross axis\n *\n * @defaultValue 'start'\n */\n blockAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Position children along the main axis\n *\n * @defaultValue 'start'\n */\n inlineAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Adjust spacing between children\n *\n * - `base` means the space between rows and columns is `base`.\n *\n * - [`base`, `none`] means the space between rows is `base`, space between columns is `none`.\n *\n * @defaultValue 'base'\n **/\n spacing?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n /**\n * Changes the display of the component.\n *\n *\n * `auto` the component's initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle<'auto' | 'none'>;\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "inlinestack-default.png", + "codeblock": { + "title": "Basic InlineStack", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n InlineStack,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <InlineStack spacing=\"base\">\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n <View border=\"base\" padding=\"base\">\n View\n </View>\n </InlineStack>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, InlineStack, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const inlineStack = root.createComponent(\n InlineStack,\n {\n spacing: 'base',\n },\n [\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n root.createComponent(View, {border: 'base', padding: 'base'}, 'View'),\n ],\n );\n\n root.appendChild(inlineStack);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "Link", + "description": "Link makes text interactive so customers can perform an action, such as navigating to another location.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "link-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "LinkProps", + "description": "", + "type": "LinkProps", + "typeDefinitions": { + "LinkProps": { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "name": "LinkProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "activateAction", + "value": "'auto' | 'copy'", + "description": "Sets the action the `activateTarget` should take when this pressable is activated.\n\nSupported actions by component:\n\n| Component | Supported Actions | Default ('auto') |\n|---------------|-------------------|-------------------|\n| [`ClipboardItem`](/docs/api/checkout-ui-extensions/latest/clipboarditem) | 'copy' | 'copy' |", + "isOptional": true, + "defaultValue": "'auto' - a default action for the target component." + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "activateTarget", + "value": "string", + "description": "ID of a component that should respond to activations (e.g. clicks) on this pressable.\n\nSee `activateAction` for how to control the behavior of the target.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'monochrome'", + "description": "Specify the color of the link. `monochrome` will take the color of its parent.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "external", + "value": "boolean", + "description": "Open the link in a new window or tab. If the link points to a domain other than your Storefront, it will always open in a new tab.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "Unique identifier.\n\nTypically used as a target for another component’s controls to associate an accessible label with an action.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "language", + "value": "string", + "description": "Indicate the text language. Useful when the text is in a different language than the rest of the page. It will allow assistive technologies such as screen readers to invoke the correct pronunciation. [Reference of values](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry) (\"subtag\" label)", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback when pressed. If `to` is set, it will execute the callback and then navigate to the location specified by `to`.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination to navigate to. You must provide either this property, `onPress`, or both.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Link/Link.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + } + ], + "value": "export interface LinkProps\n extends OverlayActivatorProps,\n DisclosureActivatorProps,\n InteractionProps {\n /**\n * Destination to navigate to. You must provide either this property, `onPress`,\n * or both.\n */\n to?: string;\n /**\n * Open the link in a new window or tab. If the link points to a domain other than your Storefront, it will always open in a new tab.\n */\n external?: boolean;\n /**\n * Unique identifier.\n *\n * Typically used as a target for another component’s controls\n * to associate an accessible label with an action.\n */\n id?: string;\n /**\n * Indicate the text language. Useful when the text is in a different language than the rest of the page.\n * It will allow assistive technologies such as screen readers to invoke the correct pronunciation.\n * [Reference of values](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry) (\"subtag\" label)\n */\n language?: string;\n /**\n * A label used for buyers using assistive technologies. When set, any\n * `children` supplied to this component will not be announced to screen reader users.\n */\n accessibilityLabel?: string;\n /**\n * Specify the color of the link.\n * `monochrome` will take the color of its parent.\n */\n appearance?: Extract;\n /**\n * Callback when pressed. If `to` is set, it will execute the callback and\n * then navigate to the location specified by `to`.\n */\n onPress?(): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Actions", + "defaultExample": { + "image": "link-default.png", + "codeblock": { + "title": "Basic Link", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Link,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Link to=\"https://www.shopify.ca/climate/sustainability-fund\">\n Sustainability fund\n </Link>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Link} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const link = root.createComponent(\n Link,\n {to: 'https://www.shopify.ca/climate/sustainability-fund'},\n 'Sustainability fund',\n );\n\n root.appendChild(link);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"monochrome\" | Takes the color of its parent.|" + }, + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- If the link isn’t in a paragraph, then consider using a plain button instead for a larger hit area.\n\n- Use links primarily for navigation and use buttons primarily for actions.\n\n- The HTML that renders for the Button and `Link` components includes style and accessibility information. Use these components intentionally and consistently to provide a more inclusive experience for assistive technology users and a more cohesive visual experience for sighted users." + } + ], + "related": [ + { + "name": "Button", + "subtitle": "Component", + "url": "button", + "type": "Component" + } + ] + }, + { + "name": "List", + "description": "Lists display a set of related content. Each list item usually begins with a bullet or a number.", + "requires": "", + "thumbnail": "list-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ListProps", + "description": "", + "type": "ListProps", + "typeDefinitions": { + "ListProps": { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "name": "ListProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the list. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "syntaxKind": "PropertySignature", + "name": "marker", + "value": "Marker", + "description": "Type of marker to display", + "isOptional": true, + "defaultValue": "'bullet'" + }, + { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "syntaxKind": "PropertySignature", + "name": "spacing", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust spacing between list items", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface ListProps extends IdProps {\n /**\n * Adjust spacing between list items\n *\n * @defaultValue 'base'\n */\n spacing?: MaybeResponsiveConditionalStyle;\n /**\n * Type of marker to display\n *\n * @defaultValue 'bullet'\n */\n marker?: Marker;\n /**\n * A label that describes the purpose or contents of the list. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n}" + }, + "Marker": { + "filePath": "src/surfaces/checkout/components/List/List.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Marker", + "value": "'none' | 'bullet' | 'number'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "list-default.png", + "codeblock": { + "title": "Basic List", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n List,\n ListItem,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <List>\n <ListItem>100% organic cotton</ListItem>\n <ListItem>Made in Canada</ListItem>\n <ListItem>Machine washable</ListItem>\n </List>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, List, ListItem} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const list = root.createComponent(List, undefined, [\n root.createComponent(ListItem, undefined, '100% organic cotton'),\n root.createComponent(ListItem, undefined, 'Made in Canada'),\n root.createComponent(ListItem, undefined, 'Machine washable'),\n ]);\n\n root.appendChild(list);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use lists to break up chunks of related content to make the information easier for customers to scan.\n\n- Phrase list items consistently. Try to start each item with a noun or a verb and be consistent with each item.\n\n- Use bullets for a text-only list of related items that don’t need to be in a specific order.\n\n- Use numbers for a text-only list of related items when you need to communicate order, priority, or sequence.\n\n- Don’t use a marker when only the semantic value of a list matters, such as with a list of links." + } + ], + "related": [ + { + "name": "ListItem", + "subtitle": "Component", + "url": "listItem", + "type": "Component" + } + ] + }, + { + "name": "ListItem", + "description": "List items are used as children of the `List` component.\n\nThey usually begins with a bullet or a number.", + "requires": "", + "thumbnail": "listitem-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "listitem-default.png", + "codeblock": { + "title": "Basic ListItem", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n List,\n ListItem,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <List>\n <ListItem>100% organic cotton</ListItem>\n </List>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, List, ListItem} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const list = root.createComponent(List, undefined, [\n root.createComponent(ListItem, undefined, '100% organic cotton'),\n ]);\n\n root.appendChild(list);\n});\n", + "language": "js" + } + ] + } + }, + "related": [ + { + "name": "List", + "subtitle": "Component", + "url": "list", + "type": "Component" + } + ] + }, + { + "name": "Map", + "description": "Use the Map component to provide visual representation of geographic data such as verifying address, package or pickup locations.\n\nPlease note that the merchant or partner has to provide an API key and a set of allowed domains where the map would render.\n\nThe 3 necessary domains needed are:\n\n- `https://*.[MERCHANT-DOMAIN].com`\n\n- `https://shop.app`\n\n- `https://shopify.com` \n\n Where `*` is a wildcard. Learn more about [match patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns).\n\n Please refer to the [Google Maps Platform documentation](https://developers.google.com/maps/documentation/javascript/get-api-key) for more details on how to get an API key.", + "requires": "", + "thumbnail": "map-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "MapProps", + "description": "", + "type": "MapProps", + "typeDefinitions": { + "MapProps": { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "name": "MapProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to describe the purpose of the map that is announced by screen readers." + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "apiKey", + "value": "string", + "description": "The Google Maps API key." + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "The id of the map. This is used to set a unique map id for the Google Maps API. If you don't provide an id, the map component will automatically create a unique one for every map. If you provide it, you need to make sure it's unique.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "latitude", + "value": "number", + "description": "The latitude of the center of the map." + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "longitude", + "value": "number", + "description": "The longitude of the center of the map." + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "maxZoom", + "value": "number", + "description": "The maximum zoom level of the map.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "minZoom", + "value": "number", + "description": "The minimum zoom level of the map.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "onBoundsChange", + "value": "(bounds: MapBounds) => void", + "description": "Callback to run when the map bounds change.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "onCenterChange", + "value": "(location: MapLocation) => void", + "description": "Callback to run when the map center changes.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "onDoublePress", + "value": "(location: MapLocation) => void", + "description": "Callback to run when the map is double clicked.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "onPress", + "value": "(location: MapLocation) => void", + "description": "Callback to run when the map is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "onZoomChange", + "value": "(zoom: MapZoom) => void", + "description": "Callback to run when the map zoom changes.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "zoom", + "value": "number", + "description": "The zoom level of the map. It must be a number between 0 and 18.", + "isOptional": true + } + ], + "value": "export interface MapProps\n extends Pick<\n SizingProps,\n 'maxBlockSize' | 'maxInlineSize' | 'minInlineSize' | 'minBlockSize'\n > {\n /**\n * The Google Maps API key.\n */\n apiKey: string;\n /**\n * The latitude of the center of the map.\n */\n latitude: number;\n /**\n * The longitude of the center of the map.\n */\n longitude: number;\n /**\n * The id of the map. This is used to set a unique map id for the Google Maps API.\n * If you don't provide an id, the map component will automatically create a unique one for every map.\n * If you provide it, you need to make sure it's unique.\n */\n id?: string;\n /**\n * The zoom level of the map. It must be a number between 0 and 18.\n */\n zoom?: number;\n /**\n * The minimum zoom level of the map.\n */\n minZoom?: number;\n /**\n * The maximum zoom level of the map.\n */\n maxZoom?: number;\n /**\n * A label to describe the purpose of the map that is announced by screen readers.\n */\n accessibilityLabel: string;\n /**\n * Callback to run when the map bounds change.\n */\n onBoundsChange?: (bounds: MapBounds) => void;\n /**\n * Callback to run when the map center changes.\n */\n onCenterChange?: (location: MapLocation) => void;\n /**\n * Callback to run when the map is pressed.\n */\n onPress?: (location: MapLocation) => void;\n /**\n * Callback to run when the map is double clicked.\n */\n onDoublePress?: (location: MapLocation) => void;\n /**\n * Callback to run when the map zoom changes.\n */\n onZoomChange?: (zoom: MapZoom) => void;\n}" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MapBounds": { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "name": "MapBounds", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "northEast", + "value": "MapLocation", + "description": "" + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "southWest", + "value": "MapLocation", + "description": "" + } + ], + "value": "export interface MapBounds {\n northEast: MapLocation;\n southWest: MapLocation;\n}" + }, + "MapLocation": { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "name": "MapLocation", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "latitude", + "value": "number", + "description": "" + }, + { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "PropertySignature", + "name": "longitude", + "value": "number", + "description": "" + } + ], + "value": "export interface MapLocation {\n latitude: number;\n longitude: number;\n}" + }, + "MapZoom": { + "filePath": "src/surfaces/checkout/components/Map/Map.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MapZoom", + "value": "1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "map-default.png", + "codeblock": { + "title": "Basic Map", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Map,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Map\n apiKey=\"YOUR_GOOGLE_MAPS_API_KEY\"\n latitude={-28.024}\n longitude={140.887}\n zoom={4}\n accessibilityLabel=\"Map showing pickup locations\"\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Map} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const map = root.createComponent(Map, {\n apiKey: 'YOUR_API_KEY',\n accessibilityLabel: 'Map showing pickup locations',\n latitude: -28.024,\n longitude: 140.887,\n zoom: 4,\n });\n\n root.appendChild(map);\n});\n", + "language": "js" + } + ] + } + }, + "related": [ + { + "name": "MapMarker", + "subtitle": "Component", + "url": "mapmarker", + "type": "Component" + }, + { + "name": "MapPopover", + "subtitle": "Component", + "url": "mappopover", + "type": "Component" + } + ] + }, + { + "name": "MapMarker", + "description": "MapMarker represents a specific location or point of interest on a map.", + "requires": "", + "thumbnail": "mapmarker-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "MapMarkerProps", + "description": "", + "type": "MapMarkerProps", + "typeDefinitions": { + "MapMarkerProps": { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "name": "MapMarkerProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "The accessibility label of the marker." + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "blockSize", + "value": "number", + "description": "The block size of the icon. This property is only used when the `icon` property is set.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "clusterable", + "value": "boolean", + "description": "Set to `true` to allow grouping the marker in clusters when zoomed out.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "icon", + "value": "string", + "description": "The URL of the icon to use for the marker.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "inlineSize", + "value": "number", + "description": "The inline size of the icon. This property is only used when the `icon` property is set.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "latitude", + "value": "number", + "description": "The latitude of the marker." + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "longitude", + "value": "number", + "description": "The longitude of the marker." + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the marker is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapMarker/MapMarker.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + } + ], + "value": "export interface MapMarkerProps extends OverlayActivatorProps {\n /**\n * The latitude of the marker.\n */\n latitude: number;\n /**\n * The longitude of the marker.\n */\n longitude: number;\n /**\n * The accessibility label of the marker.\n */\n accessibilityLabel: string;\n /**\n * Set to `true` to allow grouping the marker in clusters when zoomed out.\n */\n clusterable?: boolean;\n /**\n * Callback that is run when the marker is pressed.\n */\n onPress?(): void;\n /**\n * The URL of the icon to use for the marker.\n */\n icon?: string;\n /**\n * The block size of the icon.\n * This property is only used when the `icon` property is set.\n */\n blockSize?: number;\n /**\n * The inline size of the icon.\n * This property is only used when the `icon` property is set.\n */\n inlineSize?: number;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "mapmarker-default.png", + "codeblock": { + "title": "Basic MapMarker", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Map,\n MapMarker,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Map\n apiKey=\"YOUR_GOOGLE_MAPS_API_KEY\"\n latitude={-28.024}\n longitude={140.887}\n zoom={4}\n accessibilityLabel=\"Map\"\n >\n <MapMarker\n latitude={-28.024}\n longitude={140.887}\n accessibilityLabel=\"Map marker for Innamincka, Australia\"\n />\n </Map>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Map, MapMarker} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const map = root.createComponent(\n Map,\n {\n apiKey: 'YOUR_API_KEY',\n accessibilityLabel: 'Map',\n latitude: -28.024,\n longitude: 140.887,\n zoom: 4,\n },\n [\n root.createComponent(MapMarker, {\n latitude: -28.024,\n longitude: 140.887,\n accessibilityLabel: 'Map marker for Innamincka, Australia',\n }),\n ],\n );\n\n root.appendChild(map);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- If your markers are interactive, make sure that the selected marker's icon is different from the rest of the non-selected markers.\n\n- If there are a large number of markers obscuring important features of the map, set the markers to clusterable to help increase the readability of the map." + } + ], + "related": [ + { + "name": "Map", + "subtitle": "Component", + "url": "map", + "type": "Component" + }, + { + "name": "MapPopover", + "subtitle": "Component", + "url": "mappopover", + "type": "Component" + } + ] + }, + { + "name": "MapPopover", + "description": "MapPopover provides additional information or context about a specific location or point of interest on a map.", + "requires": "", + "thumbnail": "mappopover-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "MapPopoverProps", + "description": "", + "type": "MapPopoverProps", + "typeDefinitions": { + "MapPopoverProps": { + "filePath": "src/surfaces/checkout/components/MapPopover/MapPopover.ts", + "name": "MapPopoverProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/MapPopover/MapPopover.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapPopover/MapPopover.ts", + "syntaxKind": "MethodSignature", + "name": "onClose", + "value": "() => void", + "description": "Callback to run when the Popover is closed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/MapPopover/MapPopover.ts", + "syntaxKind": "MethodSignature", + "name": "onOpen", + "value": "() => void", + "description": "Callback to run when the Popover is opened.", + "isOptional": true + } + ], + "value": "export interface MapPopoverProps extends IdProps {\n /**\n * Callback to run when the Popover is closed.\n */\n onClose?(): void;\n /**\n * Callback to run when the Popover is opened.\n */\n onOpen?(): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "mappopover-default.png", + "codeblock": { + "title": "Basic MapPopover", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Map,\n MapMarker,\n MapPopover,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Map\n apiKey=\"YOUR_GOOGLE_MAPS_API_KEY\"\n latitude={-28.024}\n longitude={140.887}\n zoom={4}\n accessibilityLabel=\"Map\"\n >\n <MapMarker\n latitude={-28.024}\n longitude={140.887}\n accessibilityLabel=\"Map marker for Innamincka, Australia\"\n overlay={\n <MapPopover>\n Blue Mountains National Park store\n </MapPopover>\n }\n />\n </Map>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Map,\n MapMarker,\n MapPopover,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const popoverFragment = root.createFragment();\n const popover = root.createComponent(\n MapPopover,\n {},\n 'Blue Mountains National Park store',\n );\n popoverFragment.appendChild(popover);\n const map = root.createComponent(\n Map,\n {\n apiKey: 'YOUR_API_KEY',\n accessibilityLabel: 'Map',\n latitude: -28.024,\n longitude: 140.887,\n zoom: 4,\n },\n [\n root.createComponent(MapMarker, {\n latitude: -28.024,\n longitude: 140.887,\n accessibilityLabel: 'Map marker for Innamincka, Australia',\n overlay: popoverFragment,\n }),\n ],\n );\n\n root.appendChild(map);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use to display relevant details such as the name, address, description, or other pertinent information related to the location.\n\n- Ensure that the content displayed in the map popover is brief, relevant, and easy to understand.\n\n- Maintain visual consistency with the overall design of the checkout. " + } + ], + "related": [ + { + "name": "Map", + "subtitle": "Component", + "url": "map", + "type": "Component" + }, + { + "name": "MapMarker", + "subtitle": "Component", + "url": "mapmarker", + "type": "Component" + } + ] + }, + { + "name": "Menu", + "description": "Use a menu to display a list of actions in a popover. Actions can open a modal, trigger an event, or link to an external page.", + "thumbnail": "menu-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "MenuProps", + "description": "", + "type": "MenuProps", + "typeDefinitions": { + "MenuProps": { + "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "name": "MenuProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to describe the purpose of the menu that is announced by screen readers.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "syntaxKind": "PropertySignature", + "name": "onClose", + "value": "() => void", + "description": "Callback to run when the Menu is closed", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Menu/Menu.ts", + "syntaxKind": "PropertySignature", + "name": "onOpen", + "value": "() => void", + "description": "Callback to run when the Menu is opened", + "isOptional": true + } + ], + "value": "export interface MenuProps extends IdProps {\n /**\n * A label to describe the purpose of the menu that is announced by screen readers.\n */\n accessibilityLabel?: string;\n /**\n * Callback to run when the Menu is opened\n */\n onOpen?: () => void;\n /**\n * Callback to run when the Menu is closed\n */\n onClose?: () => void;\n}" + } + } + }, + { + "title": "ButtonProps children", + "description": "The Menu component exclusively accepts Button elements with restricted props as its children. The `appearance` prop will always be set to monochrome by default.", + "type": "Docs_Menu_Button_Action", + "typeDefinitions": { + "Docs_Menu_Button_Action": { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "name": "Docs_Menu_Button_Action", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ButtonAccessibilityRole", + "description": "The role of the button that will be rendered.\n\n`button`: renders a regular button.\n\n`submit`: renders a button that submits a form.", + "isOptional": true, + "defaultValue": "'button'" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "activateAction", + "value": "'auto' | 'copy'", + "description": "Sets the action the `activateTarget` should take when this pressable is activated.\n\nSupported actions by component:\n\n| Component | Supported Actions | Default ('auto') |\n|---------------|-------------------|-------------------|\n| [`ClipboardItem`](/docs/api/checkout-ui-extensions/latest/clipboarditem) | 'copy' | 'copy' |", + "isOptional": true, + "defaultValue": "'auto' - a default action for the target component." + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "activateTarget", + "value": "string", + "description": "ID of a component that should respond to activations (e.g. clicks) on this pressable.\n\nSee `activateAction` for how to control the behavior of the target.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'critical' | 'monochrome'", + "description": "Specify the color treatment of the Button.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Replaces content with a loading indicator.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loadingLabel", + "value": "string", + "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "submit", + "value": "boolean", + "description": "Allows the button to submit a form.", + "isOptional": true, + "deprecationMessage": "use `accessibilityRole=\"submit\"` instead" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + } + ], + "value": "export interface Docs_Menu_Button_Action\n extends Omit<\n ButtonProps,\n 'kind' | 'textDecoration' | 'inlineAlignment' | 'inlineSize' | 'size'\n > {}" + }, + "ButtonAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ButtonAccessibilityRole", + "value": "'button' | 'submit'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Actions", + "defaultExample": { + "image": "menu-default.png", + "altText": "An example of a Menu with three actions.", + "codeblock": { + "title": "Basic Menu", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Button,\n Menu,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <Button\n overlay={\n <Menu>\n <Button\n onPress={() =>\n console.log('Submit problem')\n }\n >\n Submit problem\n </Button>\n <Button to=\"https://shopify.com\">\n Request return\n </Button>\n <Button appearance=\"critical\">\n Cancel order\n </Button>\n </Menu>\n }\n >\n Manage\n </Button>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {Menu, Button, extension} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root, api) => {\n renderApp(root, api);\n});\n\nasync function renderApp(root, api) {\n const menuFragment = root.createFragment();\n const menu = root.createComponent(Menu, {}, [\n root.createComponent(\n Button,\n {onPress: () => console.log('Submit problem')},\n 'Submit problem',\n ),\n root.createComponent(Button, {to: 'https://shopify.com'}, 'Request return'),\n root.createComponent(Button, {appearance: 'critical'}, 'Cancel order'),\n ]);\n menuFragment.appendChild(menu);\n const button = root.createComponent(\n Button,\n {overlay: menuFragment},\n 'Manage',\n );\n\n root.appendChild(button);\n}\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n### Consolidate actions into one menu\n\n- Use the menu component in the upper-right corner of full-page extensions, to be consistent with the **Order status** page.\n- Use menus to consolidate page-level actions, instead of adding multiple buttons around the page.\n\n![The “Don’t do” example shows 3 separate action buttons on a subscription page. The “Do” example shows the same 3 actions consolidated into one menu.](/assets/templated-apis-screenshots/customer-account-ui-extensions/unstable/menu-dont-do.png)\n\n### Content guidelines\n\nWhen writing button labels:\n- Aim for 2 words (verb and noun).\n- Lead with a strong verb that encourages action.\n- Avoid unnecessary words and articles such as “the,” “an,” or “a.”\n- Use sentence case.\n\n![A button that follows the content guidelines says “Skip order”. A button that does not meet the content guidelines says “Skip this order”.](/assets/templated-apis-screenshots/customer-account-ui-extensions/unstable/menu-labels.png)\n" + } + ], + "related": [ + { + "name": "Popover", + "subtitle": "Component", + "url": "../../../checkout-ui-extensions/unstable/components/overlays/popover", + "type": "Component" + } + ] + }, + { + "name": "Modal", + "description": "Modals are a special type of overlay that shift focus towards a specific action/set of information before the main flow can proceed. They must be specified inside the `overlay` prop of an activator component (`Button`, `Link` or `Pressable`).\n\nThe library automatically applies the [WAI-ARIA Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) to both the activator and the modal content.", + "requires": "", + "thumbnail": "modal-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ModalProps", + "description": "", + "type": "ModalProps", + "typeDefinitions": { + "ModalProps": { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "name": "ModalProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to describe the purpose of the modal that is announced by screen readers. If not set, it will use the value of `title`.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the Modal. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "onClose", + "value": "() => void", + "description": "Callback when the modal is closed. That is when either the close button, the backdrop, or the `escape` key are pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "onOpen", + "value": "() => void", + "description": "Callback when the modal is opened. This is called at the beginning of the transition that opens the modal.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "boolean", + "description": "Adds a default spacing around both header (which holds the `title`) and content of the modal.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "primaryAction", + "value": "RemoteFragment", + "description": "The primary action to perform, provided as a `Button` component. The property allows only one button to be rendered.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "secondaryActions", + "value": "RemoteFragment", + "description": "The secondary action to perform, provided as a `Button` component. The property allows only one button to be rendered.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "'small' | 'auto' | 'large' | 'max'", + "description": "Adjust the size of the Modal.\n\n`max`: expands the Modal to its maximum size, on both the horizontal and vertical axes.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/Modal/Modal.ts", + "syntaxKind": "PropertySignature", + "name": "title", + "value": "string", + "description": "A title rendered at the top of the modal.", + "isOptional": true + } + ], + "value": "export interface ModalProps {\n /**\n * A unique identifier for the Modal. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n /**\n * Callback when the modal is closed. That is when either the close button, the backdrop,\n * or the `escape` key are pressed.\n */\n onClose?: () => void;\n /**\n * Callback when the modal is opened. This is called at the beginning of the transition\n * that opens the modal.\n */\n onOpen?: () => void;\n /**\n * A title rendered at the top of the modal.\n */\n title?: string;\n /**\n * A label to describe the purpose of the modal that is announced by screen readers.\n * If not set, it will use the value of `title`.\n */\n accessibilityLabel?: string;\n /**\n * Adds a default spacing around both header (which holds the `title`) and content of the modal.\n */\n padding?: boolean;\n /**\n * Adjust the size of the Modal.\n *\n * `max`: expands the Modal to its maximum size, on both the horizontal and vertical axes.\n *\n * @default 'auto'\n */\n size?: 'small' | 'auto' | 'large' | 'max';\n /**\n * The primary action to perform, provided as a `Button` component.\n * The property allows only one button to be rendered.\n */\n primaryAction?: RemoteFragment;\n /**\n * The secondary action to perform, provided as a `Button` component.\n * The property allows only one button to be rendered.\n */\n secondaryActions?: RemoteFragment;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Overlays", + "defaultExample": { + "image": "modal-default.png", + "codeblock": { + "title": "Basic Modal", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n useApi,\n Button,\n Link,\n Modal,\n TextBlock,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n const {ui} = useApi();\n\n return (\n <Link\n overlay={\n <Modal\n id=\"my-modal\"\n padding\n title=\"Return policy\"\n >\n <TextBlock>\n We have a 30-day return policy, which\n means you have 30 days after receiving\n your item to request a return.\n </TextBlock>\n <TextBlock>\n To be eligible for a return, your item\n must be in the same condition that you\n received it, unworn or unused, with\n tags, and in its original packaging.\n You’ll also need the receipt or proof\n of purchase.\n </TextBlock>\n <Button\n onPress={() =>\n ui.overlay.close('my-modal')\n }\n >\n Close\n </Button>\n </Modal>\n }\n >\n Return policy\n </Link>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Button,\n Link,\n Modal,\n TextBlock,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root, {ui}) => {\n const modalFragment = root.createFragment();\n const modal = root.createComponent(\n Modal,\n {id: 'my-modal', title: 'Return policy', padding: true},\n [\n root.createComponent(\n TextBlock,\n undefined,\n 'We have a 30-day return policy, which means you have 30 days after receiving your item to request a return.',\n ),\n root.createComponent(\n TextBlock,\n undefined,\n 'To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase.',\n ),\n root.createComponent(\n Button,\n {\n onPress() {\n ui.overlay.close('my-modal');\n },\n },\n 'Close',\n ),\n ],\n );\n modalFragment.appendChild(modal);\n const link = root.createComponent(\n Link,\n {overlay: modalFragment},\n 'Return policy',\n );\n\n root.appendChild(link);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "Use modals if:\n\n- The information needed to be shown is not critical in completing the checkout process and information cannot be condensed into one sentence.\n\n- The information the buyer is entering requires less than two rows of input fields.\n\n- The information the buyer is entering is not reliant on information on the page (which is underneath the modal and not visible to them)." + } + ], + "related": [ + { + "name": "Ui", + "subtitle": "API", + "url": "ui", + "type": "API" + } + ] + }, + { + "name": "Page", + "description": "The outer wrapper of the page—including the page title, subtitle, and page-level actions—displayed in a familiar and consistent style that sets expectations about the purpose of the page.", + "thumbnail": "page-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "PageProps", + "description": "", + "type": "PageProps", + "typeDefinitions": { + "PageProps": { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "name": "PageProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Indicates that the page is in a loading state.\n\nWhen `true`, the page shows loading indicators for the UI elements that it is owns. The page is not responsible for the loading indicators of any content that is passed as `children`.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "primaryAction", + "value": "RemoteFragment", + "description": "The action grouping, provided as button(s), that is placed in the primary position of the page.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "primaryActionAccessibilityLabel", + "value": "string", + "description": "Accessibility label for the primary action grouping. If an accessibility label is not provided, default text is used.", + "isOptional": true, + "defaultValue": "\"More actions\"" + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "primaryActionLabel", + "value": "string", + "description": "Label for the primary action grouping. If a label is not provided, default text is used.", + "isOptional": true, + "defaultValue": "\"More actions\"" + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "secondaryAction", + "value": "RemoteFragment", + "description": "The action grouping, provided as button(s), that is placed in the secondary position of the page.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "subtitle", + "value": "string", + "description": "The text to be used as subtitle.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/Page/Page.ts", + "syntaxKind": "PropertySignature", + "name": "title", + "value": "string", + "description": "The text to be used as title." + } + ], + "value": "export interface PageProps {\n /**\n * The text to be used as title.\n */\n title: string;\n\n /**\n * The text to be used as subtitle.\n */\n subtitle?: string;\n\n /**\n * The action grouping, provided as button(s), that is placed in the primary position of the page.\n */\n primaryAction?: RemoteFragment;\n\n /**\n * Label for the primary action grouping. If a label is not provided, default text is used.\n *\n * @defaultValue \"More actions\"\n */\n primaryActionLabel?: string;\n\n /**\n * Accessibility label for the primary action grouping. If an accessibility label is not provided,\n * default text is used.\n *\n * @defaultValue \"More actions\"\n */\n primaryActionAccessibilityLabel?: string;\n\n /**\n * The action grouping, provided as button(s), that is placed in the secondary position of the page.\n */\n secondaryAction?: RemoteFragment;\n\n /**\n * Indicates that the page is in a loading state.\n *\n * When `true`, the page shows loading indicators for the UI elements that it is owns.\n * The page is not responsible for the loading indicators of any content that is passed as `children`.\n *\n * @defaultValue false\n */\n loading?: boolean;\n}" + } + } + }, + { + "title": "ButtonProps primaryAction", + "description": "Supported props for Buttons used inside Page `primaryAction` prop.

    `children` only support text.", + "type": "Docs_Page_Button_PrimaryAction", + "typeDefinitions": { + "Docs_Page_Button_PrimaryAction": { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "name": "Docs_Page_Button_PrimaryAction", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Replaces content with a loading indicator.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loadingLabel", + "value": "string", + "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to.", + "isOptional": true + } + ], + "value": "export interface Docs_Page_Button_PrimaryAction\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'overlay'\n | 'to'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n > {}" + } + } + }, + { + "title": "ButtonProps secondaryAction", + "description": "Supported props for Button used inside Page `secondaryAction` prop.

    `children` are not supported.
    Use `accessibilityLabel` instead.", + "type": "Docs_Page_Button_SecondaryAction", + "typeDefinitions": { + "Docs_Page_Button_SecondaryAction": { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "name": "Docs_Page_Button_SecondaryAction", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. Needed because `children` passed to this component will be discarded." + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to.", + "isOptional": true + } + ], + "value": "export interface Docs_Page_Button_SecondaryAction\n extends Pick {\n /**\n * A label used for buyers using assistive technologies. Needed because `children` passed to this component will be discarded.\n */\n accessibilityLabel: ButtonProps['accessibilityLabel'];\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "page-preview.png", + "altText": "An example of how the Page component is used to structure the page title, description, order action buttons on the Order status page.", + "codeblock": { + "title": "Basic Page", + "tabs": [ + { + "title": "React", + "code": "import {\n Page,\n Button,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension('customer-account.page.render', () => <App />);\n\nfunction App() {\n return (\n <Page\n title=\"Order #1411\"\n subtitle=\"Confirmed Oct 5\"\n secondaryAction={<Button accessibilityLabel=\"Button\" onPress={() => {}}/>}\n primaryActionLabel=\"Manage\"\n primaryAction={\n <>\n <Button onPress={() => {}}>Buy again</Button>\n <Button onPress={() => {}}>Second action</Button>\n <Button onPress={() => {}}>Third action</Button>\n </>\n }\n >\n Content\n </Page>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n Page,\n Button,\n extension\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nasync function renderApp(root, api) {\n const primaryAction = root.createFragment();\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 1\")}}, 'Buy again primary 1'));\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 2\")}}, 'Buy again primary 2'));\n await primaryAction.append(root.createComponent(Button, {onPress: () => {console.log(\"primary action 3\")}}, 'Buy again primary 3'));\n\n const secondaryAction = root.createFragment();\n await secondaryAction.append(root.createComponent(Button, {accessibilityLabel: 'Button', onPress: () => {}}))\n\n const page = root.createComponent(\n Page,\n {\n title: \"Order #1411\",\n subtitle: \"Confirmed Oct 5\",\n primaryAction,\n primaryActionLabel: \"Manage\",\n secondaryAction,\n },\n root.createComponent('View', {}, \"Content\")\n )\n root.append(page);\n}\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n**Title**\n- Set clear expectations about the purpose and main topic of the page.\n- Aim for 1-3 words.\n- Use sentence case.\n\n**Subtitle**\n- Use to provide additional context or information that enhances the customer’s understanding of the page.\n- Use subtitles sparingly and only when they add useful information that is distinct from the title.\n\n**Buttons**\n- Use for page-level actions only.\n- If there is a single primary action for the page, display it as a primary button. Display all other page-level actions as secondary buttons.\n- See [UX guidelines](/docs/apps/customer-accounts/order-action-menu-extensions/ux-guidelines) to learn more about the button logic for order actions.\n" + } + ], + "related": [] + }, + { + "name": "PaymentIcon", + "description": "Payment icons can be used for displaying payment-related information or features such as a user’s saved or available payment methods.", + "thumbnail": "paymenticon-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "PaymentIconProps", + "description": "", + "type": "PaymentIconProps", + "typeDefinitions": { + "PaymentIconProps": { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "name": "PaymentIconProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the icon.\n\nWhen set, it will be announced to users using assistive technologies and will provide them with more context. This should only be used if the icon requires an alternative internationalised label or if it is otherwise inappropriate to make use of the default label included with the icon.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityVisibility", + "value": "'hidden' | 'visible'", + "description": "Changes the visibility of the icon to assistive technologies.\n\n`hidden` hides the component from assistive technology (for example, a screen reader) but remains visually visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "PaymentMethod | string", + "description": "The name of the payment method.\n\nCheck the list of available payment methods [here](/docs/api/checkout-ui-extensions/components/media/paymenticon#paymentmethod)." + } + ], + "value": "export interface PaymentIconProps {\n /**\n * The name of the payment method.\n *\n * Check the list of available payment methods [here](/docs/api/checkout-ui-extensions/components/media/paymenticon#paymentmethod).\n */\n name: PaymentMethod | string;\n\n /**\n * A label that describes the purpose or contents of the icon.\n *\n * When set, it will be announced to users using assistive technologies and will provide them with more context.\n * This should only be used if the icon requires an alternative internationalised label\n * or if it is otherwise inappropriate to make use of the default label included with the icon.\n */\n accessibilityLabel?: string;\n\n /**\n * Changes the visibility of the icon to assistive technologies.\n *\n * `hidden` hides the component from assistive technology (for example,\n * a screen reader) but remains visually visible.\n *\n * @defaultValue 'visible'\n */\n accessibilityVisibility?: 'hidden' | 'visible';\n}" + }, + "PaymentMethod": { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "PaymentMethod", + "value": "'7-eleven' | 'acima-leasing' | 'addi' | 'aeropay' | 'affin-bank' | 'affirm' | 'aftee' | 'afterpay-paynl-version' | 'afterpay' | 'airtel-money' | 'airteltigo-mobile-money' | 'aktia' | 'akulaku-paylater' | 'akulaku' | 'alandsbanken' | 'alfamart' | 'alfamidi' | 'alipay-hk' | 'alipay-paynl-version' | 'alipay' | 'alliance-bank' | 'alma' | 'amazon' | 'ambank' | 'american-express' | 'anyday' | 'apecoin' | 'aplazo' | 'apple-pay' | 'aqsat' | 'arhaus' | 'arvato' | 'ask' | 'astrapay' | 'atm-bersama' | 'atobaraidotcom' | 'atome' | 'atone' | 'atrato' | 'au-kantan-kessai' | 'axs' | 'bancnet' | 'bancontact' | 'bangkok-bank' | 'bank-islam' | 'bank-muamalat' | 'bank-rakyat' | 'bbva-cie' | 'bc-card' | 'bca-klikpay' | 'bca' | 'bdo' | 'belfius' | 'benefit' | 'biercheque-paynl-version' | 'bigc' | 'billease' | 'biller-paynl-version' | 'billie' | 'billink-method' | 'billink' | 'bitcoin-cash' | 'bitcoin' | 'bizum' | 'blik' | 'bnbchain' | 'bni' | 'bogus-app-coin' | 'boleto' | 'boost' | 'bpi' | 'bread-pay' | 'bread' | 'bri-direct-debit' | 'bri' | 'brimo' | 'bsi' | 'bsn' | 'bss' | 'busd' | 'careem-pay' | 'cartes-bancaires' | 'cash-app-pay' | 'catch-payments' | 'cebuana' | 'cetelem' | 'checkout-finance' | 'cimb-clicks' | 'cimb' | 'circle-k' | 'citadele' | 'clave-telered' | 'clearpay' | 'cleverpay' | 'cliq' | 'coinsph' | 'collector-bank' | 'coop' | 'coppel-pay' | 'credit-key' | 'creditclick-paynl-version' | 'credix' | 'd-barai' | 'dai' | 'daily-yamazaki' | 'dan-dan' | 'dana' | 'danamon-online' | 'dankort' | 'danske-bank' | 'dash' | 'depay' | 'deutsche-bank' | 'diners-club' | 'directpay' | 'discover' | 'divido' | 'dnb' | 'docomo-barai' | 'dogecoin' | 'dropp' | 'duologi' | 'dwolla' | 'ebucks' | 'echelon-financing' | 'ecpay' | 'eft-secure' | 'eghl' | 'elo' | 'elv' | 'enets' | 'eos' | 'epayments' | 'epospay' | 'eps' | 'esr-paymentslip-switzerland' | 'ethereum' | 'etika' | 'facebook-pay' | 'fairstone-payments' | 'familymart' | 'farmlands' | 'fashion-giftcard-paynlversion' | 'fashioncheque' | 'fawry' | 'finloup' | 'fintecture' | 'flexiti' | 'forbrugsforeningen' | 'fortiva' | 'fps' | 'fpx' | 'freecharge' | 'futurepay-mytab' | 'gcash' | 'generalfinancing' | 'genoapay' | 'gezondheidsbon-paynl-version' | 'giftcard' | 'giropay' | 'givacard' | 'gmo-bank-transfer' | 'gmo-postpay' | 'google-pay' | 'google-wallet' | 'gopay' | 'grabpay' | 'grailpay' | 'gusd' | 'hana-card' | 'handelsbanken' | 'hello-clever' | 'hong-leong-bank' | 'hong-leong-connect' | 'hsbc' | 'humm' | 'hyper' | 'hypercard' | 'hypercash' | 'hyundai-card' | 'ideal' | 'in3' | 'inbank' | 'indomaret' | 'ing-homepay' | 'interac' | 'ivy' | 'jcb' | 'jousto' | 'kakao-pay' | 'kakebaraidotcom' | 'kasikornbank' | 'kb-card' | 'kbc-cbc' | 'kfast' | 'klarna-pay-later' | 'klarna-pay-now' | 'klarna-slice-it' | 'klarna' | 'knet' | 'krediidipank' | 'kredivo' | 'krungsri' | 'krungthai-bank' | 'kueski-pay' | 'kunst-en-cultuur-cadeaukaart' | 'kuwait-finance-house' | 'laser' | 'latitude-creditline-au' | 'latitude-gem-au' | 'latitude-gem-nz' | 'latitude-go-au' | 'latitudepay' | 'lawson' | 'laybuy-heart' | 'laybuy' | 'lbc' | 'lhv' | 'line-pay' | 'linkaja' | 'linkpay' | 'litecoin' | 'lku' | 'lotte-card' | 'luminor' | 'lydia' | 'mada' | 'maestro' | 'mandiri' | 'mash' | 'master' | 'masterpass' | 'maxima' | 'maya-bank' | 'maya' | 'maybank-qrpay' | 'maybank' | 'maybankm2u' | 'mb-way' | 'mb' | 'mcash' | 'medicinos-bankas' | 'meeza' | 'merpay' | 'meta-pay' | 'ministop' | 'mobicred' | 'mobikwik' | 'mobilepay' | 'mode' | 'mokka' | 'momopay' | 'mondido' | 'monero' | 'mpesa' | 'mtn-mobile-money' | 'myfatoorah' | 'n26' | 'naps' | 'nationale-bioscoopbon' | 'nationale-entertainmentcard' | 'naver-pay' | 'nelo' | 'netbanking' | 'neteller' | 'nh-card' | 'nordea' | 'novuna' | 'ocbc-bank' | 'octo-clicks' | 'ola-money' | 'omasp' | 'op' | 'opay' | 'openpay' | 'ovo' | 'oxxo' | 'ozow' | 'pagoefectivo' | 'paid' | 'paidy' | 'palawa' | 'palawan' | 'pay-easy' | 'pay-pay' | 'paybylink' | 'payco' | 'payconiq' | 'payd' | 'payfast-instant-eft' | 'payflex' | 'payid' | 'paymark-online-eftpos' | 'paymaya' | 'payme' | 'paynow' | 'paypal' | 'payplan' | 'paypo' | 'paysafecard-paynl-version' | 'paysafecard' | 'paysafecash' | 'paysera' | 'paytm' | 'payto' | 'paytomorrow' | 'payu' | 'payzapp' | 'pei' | 'perlasfinance' | 'permata' | 'pivo' | 'pix' | 'podium-cadeaukaart' | 'poli' | 'polygon' | 'poppankki' | 'postfinance-card' | 'postfinance-efinance' | 'postpay' | 'pps' | 'przelew24' | 'przelewy24-paynl-version' | 'public-bank' | 'publicbank-pbe' | 'qr-promptpay' | 'qris' | 'qrph' | 'rabbit-line-pay' | 'rakuten-pay' | 'rapid-transfer' | 'ratepay' | 'rcbc' | 'rcs' | 'revolut' | 'rhb-bank' | 'rhb-now' | 'rietumu' | 'riverty-paynl-version' | 'rupay' | 'saastopankki' | 'sadad' | 'sam' | 'samsung-card' | 'samsung-pay' | 'santander' | 'satisfi' | 'satispay' | 'sbpl' | 'scalapay' | 'seb' | 'sepa-bank-transfer' | 'sequra' | 'sezzle' | 'shib' | 'shinhan-card' | 'shopeepay' | 'shopify-pay' | 'siam-commercial' | 'siauliu-bankas' | 'siirto' | 'sinpe-movil' | 'skrill-digital-wallet' | 'smartpay' | 'snap-checkout' | 'sofort' | 'softbank' | 'solanapay' | 'spankki' | 'spei' | 'splitit' | 'spotii' | 'spraypay' | 'standard-chartered' | 'stc-pay' | 'sunkus' | 'svea-b2b-faktura' | 'svea-b2b-invoice' | 'svea-credit-account' | 'svea-delbetalning' | 'svea-faktura' | 'svea-invoice' | 'svea-lasku' | 'svea-ostukonto' | 'svea-part-payment' | 'svea-yrityslasku' | 'sveaeramaksu' | 'swedbank' | 'swiftpay' | 'swish' | 'swissbilling' | 'synchrony-pay' | 'synchrony' | 'tabby' | 'tabit' | 'tamara' | 'tandympayment' | 'tbi-bank' | 'tendopay' | 'tensile' | 'tesco-lotus' | 'thanachart-bank' | 'toss' | 'touch-n-go' | 'trevipay' | 'truemoney-pay' | 'trustly' | 'twig-pay' | 'twint' | 'uae-visa' | 'uangme' | 'ubp' | 'unionpay' | 'unipay' | 'uob-ez-pay' | 'uob-thai' | 'uob' | 'upi' | 'urpay' | 'usdc' | 'usdp' | 'v-pay' | 'valu' | 'venmo' | 'viabill' | 'vipps' | 'visa-electron' | 'visa' | 'vvv-cadeaukaart-paynl-version' | 'vvv-giftcard' | 'walley' | 'wbtc' | 'webshop-giftcard' | 'wechat-pay' | 'wechat-paynl-version' | 'wegetfinancing' | 'xrp' | 'ymobile' | 'younited-pay' | 'zalopay' | 'zapper' | 'zinia' | 'zip' | 'zoodpay'", + "description": "" + } + } + }, + { + "title": "PaymentMethod", + "description": "", + "type": "PaymentMethod", + "typeDefinitions": { + "PaymentMethod": { + "filePath": "src/surfaces/checkout/components/PaymentIcon/PaymentIcon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "PaymentMethod", + "value": "'7-eleven' | 'acima-leasing' | 'addi' | 'aeropay' | 'affin-bank' | 'affirm' | 'aftee' | 'afterpay-paynl-version' | 'afterpay' | 'airtel-money' | 'airteltigo-mobile-money' | 'aktia' | 'akulaku-paylater' | 'akulaku' | 'alandsbanken' | 'alfamart' | 'alfamidi' | 'alipay-hk' | 'alipay-paynl-version' | 'alipay' | 'alliance-bank' | 'alma' | 'amazon' | 'ambank' | 'american-express' | 'anyday' | 'apecoin' | 'aplazo' | 'apple-pay' | 'aqsat' | 'arhaus' | 'arvato' | 'ask' | 'astrapay' | 'atm-bersama' | 'atobaraidotcom' | 'atome' | 'atone' | 'atrato' | 'au-kantan-kessai' | 'axs' | 'bancnet' | 'bancontact' | 'bangkok-bank' | 'bank-islam' | 'bank-muamalat' | 'bank-rakyat' | 'bbva-cie' | 'bc-card' | 'bca-klikpay' | 'bca' | 'bdo' | 'belfius' | 'benefit' | 'biercheque-paynl-version' | 'bigc' | 'billease' | 'biller-paynl-version' | 'billie' | 'billink-method' | 'billink' | 'bitcoin-cash' | 'bitcoin' | 'bizum' | 'blik' | 'bnbchain' | 'bni' | 'bogus-app-coin' | 'boleto' | 'boost' | 'bpi' | 'bread-pay' | 'bread' | 'bri-direct-debit' | 'bri' | 'brimo' | 'bsi' | 'bsn' | 'bss' | 'busd' | 'careem-pay' | 'cartes-bancaires' | 'cash-app-pay' | 'catch-payments' | 'cebuana' | 'cetelem' | 'checkout-finance' | 'cimb-clicks' | 'cimb' | 'circle-k' | 'citadele' | 'clave-telered' | 'clearpay' | 'cleverpay' | 'cliq' | 'coinsph' | 'collector-bank' | 'coop' | 'coppel-pay' | 'credit-key' | 'creditclick-paynl-version' | 'credix' | 'd-barai' | 'dai' | 'daily-yamazaki' | 'dan-dan' | 'dana' | 'danamon-online' | 'dankort' | 'danske-bank' | 'dash' | 'depay' | 'deutsche-bank' | 'diners-club' | 'directpay' | 'discover' | 'divido' | 'dnb' | 'docomo-barai' | 'dogecoin' | 'dropp' | 'duologi' | 'dwolla' | 'ebucks' | 'echelon-financing' | 'ecpay' | 'eft-secure' | 'eghl' | 'elo' | 'elv' | 'enets' | 'eos' | 'epayments' | 'epospay' | 'eps' | 'esr-paymentslip-switzerland' | 'ethereum' | 'etika' | 'facebook-pay' | 'fairstone-payments' | 'familymart' | 'farmlands' | 'fashion-giftcard-paynlversion' | 'fashioncheque' | 'fawry' | 'finloup' | 'fintecture' | 'flexiti' | 'forbrugsforeningen' | 'fortiva' | 'fps' | 'fpx' | 'freecharge' | 'futurepay-mytab' | 'gcash' | 'generalfinancing' | 'genoapay' | 'gezondheidsbon-paynl-version' | 'giftcard' | 'giropay' | 'givacard' | 'gmo-bank-transfer' | 'gmo-postpay' | 'google-pay' | 'google-wallet' | 'gopay' | 'grabpay' | 'grailpay' | 'gusd' | 'hana-card' | 'handelsbanken' | 'hello-clever' | 'hong-leong-bank' | 'hong-leong-connect' | 'hsbc' | 'humm' | 'hyper' | 'hypercard' | 'hypercash' | 'hyundai-card' | 'ideal' | 'in3' | 'inbank' | 'indomaret' | 'ing-homepay' | 'interac' | 'ivy' | 'jcb' | 'jousto' | 'kakao-pay' | 'kakebaraidotcom' | 'kasikornbank' | 'kb-card' | 'kbc-cbc' | 'kfast' | 'klarna-pay-later' | 'klarna-pay-now' | 'klarna-slice-it' | 'klarna' | 'knet' | 'krediidipank' | 'kredivo' | 'krungsri' | 'krungthai-bank' | 'kueski-pay' | 'kunst-en-cultuur-cadeaukaart' | 'kuwait-finance-house' | 'laser' | 'latitude-creditline-au' | 'latitude-gem-au' | 'latitude-gem-nz' | 'latitude-go-au' | 'latitudepay' | 'lawson' | 'laybuy-heart' | 'laybuy' | 'lbc' | 'lhv' | 'line-pay' | 'linkaja' | 'linkpay' | 'litecoin' | 'lku' | 'lotte-card' | 'luminor' | 'lydia' | 'mada' | 'maestro' | 'mandiri' | 'mash' | 'master' | 'masterpass' | 'maxima' | 'maya-bank' | 'maya' | 'maybank-qrpay' | 'maybank' | 'maybankm2u' | 'mb-way' | 'mb' | 'mcash' | 'medicinos-bankas' | 'meeza' | 'merpay' | 'meta-pay' | 'ministop' | 'mobicred' | 'mobikwik' | 'mobilepay' | 'mode' | 'mokka' | 'momopay' | 'mondido' | 'monero' | 'mpesa' | 'mtn-mobile-money' | 'myfatoorah' | 'n26' | 'naps' | 'nationale-bioscoopbon' | 'nationale-entertainmentcard' | 'naver-pay' | 'nelo' | 'netbanking' | 'neteller' | 'nh-card' | 'nordea' | 'novuna' | 'ocbc-bank' | 'octo-clicks' | 'ola-money' | 'omasp' | 'op' | 'opay' | 'openpay' | 'ovo' | 'oxxo' | 'ozow' | 'pagoefectivo' | 'paid' | 'paidy' | 'palawa' | 'palawan' | 'pay-easy' | 'pay-pay' | 'paybylink' | 'payco' | 'payconiq' | 'payd' | 'payfast-instant-eft' | 'payflex' | 'payid' | 'paymark-online-eftpos' | 'paymaya' | 'payme' | 'paynow' | 'paypal' | 'payplan' | 'paypo' | 'paysafecard-paynl-version' | 'paysafecard' | 'paysafecash' | 'paysera' | 'paytm' | 'payto' | 'paytomorrow' | 'payu' | 'payzapp' | 'pei' | 'perlasfinance' | 'permata' | 'pivo' | 'pix' | 'podium-cadeaukaart' | 'poli' | 'polygon' | 'poppankki' | 'postfinance-card' | 'postfinance-efinance' | 'postpay' | 'pps' | 'przelew24' | 'przelewy24-paynl-version' | 'public-bank' | 'publicbank-pbe' | 'qr-promptpay' | 'qris' | 'qrph' | 'rabbit-line-pay' | 'rakuten-pay' | 'rapid-transfer' | 'ratepay' | 'rcbc' | 'rcs' | 'revolut' | 'rhb-bank' | 'rhb-now' | 'rietumu' | 'riverty-paynl-version' | 'rupay' | 'saastopankki' | 'sadad' | 'sam' | 'samsung-card' | 'samsung-pay' | 'santander' | 'satisfi' | 'satispay' | 'sbpl' | 'scalapay' | 'seb' | 'sepa-bank-transfer' | 'sequra' | 'sezzle' | 'shib' | 'shinhan-card' | 'shopeepay' | 'shopify-pay' | 'siam-commercial' | 'siauliu-bankas' | 'siirto' | 'sinpe-movil' | 'skrill-digital-wallet' | 'smartpay' | 'snap-checkout' | 'sofort' | 'softbank' | 'solanapay' | 'spankki' | 'spei' | 'splitit' | 'spotii' | 'spraypay' | 'standard-chartered' | 'stc-pay' | 'sunkus' | 'svea-b2b-faktura' | 'svea-b2b-invoice' | 'svea-credit-account' | 'svea-delbetalning' | 'svea-faktura' | 'svea-invoice' | 'svea-lasku' | 'svea-ostukonto' | 'svea-part-payment' | 'svea-yrityslasku' | 'sveaeramaksu' | 'swedbank' | 'swiftpay' | 'swish' | 'swissbilling' | 'synchrony-pay' | 'synchrony' | 'tabby' | 'tabit' | 'tamara' | 'tandympayment' | 'tbi-bank' | 'tendopay' | 'tensile' | 'tesco-lotus' | 'thanachart-bank' | 'toss' | 'touch-n-go' | 'trevipay' | 'truemoney-pay' | 'trustly' | 'twig-pay' | 'twint' | 'uae-visa' | 'uangme' | 'ubp' | 'unionpay' | 'unipay' | 'uob-ez-pay' | 'uob-thai' | 'uob' | 'upi' | 'urpay' | 'usdc' | 'usdp' | 'v-pay' | 'valu' | 'venmo' | 'viabill' | 'vipps' | 'visa-electron' | 'visa' | 'vvv-cadeaukaart-paynl-version' | 'vvv-giftcard' | 'walley' | 'wbtc' | 'webshop-giftcard' | 'wechat-pay' | 'wechat-paynl-version' | 'wegetfinancing' | 'xrp' | 'ymobile' | 'younited-pay' | 'zalopay' | 'zapper' | 'zinia' | 'zip' | 'zoodpay'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "paymenticon-default.png", + "codeblock": { + "title": "Basic PaymentIcon", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n PaymentIcon,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <PaymentIcon name=\"shop-pay\" />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, PaymentIcon} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const paymentIcon = root.createComponent(PaymentIcon, {name: 'shop-pay'});\n\n root.appendChild(paymentIcon);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Maintain the interior appearance of the SVG. The branded portion of the payment icon as provided meets the brand guidelines of the payment provider.\n\n- Maintain the border property of the payment icon. It is designed to adapt to merchant branding in Checkout and ensures a consistent appearance across the customer experience.\n\n- The icon size is designed to be displayed consistently across checkout." + } + ], + "related": [] + }, + { + "name": "PhoneField", + "description": "A PhoneField is an input field that merchants can type into optimized for phone numbers with a country code base auto-formatting. The country code is required for the initial render of the field but it can be overriden later by the user either by selecting a country in the country selection dropdown or by manually editing the country phone code directly in the text field.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "phonefield-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "PhoneFieldProps", + "description": "", + "type": "PhoneFieldProps", + "typeDefinitions": { + "PhoneFieldProps": { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "name": "PhoneFieldProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityDescription", + "value": "string", + "description": "A detailed description for screen readers.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "accessory", + "value": "string | RemoteFragment", + "description": "Any content to render at the end of the text field. Commonly used to display an icon that opens a tooltip providing more information about the field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "autocomplete", + "value": "Autocomplete | boolean", + "description": "A hint as to the intended content of the field.\n\nWhen set to `true`, this property indicates that the field should support autofill, but you do not have any more semantic information on the intended contents.\n\nWhen set to `false`, you are indicating that this field contains sensitive information, or contents that are never saved, like one-time codes.\n\nAlternatively, you can provide an `Autocomplete` object, which describes the specific data you would like to be entered into this field during autofill.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the field can be modified.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "error", + "value": "string", + "description": "Indicate an error to the user. The field will be given a specific stylistic treatment to communicate problems that have to be resolved immediately.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "icon", + "value": "IconSource | {source: IconSource; position?: 'start' | 'end'}", + "description": "An icon to render at the start or end of the field. It will render at the start by default.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the field. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "Content to use as the field label. This value is also used as the placeholder when the field is empty." + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "maxLength", + "value": "number", + "description": "Specifies the maximum number of characters allowed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "MethodSignature", + "name": "onBlur", + "value": "() => void", + "description": "Callback when focus is removed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: string) => void", + "description": "Callback when the buyer has **finished editing** a field or pressed the country dropdown. Unlike `onChange` callbacks you may be familiar with from Polaris or other React component libraries, this callback is **not** run on every change to the input. Phone fields are “partially controlled” components, which means that while the buyer edits the field, its state is controlled by the component. Once the buyer has signalled that they have finished editing the field (typically, by blurring the field), `onChange` is called if the input actually changed from the most recent `value` property. At that point, you are expected to store this “committed value” in state, and reflect it in the phone field’s `value` property.\n\nThis state management model is important given how UI Extensions are rendered. UI Extension components run on a separate thread from the UI, so they can’t respond to input synchronously. A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components) is to have the component be the source of truth for the input `value`, and update the `value` on every user input. The delay in responding to events from a UI extension is only a few milliseconds, but attempting to strictly store state with this delay can cause issues if a user types quickly, or if the buyer is using a lower-powered device. Having the UI thread take ownership for “in progress” input, and only synchronizing when the user is finished with a field, avoids this risk.\n\nIt can still sometimes be useful to be notified when the user makes any input in the field. If you need this capability, you can use the `onInput` prop. However, never use that property to create tightly controlled state for the `value`.\n\nThis callback is called with the current formatted value of the field. If the value of a field is the same as the current `value` prop provided to the field, the `onChange` callback will not be run.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "MethodSignature", + "name": "onFocus", + "value": "() => void", + "description": "Callback when input is focused.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "MethodSignature", + "name": "onInput", + "value": "(value: string) => void", + "description": "Callback when the user makes any changes in the field including selecting a country in the dropdown. As noted in the documentation for `onChange`, you must not use this to update `state` — use the `onChange` callback for that purpose. Use the `onInput` prop when you need to do something as soon as the buyer makes a change, like clearing validation errors that apply to the field as soon as the user begins making the necessary adjustments.\n\nThis callback is called with the current formatted value.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "readonly", + "value": "boolean", + "description": "Whether the field is read-only.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "required", + "value": "boolean", + "description": "Whether the field needs a value. This requirement adds semantic value to the field, but it will not cause an error to appear automatically. If you want to present an error when this field is empty, you can do so with the `error` prop.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/PhoneField/PhoneField.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "string", + "description": "The current value for the field. If omitted, the field will be empty. You should update this value in response to the `onChange` callback.", + "isOptional": true + } + ], + "value": "export interface PhoneFieldProps {\n /**\n * Any content to render at the end of the text field. Commonly used\n * to display an icon that opens a tooltip providing more information about the field.\n */\n accessory?: string | RemoteFragment;\n\n /**\n * A detailed description for screen readers.\n */\n accessibilityDescription?: string;\n\n /**\n * A hint as to the intended content of the field.\n *\n * When set to `true`, this property indicates that the field should support\n * autofill, but you do not have any more semantic information on the intended\n * contents.\n *\n * When set to `false`, you are indicating that this field contains sensitive\n * information, or contents that are never saved, like one-time codes.\n *\n * Alternatively, you can provide an `Autocomplete` object, which describes the\n * specific data you would like to be entered into this field during autofill.\n */\n autocomplete?: Autocomplete | boolean;\n\n /**\n * Whether the field can be modified.\n */\n disabled?: boolean;\n\n /**\n * Indicate an error to the user. The field will be given a specific stylistic treatment\n * to communicate problems that have to be resolved immediately.\n */\n error?: string;\n\n /**\n * An icon to render at the start or end of the field.\n * It will render at the start by default.\n */\n icon?: IconSource | {source: IconSource; position?: 'start' | 'end'};\n\n /**\n * A unique identifier for the field. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n\n /**\n * Content to use as the field label. This value is also used as the placeholder\n * when the field is empty.\n */\n label: string;\n\n /**\n * Specifies the maximum number of characters allowed.\n */\n maxLength?: number;\n\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n\n /**\n * Whether the field is read-only.\n */\n readonly?: boolean;\n\n /**\n * Whether the field needs a value. This requirement adds semantic value\n * to the field, but it will not cause an error to appear automatically.\n * If you want to present an error when this field is empty, you can do\n * so with the `error` prop.\n */\n required?: boolean;\n\n /**\n * The current value for the field. If omitted, the field will be empty. You should\n * update this value in response to the `onChange` callback.\n */\n value?: string;\n\n /**\n * Callback when the buyer has **finished editing** a field or pressed the country dropdown.\n * Unlike `onChange` callbacks you may be familiar with from Polaris or other React component libraries,\n * this callback is **not** run on every change to the input. Phone fields are\n * “partially controlled” components, which means that while the buyer edits the\n * field, its state is controlled by the component. Once the buyer has signalled that\n * they have finished editing the field (typically, by blurring the field), `onChange`\n * is called if the input actually changed from the most recent `value` property. At\n * that point, you are expected to store this “committed value” in state, and reflect\n * it in the phone field’s `value` property.\n *\n * This state management model is important given how UI Extensions are rendered. UI Extension components\n * run on a separate thread from the UI, so they can’t respond to input synchronously.\n * A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components)\n * is to have the component be the source of truth for the input `value`, and update\n * the `value` on every user input. The delay in responding to events from a UI\n * extension is only a few milliseconds, but attempting to strictly store state with\n * this delay can cause issues if a user types quickly, or if the buyer is using a\n * lower-powered device. Having the UI thread take ownership for “in progress” input,\n * and only synchronizing when the user is finished with a field, avoids this risk.\n *\n * It can still sometimes be useful to be notified when the user makes any input in\n * the field. If you need this capability, you can use the `onInput` prop. However,\n * never use that property to create tightly controlled state for the `value`.\n *\n * This callback is called with the current formatted value of the field. If the value\n * of a field is the same as the current `value` prop provided to the field,\n * the `onChange` callback will not be run.\n */\n onChange?(value: string): void;\n /**\n * Callback when the user makes any changes in the field including selecting a country\n * in the dropdown. As noted in the documentation for `onChange`, you must not use\n * this to update `state` — use the `onChange` callback for that purpose.\n * Use the `onInput` prop when you need to do something as soon as the buyer makes a change,\n * like clearing validation errors that apply to the field as soon as the user begins\n * making the necessary adjustments.\n *\n * This callback is called with the current formatted value.\n */\n onInput?(value: string): void;\n /**\n * Callback when input is focused.\n */\n onFocus?(): void;\n /**\n * Callback when focus is removed.\n */\n onBlur?(): void;\n}" + }, + "Autocomplete": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "name": "Autocomplete", + "description": "A descriptor for selecting the data a field would like to receive during autocomplete. This attribute is modeled off of a limited set of the autocomplete values supported in browsers.", + "members": [ + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "field", + "value": "AutocompleteField", + "description": "The type of data that should be inserted into a field supporting autocomplete." + }, + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "group", + "value": "AutocompleteGroup", + "description": "The contact information “group” the autocomplete data should be sourced from.", + "isOptional": true + } + ], + "value": "export interface Autocomplete {\n /**\n * The contact information “group” the autocomplete data should be sourced from.\n */\n group?: AutocompleteGroup;\n /**\n * The type of data that should be inserted into a field supporting autocomplete.\n */\n field: AutocompleteField;\n}" + }, + "AutocompleteField": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteField", + "value": "'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'honorific-suffix' | 'nickname' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level4' | 'address-level3' | 'address-level2' | 'address-level1' | 'country' | 'country-name' | 'postal-code' | 'credit-card-name' | 'credit-card-given-name' | 'credit-card-additional-name' | 'credit-card-family-name' | 'credit-card-number' | 'credit-card-expiry' | 'credit-card-expiry-month' | 'credit-card-expiry-year' | 'credit-card-security-code' | 'credit-card-type' | 'transaction-currency' | 'transaction-amount' | 'language' | 'birthday' | 'birthday-day' | 'birthday-month' | 'birthday-year' | 'sex' | 'url' | 'photo' | 'telephone' | 'telephone-country-code' | 'telephone-national' | 'telephone-area-code' | 'telephone-local' | 'telephone-local-prefix' | 'telephone-local-suffix' | 'telephone-extension' | 'email' | 'instant-message' | 'home telephone' | 'home telephone-country-code' | 'home telephone-national' | 'home telephone-area-code' | 'home telephone-local' | 'home telephone-local-prefix' | 'home telephone-local-suffix' | 'home telephone-extension' | 'home email' | 'home instant-message' | 'work telephone' | 'work telephone-country-code' | 'work telephone-national' | 'work telephone-area-code' | 'work telephone-local' | 'work telephone-local-prefix' | 'work telephone-local-suffix' | 'work telephone-extension' | 'work email' | 'work instant-message' | 'mobile telephone' | 'mobile telephone-country-code' | 'mobile telephone-national' | 'mobile telephone-area-code' | 'mobile telephone-local' | 'mobile telephone-local-prefix' | 'mobile telephone-local-suffix' | 'mobile telephone-extension' | 'mobile email' | 'mobile instant-message' | 'fax telephone' | 'fax telephone-country-code' | 'fax telephone-national' | 'fax telephone-area-code' | 'fax telephone-local' | 'fax telephone-local-prefix' | 'fax telephone-local-suffix' | 'fax telephone-extension' | 'fax email' | 'fax instant-message' | 'pager telephone' | 'pager telephone-country-code' | 'pager telephone-national' | 'pager telephone-area-code' | 'pager telephone-local' | 'pager telephone-local-prefix' | 'pager telephone-local-suffix' | 'pager telephone-extension' | 'pager email' | 'pager instant-message'", + "description": "" + }, + "AutocompleteGroup": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteGroup", + "value": "'shipping' | 'billing'", + "description": "" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "phonefield-default.png", + "codeblock": { + "title": "Basic PhoneField", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n PhoneField,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <PhoneField\n label=\"Phone\"\n value=\"1 (555) 555-5555\"\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, PhoneField} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const phoneField = root.createComponent(PhoneField, {\n label: 'Phone',\n value: '1 (555) 555-5555',\n });\n\n root.appendChild(phoneField);\n});\n", + "language": "js" + } + ] + } + }, + "related": [] + }, + { + "name": "Popover", + "description": "Popovers are similar to tooltips. They are small overlays that open on demand after a user interaction. The difference is that the popover can contain more content, without cluttering the page. They must be specified inside the `overlay` prop of an activator component (`Button`, `Link` or `Pressable`).\n\nThe library automatically applies the WAI-ARIA Popover Widget pattern to both the activator and the popover content.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "popover-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "PopoverProps", + "description": "", + "type": "PopoverProps", + "typeDefinitions": { + "PopoverProps": { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "name": "PopoverProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "alignment", + "value": "Alignment", + "description": "Align the Popover in the axis determined by the position.", + "isOptional": true, + "defaultValue": "'center'" + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "onClose", + "value": "() => void", + "description": "Callback to run when the Popover is closed", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "onOpen", + "value": "() => void", + "description": "Callback to run when the Popover is opened", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "PropertySignature", + "name": "position", + "value": "PopoverPosition", + "description": "Position the Popover relative to the activator.", + "isOptional": true, + "defaultValue": "'blockStart'" + } + ], + "value": "export interface PopoverProps\n extends IdProps,\n Pick,\n Pick {\n /**\n * Position the Popover relative to the activator.\n * @defaultValue 'blockStart'\n */\n position?: PopoverPosition;\n /**\n * Align the Popover in the axis determined by the position.\n * @defaultValue 'center'\n */\n alignment?: Alignment;\n /**\n * Callback to run when the Popover is opened\n */\n onOpen?: () => void;\n /**\n * Callback to run when the Popover is closed\n */\n onClose?: () => void;\n}" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + }, + "PopoverPosition": { + "filePath": "src/surfaces/checkout/components/Popover/Popover.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "PopoverPosition", + "value": "'inlineStart' | 'inlineEnd' | 'blockStart' | 'blockEnd'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Overlays", + "defaultExample": { + "image": "popover-default.png", + "codeblock": { + "title": "Basic Popover", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Pressable,\n Popover,\n View,\n TextBlock,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Pressable\n overlay={\n <Popover>\n <View\n maxInlineSize={200}\n padding=\"base\"\n >\n <TextBlock>\n A thoughtful way to pay\n </TextBlock>\n <TextBlock>Tap don’t type</TextBlock>\n <TextBlock>\n Shop Pay remembers your important\n details, so you can fill carts, not\n forms. And everything is encrypted\n so you can speed safely through\n checkout.\n </TextBlock>\n </View>\n </Popover>\n }\n >\n More info\n </Pressable>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Pressable,\n Popover,\n View,\n TextBlock,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const popoverFragment = root.createFragment();\n const popover = root.createComponent(Popover, {}, [\n root.createComponent(View, {maxInlineSize: 200, padding: 'base'}, [\n root.createComponent(TextBlock, {}, 'A thoughtful way to pay'),\n root.createComponent(TextBlock, {}, 'Tap don’t type'),\n root.createComponent(\n TextBlock,\n {},\n 'Shop Pay remembers your important details, so you can fill carts, not forms. And everything is encrypted so you can speed safely through checkout.',\n ),\n ]),\n ]);\n popoverFragment.appendChild(popover);\n const pressable = root.createComponent(\n Pressable,\n {overlay: popoverFragment},\n 'More info',\n );\n\n root.appendChild(pressable);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "Use popovers if:\n\n- The intent is to ask the customer for information.\n\n- It’s possible to use at most two rows of input fields to get the information." + } + ], + "related": [ + { + "name": "Ui", + "subtitle": "API", + "url": "ui", + "type": "API" + } + ] + }, + { + "name": "Pressable", + "description": "Pressable is a generic interactive component. It shares the same styling properties as View but also adds pressable behavior, meaning that you can execute some logic in response to user interaction. Use this component for creating interactive elements without the default styling that comes with `Button` and `Link`.", + "requires": "", + "thumbnail": "pressable-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "PressableProps", + "description": "", + "type": "PressableProps", + "typeDefinitions": { + "PressableProps": { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "name": "PressableProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ButtonAccessibilityRole", + "description": "The role of the button that will be rendered.\n\n`button`: renders a regular button.\n\n`submit`: renders a button that submits a form.", + "isOptional": true, + "defaultValue": "'button'" + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "activateAction", + "value": "'auto' | 'copy'", + "description": "Sets the action the `activateTarget` should take when this pressable is activated.\n\nSupported actions by component:\n\n| Component | Supported Actions | Default ('auto') |\n|---------------|-------------------|-------------------|\n| [`ClipboardItem`](/docs/api/checkout-ui-extensions/latest/clipboarditem) | 'copy' | 'copy' |", + "isOptional": true, + "defaultValue": "'auto' - a default action for the target component." + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "activateTarget", + "value": "string", + "description": "ID of a component that should respond to activations (e.g. clicks) on this pressable.\n\nSee `activateAction` for how to control the behavior of the target.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle<\n Extract\n >", + "description": "Position children along the cross axis", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle", + "description": "Changes the display of the component.\n\n\n`inline` the component starts on the same line as preceding inline content and allows subsequent content to continue on the same line.\n\n`block` the component starts on its own new line and fills its parent.\n\n`auto` resets the component to its initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Disables the button while loading. Unlike `Button`, no indicator is rendered while loading.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onBlur", + "value": "() => void", + "description": "Callback that is run when the button or link focus is removed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onFocus", + "value": "() => void", + "description": "Callback that is run when the button or link is focused.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onPointerDown", + "value": "() => void", + "description": "Callback that is run when a pointing device button is pressed while the pointer is inside the button or link.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onPointerEnter", + "value": "() => void", + "description": "Callback that is run when the pointing device is over (enters) the button or link.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onPointerLeave", + "value": "() => void", + "description": "Callback that is run when the pointing device has left the button or link.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onPointerUp", + "value": "() => void", + "description": "Callback that is run when a pointing device button is released while the pointer is inside the element button or link.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button or link is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "opacity", + "value": "Opacity", + "description": "Sets the opacity of the View. The opacity will be applied to the background as well as all the children of the View. Use carefully as this could decrease the contrast ratio between the background and foreground elements, resulting in unreadable and inaccessible text.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to. If this value is set, If this value is set, the component will render an `` tag.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Pressable/Pressable.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + } + ], + "value": "export interface PressableProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n InteractionProps,\n SizingProps,\n SpacingProps,\n OverlayActivatorProps,\n DisclosureActivatorProps {\n /**\n * Changes the display of the component.\n *\n *\n * `inline` the component starts on the same line as preceding inline content and allows subsequent content to continue on the same line.\n *\n * `block` the component starts on its own new line and fills its parent.\n *\n * `auto` resets the component to its initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n\n /**\n * The role of the button that will be rendered.\n *\n * `button`: renders a regular button.\n *\n * `submit`: renders a button that submits a form.\n *\n * @defaultValue 'button'\n */\n accessibilityRole?: ButtonAccessibilityRole;\n\n /**\n * Disables the button, disallowing any interaction\n */\n disabled?: boolean;\n\n /**\n * Disables the button while loading. Unlike `Button`, no indicator is rendered while loading.\n */\n loading?: boolean;\n\n /**\n * Callback that is run when the button or link is pressed.\n */\n onPress?: () => void;\n\n /**\n * Callback that is run when the button or link focus is removed.\n */\n onBlur?: () => void;\n\n /**\n * Callback that is run when the button or link is focused.\n */\n onFocus?: () => void;\n\n /**\n * Callback that is run when a pointing device button is pressed while the pointer is inside the button or link.\n */\n onPointerDown?: () => void;\n\n /**\n * Callback that is run when the pointing device is over (enters) the button or link.\n */\n onPointerEnter?: () => void;\n\n /**\n * Callback that is run when the pointing device has left the button or link.\n */\n onPointerLeave?: () => void;\n\n /**\n * Callback that is run when a pointing device button is released while the pointer is inside the element button or link.\n */\n onPointerUp?: () => void;\n\n /**\n * Destination URL to link to. If this value is set, If this value is set, the component will render an `` tag.\n */\n to?: string;\n\n /**\n * Position children along the cross axis\n */\n blockAlignment?: MaybeResponsiveConditionalStyle<\n Extract\n >;\n\n /**\n * Position children along the main axis\n */\n inlineAlignment?: MaybeResponsiveConditionalStyle;\n\n /**\n * Sets the opacity of the View. The opacity will be applied to the background as well as all\n * the children of the View. Use carefully as this could decrease the contrast ratio between\n * the background and foreground elements, resulting in unreadable and inaccessible text.\n */\n opacity?: Opacity;\n\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n}" + }, + "ButtonAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ButtonAccessibilityRole", + "value": "'button' | 'submit'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Display": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Display", + "value": "'none' | 'auto' | 'inline' | 'block'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Opacity": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Opacity", + "value": "10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Actions", + "defaultExample": { + "image": "pressable-default.png", + "codeblock": { + "title": "Basic Pressable", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Icon,\n InlineLayout,\n Pressable,\n Text,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Pressable\n border=\"base\"\n cornerRadius=\"base\"\n padding=\"base\"\n >\n <InlineLayout columns={['fill', 'auto']}>\n <Text>Details</Text>\n <Icon source=\"chevronDown\" size=\"small\" />\n </InlineLayout>\n </Pressable>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Icon,\n InlineLayout,\n Pressable,\n Text,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const pressable = root.createComponent(\n Pressable,\n {\n border: 'base',\n cornerRadius: 'base',\n padding: 'base',\n onPress: () => console.log('onPress event'),\n },\n [\n root.createComponent(InlineLayout, {columns: ['fill', 'auto']}, [\n root.createComponent(Text, {}, 'Details'),\n root.createComponent(Icon, {source: 'chevronDown', size: 'small'}),\n ]),\n ],\n );\n\n root.appendChild(pressable);\n});\n", + "language": "js" + } + ] + } + }, + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "ProductThumbnail", + "description": "Product thumbnail is a representation of a product image. It provides a visual preview of the item, so buyers can quickly identify products.", + "thumbnail": "productthumbnail-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ProductThumbnailProps", + "description": "", + "type": "ProductThumbnailProps", + "typeDefinitions": { + "ProductThumbnailProps": { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "name": "ProductThumbnailProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "An alternative text description that describe the image for the reader to understand what it is about. It is extremely useful for both users using assistive technology and sighted users. A well written description provides people with visual impairments the ability to participate in consuming non-text content. When a screen readers encounters an `Image`, the description is read and announced aloud. If an image fails to load, potentially due to a poor connection, the description is displayed on screen instead. This has the benefit of letting a sighted buyer know an image was meant to load here, but as an alternative, they’re still able to consume the text content. Read [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204) to learn more.\n\nAn `alt` property is available as an alias for this for compatibility with the HTML specification. When both are specified, `accessibilityLabel` takes precedence.", + "isOptional": true, + "defaultValue": "`''`" + }, + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "alt", + "value": "string", + "description": "An alternative text description that describe the image for the reader to understand what it is about. It is extremely useful for both users using assistive technology and sighted users. A well written description provides people with visual impairments the ability to participate in consuming non-text content. When a screen readers encounters an `Image`, the description is read and announced aloud. If an image fails to load, potentially due to a poor connection, the description is displayed on screen instead. This has the benefit of letting a sighted buyer know an image was meant to load here, but as an alternative, they’re still able to consume the text content. Read [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204) to learn more.\n\nThis property is an alias for `accessibilityLabel` for compatibility with the HTML specification. When both are specified `accessibilityLabel` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "badge", + "value": "number", + "description": "Decorates the product thumbnail with the quantity of the product.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "'small' | 'base'", + "description": "Adjusts the size the product thumbnail image.", + "isOptional": true, + "defaultValue": "'base'" + }, + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "source", + "value": "MaybeConditionalStyle", + "description": "The image source (either a remote URL or a local file resource).\n\nA `src` property is available as an alias for this for compatibility with the HTML specification. When both are specified, `source` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ProductThumbnail/ProductThumbnail.ts", + "syntaxKind": "PropertySignature", + "name": "src", + "value": "MaybeConditionalStyle", + "description": "The image source (either a remote URL or a local file resource).\n\nThis property is available as an alias for `source` for compatibility with the HTML specification. When both are specified, `source` takes precedence.", + "isOptional": true + } + ], + "value": "export interface ProductThumbnailProps {\n /**\n * An alternative text description that describe the image for the reader to\n * understand what it is about. It is extremely useful for both users using\n * assistive technology and sighted users. A well written description\n * provides people with visual impairments the ability to participate in\n * consuming non-text content. When a screen readers encounters an `Image`,\n * the description is read and announced aloud. If an image fails to load,\n * potentially due to a poor connection, the description is displayed on\n * screen instead. This has the benefit of letting a sighted buyer know an\n * image was meant to load here, but as an alternative, they’re still able to\n * consume the text content. Read\n * [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204)\n * to learn more.\n *\n * This property is an alias for `accessibilityLabel` for compatibility with the HTML\n * specification. When both are specified `accessibilityLabel` takes precedence.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#alt\n */\n alt?: string;\n\n /**\n * An alternative text description that describe the image for the reader to\n * understand what it is about. It is extremely useful for both users using\n * assistive technology and sighted users. A well written description\n * provides people with visual impairments the ability to participate in\n * consuming non-text content. When a screen readers encounters an `Image`,\n * the description is read and announced aloud. If an image fails to load,\n * potentially due to a poor connection, the description is displayed on\n * screen instead. This has the benefit of letting a sighted buyer know an\n * image was meant to load here, but as an alternative, they’re still able to\n * consume the text content. Read\n * [considerations when writing alternative text](https://ux.shopify.com/considerations-when-writing-alt-text-a9c1985a8204)\n * to learn more.\n *\n * An `alt` property is available as an alias for this for compatibility with the HTML\n * specification. When both are specified, `accessibilityLabel` takes precedence.\n *\n * @defaultValue `''`\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#alt\n */\n accessibilityLabel?: string;\n\n /**\n * The image source (either a remote URL or a local file resource).\n *\n * A `src` property is available as an alias for this for compatibility with the HTML\n * specification. When both are specified, `source` takes precedence.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#src\n */\n source?: MaybeConditionalStyle;\n\n /**\n * The image source (either a remote URL or a local file resource).\n *\n * This property is available as an alias for `source` for compatibility with the HTML\n * specification. When both are specified, `source` takes precedence.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#src\n */\n src?: MaybeConditionalStyle;\n\n /**\n * Decorates the product thumbnail with the quantity of the product.\n */\n badge?: number;\n\n /**\n * Adjusts the size the product thumbnail image.\n *\n * @defaultValue 'base'\n */\n size?: Extract;\n}" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ResolutionCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ResolutionCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "resolution", + "value": "Resolution", + "description": "" + } + ], + "value": "export interface ResolutionCondition {\n resolution: Resolution;\n}" + }, + "Resolution": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Resolution", + "value": "1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "productthumbnail-default.png", + "codeblock": { + "title": "Basic ProductThumbnail", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n ProductThumbnail,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <ProductThumbnail\n source=\"/assets/api/checkout-extensions/checkout/components/product-thumbnail-example-code.png\"\n badge={2}\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, ProductThumbnail} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const paymentIcon = root.createComponent(ProductThumbnail, {\n source:\n '/assets/api/checkout-extensions/checkout/components/product-thumbnail-example-code.png',\n badge: 2,\n });\n\n root.appendChild(paymentIcon);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "**High-quality images and consistent aspect ratio**\n\n- Use optimized product images that ensure visual clarity and loading speed. Maintain a consistent aspect ratio for product thumbnails to avoid distortion or stretching of the images.\n\n**Consistent visual style and appropriate sizes**\n\n- Keep a consistent visual style for product thumbnails throughout your store. Use appropriate size for product thumbnails depending on the layout and use case. This consistency helps buyers recognize and associate the thumbnails with your product offerings.\n\n**Accessibility considerations**\n\n- Ensure product thumbnails are accessible with descriptive alternative text (alt text)." + } + ], + "related": [] + }, + { + "name": "Progress", + "description": "Use to visually represent the completion of a task or process.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "progress-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "ProgressProps", + "description": "", + "type": "ProgressProps", + "typeDefinitions": { + "ProgressProps": { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "name": "ProgressProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to use for the Progress that will be used for buyers using assistive technologies like screen readers. It will also be used to replace the animated loading indicator when buyers prefer reduced motion.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "PropertySignature", + "name": "max", + "value": "number", + "description": "Define the maximum limit of the progress element. It must have a value greater than 0 and be a valid floating point number.", + "isOptional": true, + "defaultValue": "1" + }, + { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "PropertySignature", + "name": "tone", + "value": "Tone", + "description": "Set the color of the progress bar.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "number", + "description": "Specify how much of the task that has been completed. It must be a valid floating point number between 0 and max, or between 0 and 1 if max is omitted. When undefined, the progress bar is indeterminate; this indicates that an activity is ongoing with no indication of how long it is expected to take.", + "isOptional": true + } + ], + "value": "export interface ProgressProps extends IdProps {\n /**\n * Specify how much of the task that has been completed.\n * It must be a valid floating point number between 0 and max, or between 0 and 1 if max is omitted.\n * When undefined, the progress bar is indeterminate;\n * this indicates that an activity is ongoing with no indication of how long it is expected to take.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#value\n */\n value?: number;\n\n /**\n * Define the maximum limit of the progress element.\n * It must have a value greater than 0 and be a valid floating point number.\n *\n * @defaultValue 1\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#max\n */\n max?: number;\n\n /**\n * Set the color of the progress bar.\n *\n * @defaultValue 'auto'\n */\n tone?: Tone;\n\n /**\n * A label to use for the Progress that will be used for buyers using assistive technologies like screen readers.\n * It will also be used to replace the animated loading indicator when buyers prefer reduced motion.\n *\n */\n accessibilityLabel?: string;\n}" + }, + "Tone": { + "filePath": "src/surfaces/checkout/components/Progress/Progress.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Tone", + "value": "'auto' | 'critical'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Feedback and status indicators", + "defaultExample": { + "image": "progress-indeterminate.gif", + "codeblock": { + "title": "Indeterminate state", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Progress,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Progress accessibilityLabel=\"Loading\" />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Progress} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const baseProgress = root.createComponent(Progress, {\n accessibilityLabel: 'Loading',\n });\n\n root.appendChild(baseProgress);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\nUse components like [TextBlock](../titles-and-text/textblock) or [Text](../titles-and-text/text), along with the Progress component, to display text indicating the status of the progress bar.\n\n### Loading states\n\nFor loading states, add text to reassure the user that the progress bar is not frozen.\n\n![A progress bar with \"Loading\" text](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-loading.png)\n\n### Error states\n\nFor error states, add text or a [Banner](./banner) to describe the error and next steps. Use the `critical` tone property to convey urgency.\n\n![A progress bar with error text that says \"There was a problem with the file upload. Please try again.\"](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-error.png)\n\n### Visualize a goal\n\nUse the Progress component to visualize a goal that's valuable to the customer.\n\nHere's an example of using a progress bar to show a customer's progress toward the next rewards tier:\n\n![A progress bar in customer accounts, showing that the customer is on their way to reaching the Botanical maven rewards tier.](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-goal.png)\n\nHere's an example of using a progress bar to show how much more a customer needs to spend to get free shipping:\n\n![A progress bar at checkout, showing that the customer is $43 away from free shipping.](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-free-shipping.png)\n " + } + ], + "examples": { + "description": "", + "examples": [ + { + "description": "In a determinate state, [TextBlock](../titles-and-text/textblock) or [Text](../titles-and-text/text) components can be used to communicate what the progress bar is tracking, and to set clear expectations about the current progress.", + "image": "progress-determinate.png", + "codeblock": { + "title": "Determinate state", + "tabs": [ + { + "code": "import {\n reactExtension,\n BlockStack,\n Grid,\n Progress,\n Text,\n TextBlock,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const label = 'Queue process';\n return (\n <BlockStack>\n <Grid columns={['fill', 'auto']}>\n <Text>{label}</Text>\n <Text appearance=\"subdued\">\n 45% completed\n </Text>\n </Grid>\n <Progress\n value={45}\n max={100}\n accessibilityLabel={label}\n />\n <TextBlock appearance=\"subdued\">\n Estimated wait time: 4 minutes\n </TextBlock>\n </BlockStack>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n Grid,\n Progress,\n Text,\n TextBlock,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const label = 'Queue process';\n\n const progress = root.createComponent(\n BlockStack,\n null,\n [\n root.createComponent(\n Grid,\n {\n columns: ['fill', 'auto'],\n },\n [\n root.createComponent(\n Text,\n null,\n label,\n ),\n root.createComponent(\n Text,\n {\n appearance: 'subdued',\n },\n '45% completed',\n ),\n ],\n ),\n root.createComponent(Progress, {\n value: 45,\n max: 100,\n accessibilityLabel: label,\n }),\n root.createComponent(\n TextBlock,\n {\n appearance: 'subdued',\n },\n 'Estimated wait time: 4 minutes',\n ),\n ],\n );\n\n root.appendChild(progress);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [ + { + "name": "Spinner", + "subtitle": "Component", + "url": "spinner", + "type": "Component" + } + ] + }, + { + "name": "QRCode", + "description": "Used to quickly access scannable data.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "qrcode-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "QRCodeProps", + "description": "", + "type": "QRCodeProps", + "typeDefinitions": { + "QRCodeProps": { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "name": "QRCodeProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the QR code. When set, it will be announced to users using assistive technologies and will provide more context about what the QR code may do when scanned.", + "isOptional": true, + "defaultValue": "'QR code' (translated to the user’s locale)" + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "'base' | 'none'", + "description": "Adjust the border style.", + "isOptional": true, + "defaultValue": "'base'" + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "content", + "value": "string", + "description": "The content to be encoded in the QR code, which can be any string such as a URL, email address, plain text, etc. Specific string formatting can trigger actions on the user’s device when scanned, like opening geolocation coordinates on a map, opening a preferred app or app store entry, preparing an email, text message, and more.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "logo", + "value": "string", + "description": "URL of an image to be displayed in the center of the QR code. This is useful for branding or to indicate to the user what scanning the QR code will do. By default, no image is displayed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "onError", + "value": "() => void", + "description": "Invoked when the conversion of `content` to a QR code fails. If an error occurs, the QR code and its child elements will not be displayed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/QRCode/QRCode.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "'auto' | 'fill'", + "description": "The displayed size of the QR code.\n\n`fill`: the QR code will takes up 100% of the available inline-size and maintain a 1:1 aspect ratio.\n\n`auto`: the QR code will be displayed at its default size.", + "isOptional": true, + "defaultValue": "'auto'" + } + ], + "value": "export interface QRCodeProps extends IdProps {\n /**\n * The content to be encoded in the QR code, which can be any string such as a URL, email address, plain text, etc.\n * Specific string formatting can trigger actions on the user’s device when scanned, like opening geolocation\n * coordinates on a map, opening a preferred app or app store entry, preparing an email, text message, and more.\n */\n content?: string;\n\n /**\n * URL of an image to be displayed in the center of the QR code.\n * This is useful for branding or to indicate to the user what scanning the QR code will do.\n * By default, no image is displayed.\n */\n logo?: string;\n\n /**\n * The displayed size of the QR code.\n *\n * `fill`: the QR code will takes up 100% of the available inline-size and maintain a 1:1 aspect ratio.\n *\n * `auto`: the QR code will be displayed at its default size.\n *\n * @default 'auto'\n */\n size?: 'auto' | 'fill';\n\n /**\n * Adjust the border style.\n *\n * @default 'base'\n */\n border?: Extract;\n\n /**\n * A label that describes the purpose or contents of the QR code. When set,\n * it will be announced to users using assistive technologies and will\n * provide more context about what the QR code may do when scanned.\n *\n * @default 'QR code' (translated to the user’s locale)\n */\n accessibilityLabel?: string;\n\n /**\n * Invoked when the conversion of `content` to a QR code fails.\n * If an error occurs, the QR code and its child elements will not be displayed.\n */\n onError?: () => void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "qrcode-default.png", + "codeblock": { + "title": "Basic QR Code", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Link,\n QRCode,\n TextBlock,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <>\n <QRCode content=\"https://shopify.com\" />\n\n <TextBlock>\n Scan to visit{' '}\n <Link to=\"https://shopify.com\">\n Shopify.com\n </Link>\n </TextBlock>\n </>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Link,\n QRCode,\n TextBlock,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const qrCode = root.createComponent(QRCode, {\n content: 'https://shopify.com',\n });\n\n const textBlock = root.createComponent(TextBlock, null, [\n 'Scan to visit ',\n root.createComponent(Link, {to: 'https://shopify.com'}, 'Shopify.com'),\n ]);\n\n root.appendChild(qrCode);\n root.appendChild(textBlock);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n- Always test that the QR code is scannable from a smartphone.\n- Include a square logo if that’s what your customers are familiar with.\n- Increase usability by adding a text description of what the QR code does.\n- Always provide an alternate method for customers to access the content of the QR code.\n - If the content is a URL, provide a [`Link`](/docs/api/checkout-ui-extensions/components/link) nearby.\n - If the content is data, provide a [`Button`](/docs/api/checkout-ui-extensions/components/button) to copy the data to the clipboard, or show the data in a readonly [`TextField`](/docs/api/checkout-ui-extensions/components/textfield)." + } + ], + "examples": { + "description": "", + "examples": [ + { + "description": "The QRCode component can display an image in the center. Adding a logo can increase brand trust and set expectations for the action when scanning.", + "image": "qrcode-image.png", + "codeblock": { + "title": "With logo", + "tabs": [ + { + "code": "import {\n reactExtension,\n Link,\n QRCode,\n TextBlock,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <>\n <QRCode\n content=\"https://shopify.com\"\n logo=\"https://cdn.shopify.com/YOUR_IMAGE_HERE\"\n />\n\n <TextBlock>\n Scan to visit{' '}\n <Link to=\"https://shopify.com\">\n Shopify.com\n </Link>\n </TextBlock>\n </>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n QRCode,\n TextBlock,\n Link,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const qrCode = root.createComponent(QRCode, {\n content: 'https://shopify.com',\n logo: 'https://cdn.shopify.com/YOUR_IMAGE_HERE',\n });\n\n const textBlock = root.createComponent(\n TextBlock,\n null,\n [\n 'Scan to visit ',\n root.createComponent(\n Link,\n {to: 'https://shopify.com'},\n 'Shopify.com',\n ),\n ],\n );\n\n root.appendChild(qrCode);\n root.appendChild(textBlock);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + }, + { + "description": "In most cases the default size should work well. If you need a different size, use `fill` to make it grow to the size of its parent container.", + "image": "qrcode-fill-size.png", + "codeblock": { + "title": "Fill size", + "tabs": [ + { + "code": "import {\n reactExtension,\n QRCode,\n View,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <View maxInlineSize={300}>\n <QRCode\n content=\"https://shopify.com\"\n size=\"fill\"\n />\n </View>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n View,\n QRCode,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const view = root.createComponent(View, {\n maxInlineSize: 300,\n });\n\n const qrCode = root.createComponent(QRCode, {\n content: 'https://shopify.com',\n size: 'fill',\n });\n\n view.appendChild(qrCode);\n root.appendChild(view);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + }, + { + "description": "When displaying a QR code, include an alternative way for the user to get the content", + "image": "clipboard-qrcode.png", + "codeblock": { + "title": "Copying content of a QR code to the user's clipboard", + "tabs": [ + { + "code": "import {\n reactExtension,\n BlockStack,\n Button,\n ClipboardItem,\n QRCode,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n const bitcoinAddress =\n '14qViLJfdGaP4EeHnDyJbEGQysnCpwk3gd';\n\n return (\n <BlockStack maxInlineSize={200}>\n <QRCode\n size=\"fill\"\n content={`bitcoin:${bitcoinAddress}`}\n />\n <Button activateTarget=\"bitcoin-address\">\n Copy Bitcoin address\n </Button>\n <ClipboardItem\n text={bitcoinAddress}\n id=\"bitcoin-address\"\n />\n </BlockStack>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n Button,\n ClipboardItem,\n QRCode,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const bitcoinAddress =\n '14qViLJfdGaP4EeHnDyJbEGQysnCpwk3gd';\n const qrCodeContent = `bitcoin:${bitcoinAddress}`;\n\n const qrCode = root.createComponent(QRCode, {\n content: qrCodeContent,\n size: 'fill',\n });\n\n const clipboardItem = root.createComponent(\n ClipboardItem,\n {\n text: bitcoinAddress,\n id: 'bitcoin-address',\n },\n );\n\n const button = root.createComponent(\n Button,\n {\n activateTarget: 'bitcoin-address',\n },\n 'Copy Bitcoin address',\n );\n\n const blockStack = root.createComponent(\n BlockStack,\n {\n maxInlineSize: 200,\n },\n );\n\n blockStack.appendChild(qrCode);\n blockStack.appendChild(button);\n blockStack.appendChild(clipboardItem);\n\n root.appendChild(blockStack);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [ + { + "name": "ClipboardItem", + "subtitle": "Component", + "url": "clipboarditem", + "type": "Component" + } + ] + }, + { + "name": "ResourceItem", + "description": "Use to represent a specific object within a collection, that a customer can take action on. For example, a list of active subscriptions or redeemable offers, in a style consistent with the order index page.", + "thumbnail": "resourceitem-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ResourceItemProps", + "description": "", + "type": "ResourceItemProps", + "typeDefinitions": { + "ResourceItemProps": { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "name": "ResourceItemProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "action", + "value": "RemoteFragment", + "description": "The action grouping for the item, provided as buttons.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "actionAccessibilityLabel", + "value": "string", + "description": "Accessibility label for the action grouping. If an accessibility label is not provided, default text is used.", + "isOptional": true, + "defaultValue": "\"More actions\"" + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "actionLabel", + "value": "string", + "description": "Label for the action grouping. If a label is not provided, default text is used.", + "isOptional": true, + "defaultValue": "\"More actions\"" + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Indicates that the item is in a loading state.\n\nWhen `true`, the item shows loading indicators for the UI elements that it is owns. The item is not responsible for the loading indicators of any content that is passed as `children`.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback when pressed. If `to` is set, it will execute the callback and then navigate to the location specified by `to`.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/components/ResourceItem/ResourceItem.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination to navigate to. You must provide either this property, `onPress`, or both.", + "isOptional": true + } + ], + "value": "export interface ResourceItemProps\n extends Pick {\n /**\n * The action grouping for the item, provided as buttons.\n */\n action?: RemoteFragment;\n\n /**\n * Label for the action grouping. If a label is not provided, default text is used.\n *\n * @defaultValue \"More actions\"\n */\n actionLabel?: string;\n\n /**\n * Accessibility label for the action grouping. If an accessibility label is not provided,\n * default text is used.\n *\n * @defaultValue \"More actions\"\n */\n actionAccessibilityLabel?: string;\n\n /**\n * Indicates that the item is in a loading state.\n *\n * When `true`, the item shows loading indicators for the UI elements that it is owns.\n * The item is not responsible for the loading indicators of any content that is passed as `children`.\n *\n * @defaultValue false\n */\n loading?: boolean;\n}" + } + } + }, + { + "title": "ButtonProps action", + "description": "Supported props for Buttons used inside ResourceItem `action` prop.

    `children` only support text.", + "type": "Docs_ResourceItem_Button_Action", + "typeDefinitions": { + "Docs_ResourceItem_Button_Action": { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "name": "Docs_ResourceItem_Button_Action", + "description": "", + "members": [ + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "kind", + "value": "'primary' | 'secondary' | 'plain'", + "description": "The type of button that will be rendered. The visual presentation of the button type is controlled by merchants through the Branding API.\n\n\n`primary`: button used for main actions. For example: \"Continue to next step\".\n\n`secondary`: button used for secondary actions not blocking user progress. For example: \"Download Shop app\".\n\n`plain`: renders a button that visually looks like a link.", + "isOptional": true, + "defaultValue": "'primary'" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loading", + "value": "boolean", + "description": "Replaces content with a loading indicator.", + "isOptional": true, + "defaultValue": "false" + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "loadingLabel", + "value": "string", + "description": "Accessible label for the loading indicator when user prefers reduced motion. This value is only used if `loading` is true.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback that is run when the button is pressed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "overlay", + "value": "RemoteFragment", + "description": "An overlay component to render when the user interacts with the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/customer-account/api/docs.ts", + "syntaxKind": "PropertySignature", + "name": "to", + "value": "string", + "description": "Destination URL to link to.", + "isOptional": true + } + ], + "value": "export interface Docs_ResourceItem_Button_Action\n extends Pick<\n ButtonProps,\n | 'onPress'\n | 'overlay'\n | 'to'\n | 'loading'\n | 'loadingLabel'\n | 'disabled'\n | 'accessibilityLabel'\n | 'kind'\n > {}" + } + } + } + ], + "category": "UI components", + "subCategory": "Actions", + "defaultExample": { + "image": "resourceitem-preview.png", + "altText": "An example of how the ResourceItem component is used to represent one order in the grid view of the Order index page.", + "codeblock": { + "title": "ResourceItem", + "tabs": [ + { + "title": "React", + "code": "import {\n ResourceItem,\n Button,\n Text,\n View,\n reactExtension,\n} from '@shopify/ui-extensions-react/customer-account';\nimport React from 'react';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <View maxInlineSize={300}>\n <ResourceItem\n accessibilityLabel=\"Resource Item\"\n onPress={() => {}}\n actionLabel=\"Manage\"\n action={\n <>\n <Button\n kind=\"primary\"\n onPress={() => {}}\n >\n Pay now\n </Button>\n <Button onPress={() => {}}>\n Second action\n </Button>\n <Button onPress={() => {}}>\n Third action\n </Button>\n </>\n }\n >\n Resource item content\n </ResourceItem>\n </View>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n ResourceItem,\n Button,\n View,\n extension,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension(\n 'customer-account.page.render',\n (root, api) => {\n renderApp(root, api);\n },\n)\n\nfunction renderApp(root, api) {\n\n const actionFragment = root.createFragment();\n\n const primaryButton = root.createComponent(Button, {\n kind: 'primary',\n onPress: () => {},\n });\n\n primaryButton.append(root.createText('Pay now'))\n\n const secondButton = root.createComponent(Button, {\n kind: 'secondary',\n onPress: () => {},\n });\n\n secondButton.append(root.createText('Second button'))\n\n const thirdButton = root.createComponent(Button, {\n kind: 'secondary',\n onPress: () => {},\n });\n\n thirdButton.append(root.createText('Third button'))\n\n actionFragment.append(primaryButton);\n actionFragment.append(secondButton);\n actionFragment.append(thirdButton);\n\n const resourceItem = root.createComponent(\n ResourceItem,\n {\n accessibilityLabel: 'Resource Item',\n onPress: () => {},\n actionLabel: 'Manage',\n action: actionFragment,\n },\n 'Content',\n );\n\n const view = root.createComponent(View, {maxInlineSize: 300});\n view.append(resourceItem);\n\n root.append(view);\n}\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n- Group related information.\n- Structure your content so it’s easy for customers to scan to the most important information.\n- Use images to complement text content.\n- If there is a single primary action for the object, display it as a primary button. Display other object-level actions as secondary buttons.\n- See [UX guidelines](/docs/apps/customer-accounts/order-action-menu-extensions/ux-guidelines) to learn more about the button logic for order actions.\n" + } + ], + "related": [] + }, + { + "name": "ScrollView", + "description": "ScrollView is a container for long form content, such as order summary line items, that allows for scrolling so customers can expose more content as they view.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "scrollview-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "ScrollViewProps", + "description": "", + "type": "ScrollViewProps", + "typeDefinitions": { + "ScrollViewProps": { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "name": "ScrollViewProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "direction", + "value": "'block' | 'inline'", + "description": "The direction on which the content is scrollable.\n\n`block`: Indicates that the content is scrollable on the main axis.\n\n`inline`: Indicates that the content is scrollable on the cross axis.", + "isOptional": true, + "defaultValue": "block" + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle<'auto' | 'none'>", + "description": "Changes the display of the component.\n\n\n`auto` the component's initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "hint", + "value": "'innerShadow' | {type: 'pill'; content: string}", + "description": "Provides a hint to the user that the area is scrollable.\n\n`pill`: renders a pill with a message at the end of the the scrollable area. It disappear as soon as the user starts scrolling.\n\n`innerShadow`: renders an inner visual hint to indicate that the content is scrollable.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "onScroll", + "value": "(args: ScrollViewEvent) => void", + "description": "Callback function that is called when the scroll position changes. Allows to listen to events inside the component returning the position of the scroll.\n\nNote: On touch devices, the onScroll event is fired only when the user finishes scrolling which differs from non touch devices, where the onScroll event is fired when the user scrolls", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "onScrolledToEdge", + "value": "(args: ScrollViewEvent) => void", + "description": "Callback function that is called when the scroll position reaches one of the edges.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "scrollTo", + "value": "number | HTMLElement", + "description": "Scroll to a specific position or to an element when the component is first rendered.\n\nThis property allows you to set an initial scroll position or scroll to a specific element when the `ScrollView` component mounts. Note that this action will only be performed once, during the initial render of the component.", + "isOptional": true, + "examples": [ + { + "title": "Example", + "description": "", + "tabs": [ + { + "code": "// Scroll to 100 pixels from the top on initial render\n\n\n// Scroll to a specific element on initial render\nconst elementRef = useRef(null);\n", + "title": "Example" + } + ] + } + ] + } + ], + "value": "export interface ScrollViewProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n SizingProps,\n SpacingProps {\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n /**\n * Provides a hint to the user that the area is scrollable.\n *\n * `pill`: renders a pill with a message at the end of the the scrollable area. It disappear as soon as the user starts scrolling.\n *\n * `innerShadow`: renders an inner visual hint to indicate that the content is scrollable.\n */\n hint?: 'innerShadow' | {type: 'pill'; content: string};\n /**\n * The direction on which the content is scrollable.\n *\n * `block`:\n * Indicates that the content is scrollable on the main axis.\n *\n * `inline`:\n * Indicates that the content is scrollable on the cross axis.\n *\n * @defaultValue block\n */\n direction?: 'block' | 'inline';\n /**\n * Scroll to a specific position or to an element when the component is first rendered.\n *\n * This property allows you to set an initial scroll position or scroll to a specific element\n * when the `ScrollView` component mounts. Note that this action will only be performed once,\n * during the initial render of the component.\n *\n * @example\n * // Scroll to 100 pixels from the top on initial render\n * \n *\n * // Scroll to a specific element on initial render\n * const elementRef = useRef(null);\n * \n *\n * @note\n * This property will only take effect on the first render. Subsequent updates to this property\n * will not trigger additional scroll actions.\n */\n scrollTo?: number | HTMLElement;\n /**\n * Callback function that is called when the scroll position changes.\n * Allows to listen to events inside the component\n * returning the position of the scroll.\n *\n * Note:\n * On touch devices, the onScroll event is fired only when the user finishes scrolling\n * which differs from non touch devices, where the onScroll event is fired when the user scrolls\n */\n onScroll?: (args: ScrollViewEvent) => void;\n /**\n * Callback function that is called when the scroll position reaches one of the edges.\n */\n onScrolledToEdge?: (args: ScrollViewEvent) => void;\n /**\n * Changes the display of the component.\n *\n *\n * `auto` the component's initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle<'auto' | 'none'>;\n}" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "ScrollViewEvent": { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "name": "ScrollViewEvent", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "position", + "value": "{ inline: number; block: number; }", + "description": "The current scroll position, in pixels." + }, + { + "filePath": "src/surfaces/checkout/components/ScrollView/ScrollView.ts", + "syntaxKind": "PropertySignature", + "name": "scrolledTo", + "value": "{ inline: \"start\" | \"end\"; block: \"start\" | \"end\"; }", + "description": "A flag to indicate if the scroll is at the start or end of an axis." + } + ], + "value": "export interface ScrollViewEvent {\n /**\n * The current scroll position, in pixels.\n */\n position: {\n /** The current scroll horizontal position, in pixels.*/\n inline: number;\n /** The current scroll vertical position, in pixels.*/\n block: number;\n };\n /**\n * A flag to indicate if the scroll is at the start or end of an axis.\n */\n scrolledTo: {\n /** A flag to indicate if the scroll is at the start or end of cross axis. */\n inline: 'start' | 'end' | null;\n /** A flag to indicate if the scroll is at the start or end of main axis. */\n block: 'start' | 'end' | null;\n };\n}" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "scrollview-default.png", + "codeblock": { + "title": "Basic Scrollview", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n ScrollView,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <ScrollView maxBlockSize={300}>\n <View\n border=\"base\"\n padding=\"base\"\n minBlockSize={50}\n >\n View\n </View>\n <View\n border=\"base\"\n padding=\"base\"\n minBlockSize={50}\n >\n View\n </View>\n <View\n border=\"base\"\n padding=\"base\"\n minBlockSize={50}\n >\n View\n </View>\n <View\n border=\"base\"\n padding=\"base\"\n minBlockSize={50}\n >\n View\n </View>\n <View\n border=\"base\"\n padding=\"base\"\n minBlockSize={50}\n >\n View\n </View>\n </ScrollView>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, ScrollView, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const scrollView = root.createComponent(ScrollView, {maxBlockSize: 400}, [\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n root.createComponent(\n View,\n {border: 'base', padding: 'base', minBlockSize: 50},\n 'View',\n ),\n ]);\n\n root.appendChild(scrollView);\n});\n", + "language": "js" + } + ] + } + }, + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "Select", + "description": "Selects let buyers choose one option from an options menu. Consider select when you have 4 or more options, to avoid cluttering the interface.", + "requires": "", + "thumbnail": "select-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "SelectProps", + "description": "", + "type": "SelectProps", + "typeDefinitions": { + "SelectProps": { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "name": "SelectProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "autocomplete", + "value": "Autocomplete | boolean", + "description": "A hint as to the intended content of the field.\n\nWhen set to `true`, this property indicates that the field should support autofill, but you do not have any more semantic information on the intended contents.\n\nWhen set to `false`, you are indicating that this field contains sensitive information, or contents that are never saved, like one-time codes. Note that it is impossible to prevent autocomplete in some browsers, so do not depend on its absence.\n\nAlternatively, you can provide an `Autocomplete` object, which describes the specific data you would like to be entered into this field during autocomplete.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the select can be changed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "error", + "value": "string", + "description": "Indicate an error to the user. The field will be given a specific stylistic treatment to communicate problems that have to be resolved immediately.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the field. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "Content to use as the field label." + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "MethodSignature", + "name": "onBlur", + "value": "() => void", + "description": "Callback when focus is removed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: string) => void", + "description": "A callback that is run whenever the selected option changes. This callback is called with the string `value` of the selected `option`. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), so you must store this value in state and reflect it back in the `value` prop of the select.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "MethodSignature", + "name": "onFocus", + "value": "() => void", + "description": "Callback when input is focused.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "options", + "value": "SelectOptionProps[]", + "description": "The options a buyer can select from." + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "placeholder", + "value": "string", + "description": "A short hint that describes the expected value of the field when no value is set.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "readonly", + "value": "boolean", + "description": "Whether the field is read only.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "required", + "value": "boolean", + "description": "Whether the field needs a value. This requirement adds semantic value to the field, but it will not cause an error to appear automatically. If you want to present an error when this field is empty, you can do so with the `error` prop.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "string", + "description": "The active option for the select. This should match to one of the `value` properties in the `options` prop. When not set, the value will default to an empty string, which will show the `placeholder` text as the \"selected value\".", + "isOptional": true + } + ], + "value": "export interface SelectProps {\n /**\n * A unique identifier for the field. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n /**\n * Content to use as the field label.\n */\n label: string;\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n /**\n * The active option for the select. This should match to one of the\n * `value` properties in the `options` prop. When not set,\n * the value will default to an empty string, which will show the\n * `placeholder` text as the \"selected value\".\n */\n value?: string;\n /**\n * The options a buyer can select from.\n */\n options: SelectOptionProps[];\n /**\n * A short hint that describes the expected value of the field when no value is set.\n */\n placeholder?: string;\n /**\n * Whether the field needs a value. This requirement adds semantic value\n * to the field, but it will not cause an error to appear automatically.\n * If you want to present an error when this field is empty, you can do\n * so with the `error` prop.\n */\n required?: boolean;\n /**\n * Whether the select can be changed.\n */\n disabled?: boolean;\n /**\n * Whether the field is read only.\n */\n readonly?: boolean;\n /**\n * Indicate an error to the user. The field will be given a specific stylistic treatment\n * to communicate problems that have to be resolved immediately.\n */\n error?: string;\n /**\n * A hint as to the intended content of the field.\n *\n * When set to `true`, this property indicates that the field should support\n * autofill, but you do not have any more semantic information on the intended\n * contents.\n *\n * When set to `false`, you are indicating that this field contains sensitive\n * information, or contents that are never saved, like one-time codes. Note that\n * it is impossible to prevent autocomplete in some browsers, so do not depend on\n * its absence.\n *\n * Alternatively, you can provide an `Autocomplete` object, which describes the\n * specific data you would like to be entered into this field during autocomplete.\n */\n autocomplete?: Autocomplete | boolean;\n /**\n * Callback when focus is removed.\n */\n onBlur?(): void;\n /**\n * Callback when input is focused.\n */\n onFocus?(): void;\n /**\n * A callback that is run whenever the selected option changes. This callback\n * is called with the string `value` of the selected `option`. This component\n * is [controlled](https://reactjs.org/docs/forms.html#controlled-components),\n * so you must store this value in state and reflect it back in the `value`\n * prop of the select.\n */\n onChange?(value: string): void;\n}" + }, + "Autocomplete": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "name": "Autocomplete", + "description": "A descriptor for selecting the data a field would like to receive during autocomplete. This attribute is modeled off of a limited set of the autocomplete values supported in browsers.", + "members": [ + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "field", + "value": "AutocompleteField", + "description": "The type of data that should be inserted into a field supporting autocomplete." + }, + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "group", + "value": "AutocompleteGroup", + "description": "The contact information “group” the autocomplete data should be sourced from.", + "isOptional": true + } + ], + "value": "export interface Autocomplete {\n /**\n * The contact information “group” the autocomplete data should be sourced from.\n */\n group?: AutocompleteGroup;\n /**\n * The type of data that should be inserted into a field supporting autocomplete.\n */\n field: AutocompleteField;\n}" + }, + "AutocompleteField": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteField", + "value": "'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'honorific-suffix' | 'nickname' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level4' | 'address-level3' | 'address-level2' | 'address-level1' | 'country' | 'country-name' | 'postal-code' | 'credit-card-name' | 'credit-card-given-name' | 'credit-card-additional-name' | 'credit-card-family-name' | 'credit-card-number' | 'credit-card-expiry' | 'credit-card-expiry-month' | 'credit-card-expiry-year' | 'credit-card-security-code' | 'credit-card-type' | 'transaction-currency' | 'transaction-amount' | 'language' | 'birthday' | 'birthday-day' | 'birthday-month' | 'birthday-year' | 'sex' | 'url' | 'photo' | 'telephone' | 'telephone-country-code' | 'telephone-national' | 'telephone-area-code' | 'telephone-local' | 'telephone-local-prefix' | 'telephone-local-suffix' | 'telephone-extension' | 'email' | 'instant-message' | 'home telephone' | 'home telephone-country-code' | 'home telephone-national' | 'home telephone-area-code' | 'home telephone-local' | 'home telephone-local-prefix' | 'home telephone-local-suffix' | 'home telephone-extension' | 'home email' | 'home instant-message' | 'work telephone' | 'work telephone-country-code' | 'work telephone-national' | 'work telephone-area-code' | 'work telephone-local' | 'work telephone-local-prefix' | 'work telephone-local-suffix' | 'work telephone-extension' | 'work email' | 'work instant-message' | 'mobile telephone' | 'mobile telephone-country-code' | 'mobile telephone-national' | 'mobile telephone-area-code' | 'mobile telephone-local' | 'mobile telephone-local-prefix' | 'mobile telephone-local-suffix' | 'mobile telephone-extension' | 'mobile email' | 'mobile instant-message' | 'fax telephone' | 'fax telephone-country-code' | 'fax telephone-national' | 'fax telephone-area-code' | 'fax telephone-local' | 'fax telephone-local-prefix' | 'fax telephone-local-suffix' | 'fax telephone-extension' | 'fax email' | 'fax instant-message' | 'pager telephone' | 'pager telephone-country-code' | 'pager telephone-national' | 'pager telephone-area-code' | 'pager telephone-local' | 'pager telephone-local-prefix' | 'pager telephone-local-suffix' | 'pager telephone-extension' | 'pager email' | 'pager instant-message'", + "description": "" + }, + "AutocompleteGroup": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteGroup", + "value": "'shipping' | 'billing'", + "description": "" + }, + "SelectOptionProps": { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "name": "SelectOptionProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether this option can be selected or not.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "The buyer-facing label for this option." + }, + { + "filePath": "src/surfaces/checkout/components/Select/Select.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "string", + "description": "The value that will be passed to the select’s `onChange` callback when this option is selected." + } + ], + "value": "export interface SelectOptionProps {\n /**\n * The value that will be passed to the select’s `onChange` callback\n * when this option is selected.\n */\n value: string;\n /**\n * The buyer-facing label for this option.\n */\n label: string;\n /**\n * Whether this option can be selected or not.\n */\n disabled?: boolean;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "select-default.png", + "codeblock": { + "title": "Basic Select", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Select,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Select\n label=\"Country\"\n value=\"2\"\n options={[\n {\n value: '1',\n label: 'Australia',\n },\n {\n value: '2',\n label: 'Canada',\n },\n {\n value: '3',\n label: 'France',\n },\n {\n value: '4',\n label: 'Japan',\n },\n {\n value: '5',\n label: 'Nigeria',\n },\n {\n value: '6',\n label: 'United States',\n },\n ]}\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Select} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const select = root.createComponent(Select, {\n label: 'Country',\n value: '2',\n options: [\n {\n value: '1',\n label: 'Australia',\n },\n {\n value: '2',\n label: 'Canada',\n },\n {\n value: '3',\n label: 'France',\n },\n {\n value: '4',\n label: 'Japan',\n },\n {\n value: '5',\n label: 'Nigeria',\n },\n {\n value: '6',\n label: 'United States',\n },\n ],\n });\n\n root.appendChild(select);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use this component when customers need to choose between four or more predefined options.\n\n- Have a default option selected whenever possible. Use Select as placeholder text if there’s no logical default option." + } + ], + "examples": { + "description": "", + "examples": [ + { + "image": "select-time-picking.png", + "description": "The Select component is a great choice for displaying a long list of time choices, as it helps conserve valuable space. If the number of options is less than or equal to 5, we recommend using the [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) component. This allows buyers to see all options immediately without the need for clicking into the select.", + "codeblock": { + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Select,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Select\n label=\"Pickup time\"\n value=\"1\"\n options={[\n {\n value: '1',\n label: '9:00 AM',\n },\n {\n value: '2',\n label: '9:30 AM',\n },\n {\n value: '3',\n label: '10:00 AM',\n },\n {\n value: '4',\n label: '10:30 AM',\n },\n {\n value: '5',\n label: '11:00 AM',\n },\n {\n value: '6',\n label: '11:30 AM',\n },\n ]}\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Select} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const select = root.createComponent(Select, {\n label: 'Pickup time',\n value: '1',\n options: [\n {\n value: '1',\n label: '9:00 AM',\n },\n {\n value: '2',\n label: '9:30 AM',\n },\n {\n value: '3',\n label: '10:00 AM',\n },\n {\n value: '4',\n label: '10:30 AM',\n },\n {\n value: '5',\n label: '11:00 AM',\n },\n {\n value: '6',\n label: '11:30 AM',\n },\n ],\n });\n\n root.appendChild(select);\n});\n", + "language": "js" + } + ], + "title": "Using the Select component to display a long list of time choices" + } + } + ] + }, + "related": [] + }, + { + "name": "Sheet", + "description": "The Sheet component displays essential information for customers at the bottom of the screen, appearing above other elements. Use it sparingly to avoid distracting customers during checkout. This component requires access to [Customer Privacy API](/docs/api/checkout-ui-extensions/unstable/configuration#collect-buyer-consent) to be rendered. \n\nThe library automatically applies the [WAI-ARIA Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) to both the activator and the sheet content.", + "requires": "configuration of the [Customer Privacy](/docs/api/checkout-ui-extensions/unstable/configuration#collect-buyer-consent) capability to be rendered.", + "thumbnail": "sheet-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "SheetProps", + "description": "", + "type": "SheetProps", + "typeDefinitions": { + "SheetProps": { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "name": "SheetProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to describe the purpose of the sheet that is announced by screen readers. If not set, it will use the value of `heading`.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "defaultOpen", + "value": "boolean", + "description": "Indicates whether the sheet should be open by default.\n\nThis property is necessary in some cases, but its usage is generally discouraged due to potential negative impacts on user experience.\n\nDevelopers should:\n- Only set this property to true when there are vitally important behaviors of the application that depend on the user interacting with the sheet.\n- Make every effort to conditionally hide the sheet based on the state of checkout. An explicit example is custom privacy consent, where the sheet should only be displayed when consent is necessary and has not yet been explicitly given by the user.\n\nThis property is useful for when the Sheet needs to be rendered on the page load and not triggered by a user action. The property should only take effect when the `Sheet` is rendered for the first time.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "heading", + "value": "string", + "description": "A heading rendered at the top of the sheet.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "MethodSignature", + "name": "onHide", + "value": "() => void", + "description": "Callback fired when the sheet is closed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "MethodSignature", + "name": "onShow", + "value": "() => void", + "description": "Callback fired when the sheet is opened.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "primaryAction", + "value": "RemoteFragment", + "description": "The primary action to perform, provided as a `Button` component. The property allows up to two buttons to be rendered.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Sheet/Sheet.ts", + "syntaxKind": "PropertySignature", + "name": "secondaryAction", + "value": "RemoteFragment", + "description": "The secondary action to perform, provided as a `Button` component. The property allows only one button to be rendered.", + "isOptional": true + } + ], + "value": "export interface SheetProps extends IdProps {\n /**\n * A label to describe the purpose of the sheet that is announced by screen readers.\n * If not set, it will use the value of `heading`.\n */\n accessibilityLabel?: string;\n\n /**\n * Indicates whether the sheet should be open by default.\n *\n * This property is necessary in some cases, but its usage is generally discouraged due to potential negative impacts on user experience.\n *\n * Developers should:\n * - Only set this property to true when there are vitally important behaviors of the application that depend on the user interacting with the sheet.\n * - Make every effort to conditionally hide the sheet based on the state of checkout. An explicit example is custom privacy consent, where the sheet should only be displayed when consent is necessary and has not yet been explicitly given by the user.\n *\n * This property is useful for when the Sheet needs to be rendered on the page load and not triggered by a user action.\n * The property should only take effect when the `Sheet` is rendered for the first time.\n */\n defaultOpen?: boolean;\n\n /** A heading rendered at the top of the sheet. */\n heading?: string;\n\n /** Callback fired when the sheet is opened. */\n onShow?(): void;\n\n /** Callback fired when the sheet is closed. */\n onHide?(): void;\n\n /**\n * The primary action to perform, provided as a `Button` component.\n * The property allows up to two buttons to be rendered.\n */\n primaryAction?: RemoteFragment;\n\n /**\n * The secondary action to perform, provided as a `Button` component.\n * The property allows only one button to be rendered.\n */\n secondaryAction?: RemoteFragment;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Overlays", + "defaultExample": { + "image": "sheet-default.png", + "codeblock": { + "title": "Basic Sheet", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Link,\n Sheet,\n TextBlock,\n} from '@shopify/ui-extensions-react/customer-account';\n\n// This component requires access to Customer Privacy API to be rendered.\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Link\n overlay={\n <Sheet\n id=\"basic-sheet\"\n heading=\"Basic Sheet\"\n accessibilityLabel=\"A sheet with text content\"\n >\n <TextBlock>\n Basic Sheet Content\n </TextBlock>\n </Sheet>\n }\n >\n Open sheet\n </Link>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Link,\n Sheet,\n TextBlock,\n} from '@shopify/ui-extensions/customer-account';\n\n// This component requires access to Customer Privacy API to be rendered.\n\nexport default extension('customer-account.page.render', (root) => {\n const sheetFragment = root.createFragment();\n const sheet = root.createComponent(\n Sheet,\n {\n id: 'basic-sheet',\n heading: 'Basic Sheet',\n accessibilityLabel: 'A sheet with text content',\n },\n [root.createComponent(TextBlock, undefined, 'Basic Sheet Content')],\n );\n sheetFragment.appendChild(sheet);\n const link = root.createComponent(\n Link,\n {overlay: sheetFragment},\n 'Open sheet',\n );\n\n root.appendChild(link);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "shopify-controlled-surfaces", + "title": "Shopify-controlled surfaces", + "sectionContent": "To prevent disruptions during checkout, we maintain strict design control over key areas of the Sheet component. These Shopify-controlled elements include: \n\n

    Locations of elements

    \n\nThe Sheet elements (header, content, action buttons, and dismiss button) are strategically positioned and sized to present vital information upfront.\n\n\n\n\n\n
    \n\n

    Padding and spacing

    \n\n\n\n
    \n\n

    Maximum height

    \n\nTo balance customer attention and task completion, a maximum height is set for the Sheet component.\n\n\n\n\n\nWhen content pushes the sheet to exceed this limit, the following UI behaviors are triggered:\n\n
    \n\n

    Heading and content are scrollable

    \n\n\n\n
    \n\n

    Expand pill appears to allow customers to view the entire content

    \n\n\n\n
    \n\n

    Actions slot and dismiss button remain fixed

    \n\n" + }, + { + "type": "Generic", + "anchorLink": "privacy-consent-requirements", + "title": "Privacy consent requirements", + "sectionContent": "

    Content

    \n\nFor the best customer experience, ensure content is brief and to the point.\n\n\n\nVarious strategies can be employed to avoid content scrolling.\n\n
    \n\n

    Use short content

    \n\n\n\n
    \n\n

    Use small text size

    \n\n \n\n
    \n\n

    Remove the header

    \n\n \n\n
    \n\n

    Actions slot

    \n\nThe actions slots allows customers to make decisions and is split into primary and secondary sections.\n\n\n\n
    \n\n

    Primary section

    \n\n Contains primary actions for customer decisions on the sheet’s prompt. Up to two buttons are allowed. Keep the button’s content brief so that it doesn’t wrap to more than one line.\n\n\n\n
    \n\n

    Secondary section

    \n\nContains action that is unrelated to the sheet’s prompt. Only one button is allowed. A modal can be activated when engaging with the secondary action. Keep the button’s content brief so that it doesn’t wrap to more than one line.\n\n\n\n
    \n\n

    Consent, denial of consent, and sheet dismissal

    \n\n

    Consent

    \n\nWhen a customer expresses consent by pressing the acceptance button, cookies will load and the sheet should not re-appear on refresh.\n\n
    \n\n

    Denial of consent

    \n\nWhen a customer expresses denial of consent by pressing the rejection button, cookies will not load and the sheet will not re-appear on refresh.\n\n
    \n\n

    Sheet dismissal

    \n\nWhen a customer neither grants nor denies consent by pressing the dismiss button, cookies will not load and the sheet will re-appear on refresh.\n\n" + } + ], + "examples": { + "description": "", + "examples": [ + { + "description": "The Sheet component can be used to display privacy consent preferences in the Checkout interface. Sheet can be defaulted to open for this use case.\n\n This component requires access to [Customer Privacy API](/docs/api/checkout-ui-extensions/unstable/apis/customer-privacy) to be rendered.", + "codeblock": { + "title": "Using Sheet to display consent preferences", + "tabs": [ + { + "code": "import {\n reactExtension,\n Button,\n Link,\n Sheet,\n TextBlock,\n useApi,\n useCustomerPrivacy,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const {applyTrackingConsentChange, ui} =\n useApi();\n\n const {shouldShowBanner} = useCustomerPrivacy();\n\n const sheetId = 'sheet-consent';\n\n const handleConsentChange = async ({\n analytics,\n marketing,\n preferences,\n saleOfData,\n }) => {\n try {\n const result =\n await applyTrackingConsentChange({\n type: 'changeVisitorConsent',\n analytics,\n marketing,\n preferences,\n saleOfData,\n });\n\n // Check if operation was successful\n if (result.type === 'success') {\n ui.overlay.close(sheetId);\n } else {\n // Handle failure case here\n }\n } catch (error) {\n // Handle error case here\n }\n };\n\n return (\n <Sheet\n id={sheetId}\n heading=\"We value your privacy\"\n accessibilityLabel=\"A sheet that collects privacy consent preferences\"\n defaultOpen={shouldShowBanner}\n primaryAction={\n <>\n <Button\n kind=\"secondary\"\n onPress={() =>\n handleConsentChange({\n // values derived from local form state\n analytics: false,\n marketing: false,\n preferences: false,\n saleOfData: false,\n })\n }\n >\n I decline\n </Button>\n <Button\n kind=\"secondary\"\n onPress={() =>\n handleConsentChange({\n analytics: true,\n marketing: true,\n preferences: true,\n saleOfData: true,\n })\n }\n >\n I agree\n </Button>\n </>\n }\n secondaryAction={\n <Button\n kind=\"plain\"\n overlay={\n // Open a settings modal\n }\n >\n Settings\n </Button>\n }\n >\n <TextBlock>\n This website uses cookies to ensure you\n get the best experience on our website.\n <Link>Privacy Policy</Link>\n </TextBlock>\n </Sheet>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Sheet,\n Button,\n Link,\n TextBlock,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.footer.render-after',\n (\n root,\n {\n applyTrackingConsentChange,\n customerPrivacy,\n ui,\n },\n ) => {\n customerPrivacy.subscribe(\n ({shouldShowBanner}) => {\n const primaryFragment =\n root.createFragment();\n const secondaryFragment =\n root.createFragment();\n const handleConsentChange = async ({\n analytics,\n marketing,\n preferences,\n saleOfData,\n }) => {\n try {\n const result =\n await applyTrackingConsentChange({\n type: 'changeVisitorConsent',\n analytics,\n marketing,\n preferences,\n saleOfData,\n });\n\n // Check if operation was successful\n if (result) {\n ui.overlay.close(sheetId);\n } else {\n // Handle failure case here\n }\n } catch (error) {\n // Handle error case here\n }\n };\n\n const declineButton =\n root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () =>\n handleConsentChange({\n analytics: false,\n marketing: false,\n preferences: false,\n saleOfData: false,\n }),\n },\n 'I decline',\n );\n\n const agreeButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () =>\n handleConsentChange({\n analytics: true,\n marketing: true,\n preferences: true,\n saleOfData: true,\n }),\n },\n 'I agree',\n );\n\n const settingsButton =\n root.createComponent(\n Button,\n {\n kind: 'secondary',\n },\n 'Settings',\n );\n\n primaryFragment.appendChild(\n declineButton,\n );\n primaryFragment.appendChild(agreeButton);\n secondaryFragment.appendChild(\n settingsButton,\n );\n\n const sheetId = 'sheet-consent';\n const sheet = root.createComponent(\n Sheet,\n {\n id: sheetId,\n heading: 'We value your privacy',\n accessibilityLabel:\n 'A sheet that collects privacy consent preferences',\n defaultOpen: shouldShowBanner,\n primaryAction: primaryFragment,\n secondaryAction: secondaryFragment,\n },\n );\n\n const textBlock = root.createComponent(\n TextBlock,\n null,\n [\n 'We and our partners use cookies and other technologies to improve your experience, measure performance, and tailor marketing. Details in our ',\n root.createComponent(\n Link,\n null,\n 'Privacy Policy',\n ),\n ],\n );\n\n sheet.appendChild(textBlock);\n root.appendChild(sheet);\n },\n );\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + }, + { + "description": "In order to save space in the action slot, secondary actions can be placed in the content area.", + "image": "sheet-description-preferences.png", + "codeblock": { + "title": "Preferences button is in the description as a link", + "tabs": [ + { + "code": "import {\n reactExtension,\n Button,\n BlockStack,\n Link,\n Sheet,\n TextBlock,\n useCustomerPrivacy,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const {shouldShowBanner} = useCustomerPrivacy();\n\n const sheetId = 'sheet-consent';\n\n return (\n <Sheet\n id={sheetId}\n accessibilityLabel=\"A sheet that collects privacy consent preferences\"\n defaultOpen={shouldShowBanner}\n primaryAction={\n <>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I decline\n </Button>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I agree\n </Button>\n </>\n }\n >\n <BlockStack spacing=\"none\">\n <TextBlock>\n This website uses cookies to ensure you\n get the best experience on our website.\n </TextBlock>\n <TextBlock>\n <Link>Privacy Policy</Link> ‧{' '}\n <Link>Cookie Policy</Link> ‧{' '}\n <Link\n // overlay: <Modal>Preferences modal...</Modal>,\n >\n Preferences\n </Link>\n </TextBlock>\n </BlockStack>\n </Sheet>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Sheet,\n Button,\n Link,\n TextBlock,\n BlockStack,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.footer.render-after',\n (root, {customerPrivacy}) => {\n const primaryFragment = root.createFragment();\n\n const declineButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I decline',\n );\n\n const agreeButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I agree',\n );\n\n primaryFragment.appendChild(declineButton);\n primaryFragment.appendChild(agreeButton);\n\n const sheetId = 'sheet-consent';\n const sheet = root.createComponent(Sheet, {\n id: sheetId,\n accessibilityLabel:\n 'A sheet that collects privacy consent preferences',\n defaultOpen:\n customerPrivacy.current.shouldShowBanner,\n primaryAction: primaryFragment,\n });\n\n const textBlock = root.createComponent(\n TextBlock,\n null,\n 'This website uses cookies to ensure you get the best experience on our website.',\n );\n\n const linkBlock = root.createComponent(\n TextBlock,\n null,\n [\n root.createComponent(\n Link,\n null,\n 'Privacy Policy',\n ),\n ' ‧ ',\n root.createComponent(\n Link,\n null,\n 'Cookie Policy',\n ),\n ' ‧ ',\n root.createComponent(\n Link,\n {\n // overlay: <Modal>Preferences modal...</Modal>,,\n },\n 'Preferences',\n ),\n ],\n );\n\n const blockStack = root.createComponent(\n BlockStack,\n {spacing: 'none'},\n [textBlock, linkBlock],\n );\n sheet.appendChild(blockStack);\n root.appendChild(sheet);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + }, + { + "description": "An icon button can be used in the secondary actions area to allow for more space for the primary actions.", + "image": "sheet-icon-button-preferences.png", + "codeblock": { + "title": "Icon button used for preferences", + "tabs": [ + { + "code": "import {\n reactExtension,\n Button,\n Link,\n Icon,\n Sheet,\n TextBlock,\n useCustomerPrivacy,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const {shouldShowBanner} = useCustomerPrivacy();\n\n return (\n <Sheet\n accessibilityLabel=\"A sheet that collects privacy consent preferences\"\n heading=\"We value your privacy\"\n defaultOpen={shouldShowBanner}\n primaryAction={\n <>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I decline\n </Button>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I agree\n </Button>\n </>\n }\n secondaryAction={\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n <Icon source=\"settings\" />\n </Button>\n }\n >\n <TextBlock>\n This website uses cookies to ensure you\n get the best experience on our website.{' '}\n <Link>Privacy Policy</Link>.\n </TextBlock>\n </Sheet>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Sheet,\n Button,\n Link,\n TextBlock,\n Icon,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.footer.render-after',\n (root, {customerPrivacy}) => {\n const primaryFragment = root.createFragment();\n const secondaryFragment =\n root.createFragment();\n\n const declineButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I decline',\n );\n\n const agreeButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I agree',\n );\n\n const preferencesButton =\n root.createComponent(\n Button,\n {\n kind: 'secondary',\n },\n root.createComponent(Icon, {\n source: 'settings',\n }),\n );\n\n primaryFragment.appendChild(declineButton);\n primaryFragment.appendChild(agreeButton);\n secondaryFragment.appendChild(\n preferencesButton,\n );\n\n const sheet = root.createComponent(Sheet, {\n accessibilityLabel:\n 'A sheet that collects privacy consent preferences',\n defaultOpen:\n customerPrivacy.current.shouldShowBanner,\n primaryAction: primaryFragment,\n secondaryAction: secondaryFragment,\n });\n\n const textBlock = root.createComponent(\n TextBlock,\n null,\n [\n 'This website uses cookies to ensure you get the best experience on our website. ',\n root.createComponent(\n Link,\n null,\n 'Privacy Policy',\n ),\n ],\n );\n\n sheet.appendChild(textBlock);\n root.appendChild(sheet);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + }, + { + "description": "The description can take in layout components to allow for different types of content to be structured in specific ways.", + "image": "sheet-layout-content.png", + "codeblock": { + "title": "Using layout component in the description ", + "tabs": [ + { + "code": "import {\n reactExtension,\n Button,\n Link,\n Image,\n InlineLayout,\n Sheet,\n TextBlock,\n useCustomerPrivacy,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const {shouldShowBanner} = useCustomerPrivacy();\n\n return (\n <Sheet\n accessibilityLabel=\"A sheet that collects privacy consent preferences\"\n defaultOpen={shouldShowBanner}\n primaryAction={\n <>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I decline\n </Button>\n <Button\n kind=\"secondary\"\n onPress={() => {}}\n >\n I agree\n </Button>\n </>\n }\n secondaryAction={\n <Button kind=\"plain\" onPress={() => {}}>\n Preferences\n </Button>\n }\n >\n <InlineLayout\n padding=\"none\"\n spacing=\"small100\"\n columns={[38, 'fill']}\n >\n <Image source=\"https://yourawesomeimage.com\" />\n <TextBlock>\n This website uses cookies to ensure you\n get the best experience on our website.{' '}\n <Link>Learn more</Link>.\n </TextBlock>\n </InlineLayout>\n </Sheet>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Sheet,\n Button,\n Link,\n TextBlock,\n Image,\n InlineLayout,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.footer.render-after',\n (root, {customerPrivacy}) => {\n const primaryFragment = root.createFragment();\n const secondaryFragment =\n root.createFragment();\n\n const declineButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I decline',\n );\n\n const agreeButton = root.createComponent(\n Button,\n {\n kind: 'secondary',\n onPress: () => {},\n },\n 'I agree',\n );\n\n const preferencesButton =\n root.createComponent(\n Button,\n {\n kind: 'plain',\n },\n 'Preferences',\n );\n\n primaryFragment.appendChild(declineButton);\n primaryFragment.appendChild(agreeButton);\n secondaryFragment.appendChild(\n preferencesButton,\n );\n\n const sheet = root.createComponent(Sheet, {\n accessibilityLabel:\n 'A sheet that collects privacy consent preferences',\n defaultOpen:\n customerPrivacy.current.shouldShowBanner,\n primaryAction: primaryFragment,\n secondaryAction: secondaryFragment,\n });\n\n const textBlock = root.createComponent(\n TextBlock,\n null,\n [\n 'This website uses cookies to ensure you get the best experience on our website.',\n root.createComponent(\n Link,\n null,\n 'Learn more',\n ),\n ],\n );\n\n const inlineLayout = root.createComponent(\n InlineLayout,\n {\n padding: 'none',\n spacing: 'small100',\n columns: [38, 'fill'],\n },\n [\n root.createComponent(Image, {\n source: 'https://yourawesomeimage.com',\n }),\n textBlock,\n ],\n );\n\n sheet.appendChild(inlineLayout);\n root.appendChild(sheet);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [ + { + "name": "Ui", + "subtitle": "API", + "url": "ui", + "type": "API" + } + ] + }, + { + "name": "SkeletonImage", + "description": "SkeletonImage is used to provide a low fidelity representation of an image before it appears on the page.", + "requires": "", + "thumbnail": "skeletonimage-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "SkeletonImageProps", + "description": "", + "type": "SkeletonImageProps", + "typeDefinitions": { + "SkeletonImageProps": { + "filePath": "src/surfaces/checkout/components/SkeletonImage/SkeletonImage.ts", + "name": "SkeletonImageProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/SkeletonImage/SkeletonImage.ts", + "syntaxKind": "PropertySignature", + "name": "aspectRatio", + "value": "number", + "description": "Displays the skeleton at the specified aspect ratio (fills the width of the parent container and sets the height accordingly).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonImage/SkeletonImage.ts", + "syntaxKind": "PropertySignature", + "name": "blockSize", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust the block size of the skeleton.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonImage/SkeletonImage.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonImage/SkeletonImage.ts", + "syntaxKind": "PropertySignature", + "name": "inlineSize", + "value": "MaybeResponsiveConditionalStyle", + "description": "Adjust the inline size of the skeleton.", + "isOptional": true + } + ], + "value": "export interface SkeletonImageProps extends IdProps {\n /**\n * Adjust the block size of the skeleton.\n */\n blockSize?: MaybeResponsiveConditionalStyle;\n /**\n * Adjust the inline size of the skeleton.\n */\n inlineSize?: MaybeResponsiveConditionalStyle;\n /**\n * Displays the skeleton at the specified aspect ratio (fills the width of the\n * parent container and sets the height accordingly).\n */\n aspectRatio?: number;\n}" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Media and visuals", + "defaultExample": { + "image": "skeletonimage-default.png", + "codeblock": { + "title": "Basic SkeletonImage", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n SkeletonImage,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <SkeletonImage\n inlineSize={300}\n blockSize={300}\n />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, SkeletonImage} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const skeletonImage = root.createComponent(SkeletonImage, {\n inlineSize: 300,\n blockSize: 300,\n });\n\n root.appendChild(skeletonImage);\n});\n", + "language": "js" + } + ] + } + }, + "examples": { + "description": "", + "examples": [ + { + "description": "When adding content to a layout, incorporate a skeleton loader that renders the approximate size and position of the content during loading. This will provide a seamless transition from skeleton loaders to the content, and prevent any layout shift when the resulting content loads.", + "image": "loading-skeletons.gif", + "codeblock": { + "title": "Using skeleton loaders to prevent layout shifts on content load.", + "tabs": [ + { + "code": "import {\n reactExtension,\n View,\n BlockStack,\n InlineLayout,\n SkeletonImage,\n Image,\n Icon,\n SkeletonText,\n Text,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <LoadingStateSkeletons />,\n);\n\nexport const ProductThumbnail = ({\n source = 'https://yourawesomeimage.com',\n}) => (\n <View\n minBlockSize={64}\n cornerRadius=\"large\"\n maxInlineSize={64}\n minInlineSize={64}\n border=\"base\"\n >\n {source ? (\n <Image\n fit=\"cover\"\n aspectRatio={1}\n source={source}\n cornerRadius=\"large\"\n />\n ) : (\n <View maxInlineSize={33}>\n <Icon source=\"camera\" size=\"fill\" />\n </View>\n )}\n </View>\n);\nexport const LoadingStateSkeletons = () => {\n const loading = true;\n const [item1, item2] = [\n {\n title: 'Felipe Toledo WildFire',\n variantTitle: 'Medium',\n price: '$330.00',\n },\n {\n title: 'Roller',\n variantTitle: 'Medium',\n price: '$248.00',\n },\n ];\n const itemInfo = ({title, variantTitle}) =>\n loading ? (\n <>\n <SkeletonText>{title}</SkeletonText>\n <SkeletonText>\n {variantTitle}\n </SkeletonText>\n </>\n ) : (\n <>\n <Text emphasis=\"bold\">{title}</Text>\n <Text appearance=\"subdued\">\n {variantTitle}\n </Text>\n </>\n );\n const order = (item) => (\n <InlineLayout\n columns={['auto', 'fill', 'auto']}\n spacing=\"base\"\n blockAlignment=\"center\"\n >\n {loading ? (\n <SkeletonImage\n blockSize={64}\n inlineSize={64}\n />\n ) : (\n <ProductThumbnail />\n )}\n <BlockStack spacing=\"extraTight\">\n {itemInfo(item)}\n </BlockStack>\n {loading ? (\n <SkeletonText>{item.price}</SkeletonText>\n ) : (\n <Text emphasis=\"bold\">{item.price}</Text>\n )}\n </InlineLayout>\n );\n return (\n <View maxInlineSize={400}>\n <BlockStack>\n {order(item1)}\n {order(item2)}\n </BlockStack>\n </View>\n );\n};\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n View,\n InlineLayout,\n Image,\n Icon,\n Text,\n SkeletonImage,\n SkeletonText,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const source = 'https://yourawesomeimage.com';\n const loading = true;\n const [item1, item2] = [\n {\n title: 'Felipe Toledo WildFire',\n variantTitle: 'Medium',\n price: '$330.00',\n },\n {\n title: 'Roller',\n variantTitle: 'Medium',\n price: '$248.00',\n },\n ];\n const thumbnail = root.createComponent(\n View,\n {\n minBlockSize: 64,\n cornerRadius: 'large',\n maxInlineSize: 64,\n minInlineSize: 64,\n border: 'base',\n },\n [\n source\n ? root.createComponent(Image, {\n fit: 'cover',\n aspectRatio: 1,\n source,\n cornerRadius: 'large',\n })\n : root.createComponent(\n View,\n {maxInlineSize: 33},\n [\n root.createComponent(Icon, {\n source: 'camera',\n size: 'fill',\n }),\n ],\n ),\n ],\n );\n const itemInfo = ({title, variantTitle}) =>\n root.createComponent(\n BlockStack,\n {\n spacing: 'extraTight',\n },\n [\n loading\n ? (root.createComponent(\n SkeletonText,\n {},\n title,\n ),\n root.createComponent(\n SkeletonText,\n {},\n variantTitle,\n ))\n : (root.createComponent(\n Text,\n {},\n title,\n ),\n root.createComponent(\n Text,\n {},\n variantTitle,\n )),\n ],\n );\n const order = (item) =>\n root.createComponent(\n InlineLayout,\n {\n columns: ['auto', 'fill', 'auto'],\n spacing: 'base',\n blockAlignment: 'center',\n },\n [\n loading\n ? root.createComponent(\n SkeletonImage,\n {\n blockSize: 64,\n inlineSize: 64,\n },\n )\n : thumbnail,\n itemInfo(item),\n loading\n ? root.createComponent(\n SkeletonText,\n {},\n item.price,\n )\n : root.createComponent(\n Text,\n {},\n item.price,\n ),\n ],\n );\n const view = root.createComponent(\n View,\n {\n maxInlineSize: 400,\n },\n [\n root.createComponent(BlockStack, {}, [\n order(item1),\n order(item2),\n ]),\n ],\n );\n root.appendChild(view);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [] + }, + { + "name": "SkeletonText", + "description": "SkeletonText is used to provide a low fidelity representation of text content before it appears on the page. \n\nOptionally you can use any text content inside `SkeletonText` to be used as a base for the rendered skeleton", + "requires": "", + "isVisualComponent": true, + "thumbnail": "skeletontext-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "SkeletonTextProps", + "description": "", + "type": "SkeletonTextProps", + "typeDefinitions": { + "SkeletonTextProps": { + "filePath": "src/surfaces/checkout/components/SkeletonText/SkeletonText.ts", + "name": "SkeletonTextProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/SkeletonText/SkeletonText.ts", + "syntaxKind": "PropertySignature", + "name": "emphasis", + "value": "'bold'", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonText/SkeletonText.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonText/SkeletonText.ts", + "syntaxKind": "PropertySignature", + "name": "inlineSize", + "value": "'small' | 'large' | 'base'", + "description": "Adjust the length of the text when no children are passed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonText/SkeletonText.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "TextSize", + "description": "Size of the text the skeleton replaces.", + "isOptional": true + } + ], + "value": "export interface SkeletonTextProps extends IdProps {\n /**\n * @private\n * Use to emphasize a word or a group of words.\n */\n emphasis?: 'bold';\n /**\n * Adjust the length of the text when no children are passed.\n */\n inlineSize?: Extract;\n /**\n * Size of the text the skeleton replaces.\n */\n size?: TextSize;\n}" + }, + "TextSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "TextSize", + "value": "Extract | 'medium'", + "description": "" + }, + "Size": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Size", + "value": "'extraSmall' | 'small' | 'base' | 'large' | 'extraLarge' | 'fill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "skeletontext-default.png", + "codeblock": { + "title": "Basic SkeletonText", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n SkeletonText,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <SkeletonText />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, SkeletonText} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const skeletonText = root.createComponent(SkeletonText);\n\n root.appendChild(skeletonText);\n});\n", + "language": "js" + } + ] + } + }, + "examples": { + "description": "", + "examples": [ + { + "description": "When adding content to a layout, incorporate a skeleton loader that renders the approximate size and position of the content during loading. This will provide a seamless transition from skeleton loaders to the content, and prevent any layout shift when the resulting content loads.", + "image": "loading-skeletons.gif", + "codeblock": { + "title": "Using skeleton loaders to prevent layout shifts on content load.", + "tabs": [ + { + "code": "import {\n reactExtension,\n View,\n BlockStack,\n InlineLayout,\n SkeletonImage,\n Image,\n Icon,\n SkeletonText,\n Text,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <LoadingStateSkeletons />,\n);\n\nexport const ProductThumbnail = ({\n source = 'https://yourawesomeimage.com',\n}) => (\n <View\n minBlockSize={64}\n cornerRadius=\"large\"\n maxInlineSize={64}\n minInlineSize={64}\n border=\"base\"\n >\n {source ? (\n <Image\n fit=\"cover\"\n aspectRatio={1}\n source={source}\n cornerRadius=\"large\"\n />\n ) : (\n <View maxInlineSize={33}>\n <Icon source=\"camera\" size=\"fill\" />\n </View>\n )}\n </View>\n);\nexport const LoadingStateSkeletons = () => {\n const loading = true;\n const [item1, item2] = [\n {\n title: 'Felipe Toledo WildFire',\n variantTitle: 'Medium',\n price: '$330.00',\n },\n {\n title: 'Roller',\n variantTitle: 'Medium',\n price: '$248.00',\n },\n ];\n const itemInfo = ({title, variantTitle}) =>\n loading ? (\n <>\n <SkeletonText>{title}</SkeletonText>\n <SkeletonText>\n {variantTitle}\n </SkeletonText>\n </>\n ) : (\n <>\n <Text emphasis=\"bold\">{title}</Text>\n <Text appearance=\"subdued\">\n {variantTitle}\n </Text>\n </>\n );\n const order = (item) => (\n <InlineLayout\n columns={['auto', 'fill', 'auto']}\n spacing=\"base\"\n blockAlignment=\"center\"\n >\n {loading ? (\n <SkeletonImage\n blockSize={64}\n inlineSize={64}\n />\n ) : (\n <ProductThumbnail />\n )}\n <BlockStack spacing=\"extraTight\">\n {itemInfo(item)}\n </BlockStack>\n {loading ? (\n <SkeletonText>{item.price}</SkeletonText>\n ) : (\n <Text emphasis=\"bold\">{item.price}</Text>\n )}\n </InlineLayout>\n );\n return (\n <View maxInlineSize={400}>\n <BlockStack>\n {order(item1)}\n {order(item2)}\n </BlockStack>\n </View>\n );\n};\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n BlockStack,\n View,\n InlineLayout,\n Image,\n Icon,\n Text,\n SkeletonImage,\n SkeletonText,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const source = 'https://yourawesomeimage.com';\n const loading = true;\n const [item1, item2] = [\n {\n title: 'Felipe Toledo WildFire',\n variantTitle: 'Medium',\n price: '$330.00',\n },\n {\n title: 'Roller',\n variantTitle: 'Medium',\n price: '$248.00',\n },\n ];\n const thumbnail = root.createComponent(\n View,\n {\n minBlockSize: 64,\n cornerRadius: 'large',\n maxInlineSize: 64,\n minInlineSize: 64,\n border: 'base',\n },\n [\n source\n ? root.createComponent(Image, {\n fit: 'cover',\n aspectRatio: 1,\n source,\n cornerRadius: 'large',\n })\n : root.createComponent(\n View,\n {maxInlineSize: 33},\n [\n root.createComponent(Icon, {\n source: 'camera',\n size: 'fill',\n }),\n ],\n ),\n ],\n );\n const itemInfo = ({title, variantTitle}) =>\n root.createComponent(\n BlockStack,\n {\n spacing: 'extraTight',\n },\n [\n loading\n ? (root.createComponent(\n SkeletonText,\n {},\n title,\n ),\n root.createComponent(\n SkeletonText,\n {},\n variantTitle,\n ))\n : (root.createComponent(\n Text,\n {},\n title,\n ),\n root.createComponent(\n Text,\n {},\n variantTitle,\n )),\n ],\n );\n const order = (item) =>\n root.createComponent(\n InlineLayout,\n {\n columns: ['auto', 'fill', 'auto'],\n spacing: 'base',\n blockAlignment: 'center',\n },\n [\n loading\n ? root.createComponent(\n SkeletonImage,\n {\n blockSize: 64,\n inlineSize: 64,\n },\n )\n : thumbnail,\n itemInfo(item),\n loading\n ? root.createComponent(\n SkeletonText,\n {},\n item.price,\n )\n : root.createComponent(\n Text,\n {},\n item.price,\n ),\n ],\n );\n const view = root.createComponent(\n View,\n {\n maxInlineSize: 400,\n },\n [\n root.createComponent(BlockStack, {}, [\n order(item1),\n order(item2),\n ]),\n ],\n );\n root.appendChild(view);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [] + }, + { + "name": "SkeletonTextBlock", + "description": "SkeletonTextBlock is used to provide a low fidelity representation of a block of text before it appears on the page. \n\nOptionally you can use any text content inside `SkeletonTextBlock` to be used as a base for the rendered skeleton", + "requires": "", + "isVisualComponent": true, + "thumbnail": "skeletontextblock-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "SkeletonTextBlockProps", + "description": "", + "type": "SkeletonTextBlockProps", + "typeDefinitions": { + "SkeletonTextBlockProps": { + "filePath": "src/surfaces/checkout/components/SkeletonTextBlock/SkeletonTextBlock.ts", + "name": "SkeletonTextBlockProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/SkeletonTextBlock/SkeletonTextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "emphasis", + "value": "'bold'", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonTextBlock/SkeletonTextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonTextBlock/SkeletonTextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "lines", + "value": "number", + "description": "Number of lines to display when no children are passed.", + "isOptional": true, + "defaultValue": "1" + }, + { + "filePath": "src/surfaces/checkout/components/SkeletonTextBlock/SkeletonTextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "TextSize", + "description": "Size of the text the skeleton replaces.", + "isOptional": true + } + ], + "value": "export interface SkeletonTextBlockProps extends IdProps {\n /**\n * @private\n * Use to emphasize a word or a group of words.\n */\n emphasis?: 'bold';\n /**\n * Number of lines to display when no children are passed.\n *\n * @defaultValue 1\n */\n lines?: number;\n /**\n * Size of the text the skeleton replaces.\n */\n size?: TextSize;\n}" + }, + "TextSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "TextSize", + "value": "Extract | 'medium'", + "description": "" + }, + "Size": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Size", + "value": "'extraSmall' | 'small' | 'base' | 'large' | 'extraLarge' | 'fill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "skeletontextblock-default.png", + "codeblock": { + "title": "Basic SkeletonTextBlock", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n SkeletonTextBlock,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <SkeletonTextBlock />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, SkeletonTextBlock} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const skeletonTextBlock = root.createComponent(SkeletonTextBlock);\n\n root.appendChild(skeletonTextBlock);\n});\n", + "language": "js" + } + ] + } + }, + "related": [] + }, + { + "name": "Spinner", + "description": "Spinner is used to notify buyers that their action is being processed. The Spinner is usually used when sending or receiving data from a server.", + "requires": "", + "thumbnail": "spinner-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "SpinnerProps", + "description": "", + "type": "SpinnerProps", + "typeDefinitions": { + "SpinnerProps": { + "filePath": "src/surfaces/checkout/components/Spinner/Spinner.ts", + "name": "SpinnerProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Spinner/Spinner.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label to use for the Spinner that will be used for buyers using assistive technologies like screen readers. If will also be used to replace the animated loading indicator when buyers prefers reduced motion. If not included, it will use the loading indicator for all buyers.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Spinner/Spinner.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'accent' | 'monochrome'", + "description": "Sets the appearance (color) of the icon.", + "isOptional": true, + "defaultValue": "'accent'" + }, + { + "filePath": "src/surfaces/checkout/components/Spinner/Spinner.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Spinner/Spinner.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "'extraSmall' | 'small' | 'large' | 'base' | 'fill'", + "description": "Adjusts the size of the icon.", + "isOptional": true, + "defaultValue": "'base'" + } + ], + "value": "export interface SpinnerProps extends IdProps {\n /**\n * Adjusts the size of the icon.\n *\n * @defaultValue 'base'\n */\n size?: Extract;\n\n /**\n * Sets the appearance (color) of the icon.\n *\n * @defaultValue 'accent'\n */\n appearance?: Extract;\n\n /**\n * A label to use for the Spinner that will be used for buyers using\n * assistive technologies like screen readers. If will also be used to replace\n * the animated loading indicator when buyers prefers reduced motion. If not included,\n * it will use the loading indicator for all buyers.\n */\n accessibilityLabel?: string;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Feedback and status indicators", + "defaultExample": { + "image": "spinner-default.png", + "codeblock": { + "title": "Basic Spinner", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Spinner,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Spinner />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Spinner} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const spinner = root.createComponent(Spinner);\n\n root.appendChild(spinner);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"accent\" | Conveys emphasis and draws attention to the element. |\n| \"monochrome\" | Takes the color of its parent.|" + } + ], + "related": [ + { + "name": "Progress", + "subtitle": "Component", + "url": "progress", + "type": "Component" + } + ] + }, + { + "name": "Stepper", + "description": "Use a stepper to increase or decrease a value, like changing the quantity from 1 to 2.", + "requires": "", + "thumbnail": "stepper-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "StepperProps", + "description": "", + "type": "StepperProps", + "typeDefinitions": { + "StepperProps": { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "name": "StepperProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityDescription", + "value": "string", + "description": "A detailed description for screen readers.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the field can be modified.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "error", + "value": "string", + "description": "Indicate an error to the user. The field will be given a specific stylistic treatment to communicate problems that have to be resolved immediately.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "icon", + "value": "IconSource", + "description": "An icon to render at the start of the field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the field. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "Content to use as the field label. This value is also used as the placeholder when the field is empty." + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "max", + "value": "number", + "description": "The highest decimal or integer to be accepted for the stepper field. When used with `step` the value will round down to the max number. Note: a buyer will still be able to use the keyboard to input a number higher than the max. It is up to the developer to add appropriate validation.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "min", + "value": "number", + "description": "The lowest decimal or integer to be accepted for the stepper field. When used with `step` the value will round up to the min number. Note: a buyer will still be able to use the keyboard to input a number lower than the min. It is up to the developer to add appropriate validation.", + "isOptional": true, + "defaultValue": "0" + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "MethodSignature", + "name": "onBlur", + "value": "() => void", + "description": "Callback when focus is removed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: number) => void", + "description": "Callback when the buyer has **finished editing** a field. Unlike `onChange` callbacks you may be familiar with from Polaris or other React component libraries, this callback is **not** run on every change to the input. Text fields are “partially controlled” components, which means that while the buyer edits the field, its state is controlled by the component. Once the buyer has signalled that they have finished editing the field (typically, by blurring the field), `onChange` is called if the input actually changed from the most recent `value` property. At that point, you are expected to store this “committed value” in state, and reflect it in the text field’s `value` property.\n\nThis state management model is important given how UI Extensions are rendered. UI Extension components run on a separate thread from the UI, so they can’t respond to input synchronously. A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components) is to have the component be the source of truth for the input `value`, and update the `value` on every user input. The delay in responding to events from a UI extension is only a few milliseconds, but attempting to strictly store state with this delay can cause issues if a user types quickly, or if the buyer is using a lower-powered device. Having the UI thread take ownership for “in progress” input, and only synchronizing when the user is finished with a field, avoids this risk.\n\nIt can still sometimes be useful to be notified when the user makes any input in the field. If you need this capability, you can use the `onInput` prop. However, never use that property to create tightly controlled state for the `value`.\n\nThis callback is called with the current value of the field. If the value of a field is the same as the current `value` prop provided to the field, the `onChange` callback will not be run.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "MethodSignature", + "name": "onFocus", + "value": "() => void", + "description": "Callback when input is focused.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "MethodSignature", + "name": "onInput", + "value": "(value: number) => void", + "description": "Callback when the user makes any changes in the field. As noted in the documentation for `onChange`, you **must not** use this to update `state` — use the `onChange` callback for that purpose. Use the `onInput` prop when you need to do something as soon as the buyer makes a change, like clearing validation errors that apply to the field as soon as the user begins making the necessary adjustments.\n\nThis callback is called with the current value of the field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "prefix", + "value": "string", + "description": "Text content to render before the value.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "readonly", + "value": "boolean", + "description": "Whether the field is read-only.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "required", + "value": "boolean", + "description": "Whether the field needs a value. This requirement adds semantic value to the field, but it will not cause an error to appear automatically. If you want to present an error when this field is empty, you can do so with the `error` prop.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "step", + "value": "number", + "description": "The amount the value can increase or decrease by. This can be an integer or decimal. If a `max` or `min` is specified with `step` when increasing/decreasing the value via the stepper buttons the final value will always round to the `max` or `min` rather than the closest valid amount.", + "isOptional": true, + "defaultValue": "1" + }, + { + "filePath": "src/surfaces/checkout/components/Stepper/Stepper.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "number | undefined", + "description": "The current value for the field. If omitted, the field will be empty. You should update this value in response to the `onChange` callback.", + "isOptional": true + } + ], + "value": "export interface StepperProps {\n /**\n * A detailed description for screen readers.\n */\n accessibilityDescription?: string;\n\n /**\n * Whether the field can be modified.\n */\n disabled?: boolean;\n\n /**\n * Indicate an error to the user. The field will be given a specific stylistic treatment\n * to communicate problems that have to be resolved immediately.\n */\n error?: string;\n\n /**\n * Content to use as the field label. This value is also used as the placeholder\n * when the field is empty.\n */\n label: string;\n\n /**\n * An icon to render at the start of the field.\n */\n icon?: IconSource;\n\n /**\n * A unique identifier for the field. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n\n /**\n * The highest decimal or integer to be accepted for the stepper field.\n * When used with `step` the value will round down to the max number.\n * Note: a buyer will still be able to use the keyboard to input a number higher than\n * the max. It is up to the developer to add appropriate validation.\n */\n max?: number;\n\n /**\n * The lowest decimal or integer to be accepted for the stepper field.\n * When used with `step` the value will round up to the min number.\n * Note: a buyer will still be able to use the keyboard to input a number lower than\n * the min. It is up to the developer to add appropriate validation.\n *\n * @defaultValue 0\n */\n min?: number;\n\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n\n /**\n * Text content to render before the value.\n */\n prefix?: string;\n\n /**\n * Whether the field is read-only.\n */\n readonly?: boolean;\n\n /**\n * Whether the field needs a value. This requirement adds semantic value\n * to the field, but it will not cause an error to appear automatically.\n * If you want to present an error when this field is empty, you can do\n * so with the `error` prop.\n */\n required?: boolean;\n\n /**\n * The amount the value can increase or decrease by. This can be an integer or decimal.\n * If a `max` or `min` is specified with `step` when increasing/decreasing the value\n * via the stepper buttons the final value will always round to the `max` or `min`\n * rather than the closest valid amount.\n *\n * @defaultValue 1\n */\n step?: number;\n\n /**\n * The current value for the field. If omitted, the field will be empty. You should\n * update this value in response to the `onChange` callback.\n */\n value?: number | undefined;\n\n /**\n * Callback when input is focused.\n */\n onFocus?(): void;\n\n /**\n * Callback when focus is removed.\n */\n onBlur?(): void;\n\n /**\n * Callback when the buyer has **finished editing** a field. Unlike `onChange`\n * callbacks you may be familiar with from Polaris or other React component libraries,\n * this callback is **not** run on every change to the input. Text fields are\n * “partially controlled” components, which means that while the buyer edits the\n * field, its state is controlled by the component. Once the buyer has signalled that\n * they have finished editing the field (typically, by blurring the field), `onChange`\n * is called if the input actually changed from the most recent `value` property. At\n * that point, you are expected to store this “committed value” in state, and reflect\n * it in the text field’s `value` property.\n *\n * This state management model is important given how UI Extensions are rendered. UI Extension components\n * run on a separate thread from the UI, so they can’t respond to input synchronously.\n * A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components)\n * is to have the component be the source of truth for the input `value`, and update\n * the `value` on every user input. The delay in responding to events from a UI\n * extension is only a few milliseconds, but attempting to strictly store state with\n * this delay can cause issues if a user types quickly, or if the buyer is using a\n * lower-powered device. Having the UI thread take ownership for “in progress” input,\n * and only synchronizing when the user is finished with a field, avoids this risk.\n *\n * It can still sometimes be useful to be notified when the user makes any input in\n * the field. If you need this capability, you can use the `onInput` prop. However,\n * never use that property to create tightly controlled state for the `value`.\n *\n * This callback is called with the current value of the field. If the value of a field\n * is the same as the current `value` prop provided to the field, the `onChange` callback\n * will not be run.\n */\n onChange?(value: number | undefined): void;\n\n /**\n * Callback when the user makes any changes in the field. As noted in the documentation\n * for `onChange`, you **must not** use this to update `state` — use the `onChange`\n * callback for that purpose. Use the `onInput` prop when you need to do something\n * as soon as the buyer makes a change, like clearing validation errors that apply to\n * the field as soon as the user begins making the necessary adjustments.\n *\n * This callback is called with the current value of the field.\n */\n onInput?(value: number | undefined): void;\n}" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "stepper-default.png", + "codeblock": { + "title": "Basic Stepper", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Stepper,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Stepper label=\"Quantity\" value={1} />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Stepper} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const stepper = root.createComponent(Stepper, {\n label: 'Quantity',\n value: 1,\n });\n\n root.appendChild(stepper);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use this component when customers are likely to choose a number within a small range, such as when changing a quantity from one to three.\n\n- If there’s no default number, then consider choosing another component such as a TextField or Select." + } + ], + "related": [] + }, + { + "name": "Switch", + "description": "Use a switch to represent an on or off state that takes effect immediately when tapped.", + "requires": "", + "isVisualComponent": true, + "thumbnail": "switch-thumbnail.png", + "type": "", + "definitions": [ + { + "title": "SwitchProps", + "description": "", + "type": "SwitchProps", + "typeDefinitions": { + "SwitchProps": { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "name": "SwitchProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "checked", + "value": "boolean", + "description": "Whether the switch is active.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the switch can be changed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "Visual content to use as the switch label.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: boolean) => void", + "description": "A callback that is run whenever the switch is changed. This callback is called with a boolean indicating whether the switch should now be active or inactive. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), so you must store this value in state and reflect it back in the `checked` or `value` props.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "toggles", + "value": "string", + "description": "The component's identifier whose visibility will be toggled when this component is actioned.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Switch/Switch.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "boolean", + "description": "Whether the switch is selected. This prop is an alias for `checked`, and can be useful in form libraries that provide a normalized API for dealing with both `boolean` and `string` values. If both `value` and `checked` are set, `checked` takes precedence.", + "isOptional": true + } + ], + "value": "export interface SwitchProps extends IdProps, DisclosureActivatorProps {\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n\n /**\n * Whether the switch is active.\n */\n checked?: boolean;\n\n /**\n * Visual content to use as the switch label.\n */\n label?: string;\n\n /**\n * Whether the switch is selected. This prop is an alias for `checked`,\n * and can be useful in form libraries that provide a normalized API for\n * dealing with both `boolean` and `string` values. If both `value` and\n * `checked` are set, `checked` takes precedence.\n */\n value?: boolean;\n\n /**\n * Whether the switch can be changed.\n */\n disabled?: boolean;\n\n /**\n * A label used for buyers using assistive technologies.\n */\n accessibilityLabel?: string;\n\n /**\n * A callback that is run whenever the switch is changed. This callback\n * is called with a boolean indicating whether the switch should now be\n * active or inactive. This component is [controlled](https://reactjs.org/docs/forms.html#controlled-components),\n * so you must store this value in state and reflect it back in the\n * `checked` or `value` props.\n */\n onChange?(value: boolean): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "switch-default.png", + "codeblock": { + "title": "Basic Switch", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Switch,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Switch accessibilityLabel=\"my-switch\" />\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Switch} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const baseSwitch = root.createComponent(Switch, {\n accessibilityLabel: 'my-switch',\n });\n\n root.appendChild(baseSwitch);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "\n- The outcome of a switch should take effect immediately when tapped.\n- Use for independent settings, like turning on a stand-alone feature.\n- Most of the time no call-to-action should be needed as the switch should take effect immediately, but if the experience needs one, use “done” instead of “submit” or “apply”.\n\n### Content\nThe label should be a noun. Try explaining the setting out loud to test the name. The name should make sense when you insert it into these statements:\n\n- You can turn [setting_label] on or off in settings.\n- [setting_label] is on.\n- [setting_label] is off.\n\n### Switch vs checkbox\n- If the experience requires multiple connected inputs, like a survey, use a checkbox instead of a switch.\n- If the experience requires an error state, like agreeing to terms and conditions, use a checkbox instead of a switch. Both on and off options for a switch should always be valid.\n- If you’re unsure, default to a checkbox as it’s the more familiar web pattern.\n\n\n " + } + ], + "examples": { + "description": "", + "examples": [ + { + "description": "This example demonstrates pairing the switch with a custom label and layout while keeping it accessible to screen readers.", + "image": "switch-custom-label.png", + "codeblock": { + "title": "Custom label", + "tabs": [ + { + "code": "import {\n reactExtension,\n InlineLayout,\n Switch,\n Text,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.footer.render-after',\n () => <Extension />,\n);\n\nfunction Extension() {\n const switchLabel = 'Shipping insurance';\n return (\n <InlineLayout\n padding=\"base\"\n borderRadius=\"base\"\n border=\"base\"\n columns={['fill', 'auto']}\n >\n <Text>{switchLabel}</Text>\n <Switch accessibilityLabel={switchLabel} />\n </InlineLayout>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n InlineLayout,\n Switch,\n Text,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const switchLabel = 'Shipping insurance';\n\n const inlineLayout = root.createComponent(\n InlineLayout,\n {\n padding: 'base',\n borderRadius: 'base',\n border: 'base',\n columns: ['fill', 'auto'],\n },\n [\n root.createComponent(\n Text,\n null,\n switchLabel,\n ),\n root.createComponent(Switch, {\n accessibilityLabel: switchLabel,\n }),\n ],\n );\n\n root.appendChild(inlineLayout);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [ + { + "name": "Checkbox", + "subtitle": "Component", + "url": "checkbox", + "type": "Component" + } + ] + }, + { + "name": "Tag", + "description": "A Tag is used to help label, organize or categorize objects. It is commonly used in Checkout to display the discounts applied to a cart.", + "requires": "", + "thumbnail": "tag-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "TagProps", + "description": "", + "type": "TagProps", + "typeDefinitions": { + "TagProps": { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "name": "TagProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "syntaxKind": "PropertySignature", + "name": "children", + "value": "string", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "syntaxKind": "PropertySignature", + "name": "icon", + "value": "IconSource", + "description": "Icon source", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Tag/Tag.ts", + "syntaxKind": "MethodSignature", + "name": "onRemove", + "value": "() => void", + "description": "Callback when tag is removed", + "isOptional": true + } + ], + "value": "export interface TagProps extends IdProps {\n children?: string;\n /**\n * Icon source\n */\n icon?: IconSource;\n /**\n * A label used for buyers using assistive technologies. When set, any\n * `children` supplied to this component will not be announced to screen reader users.\n */\n accessibilityLabel?: string;\n /**\n * Callback when tag is removed\n */\n onRemove?(): void;\n}" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "tag-default.png", + "codeblock": { + "title": "Basic Tag", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Tag,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Tag icon=\"discount\">SPRING</Tag>;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Tag} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const tag = root.createComponent(Tag, {icon: 'discount'}, 'SPRING');\n\n root.appendChild(tag);\n});\n", + "language": "js" + } + ] + } + }, + "related": [] + }, + { + "name": "Text", + "description": "Text is used to visually style and provide semantic value for a small piece of text content.", + "requires": "", + "thumbnail": "text-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "TextProps", + "description": "", + "type": "TextProps", + "typeDefinitions": { + "TextProps": { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "name": "TextProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "TextAccessibilityRole", + "description": "Set the semantic of the component’s content", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityVisibility", + "value": "AccessibilityVisibility", + "description": "Changes the visibility of the element to assistive technologies.\n\n`hidden` hides the component from assistive technology (for example, a screen reader) but remains visually visible.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'subdued' | 'accent' | 'decorative' | 'info' | 'success' | 'warning' | 'critical'", + "description": "Changes the visual appearance", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "emphasis", + "value": "Emphasis", + "description": "Use to emphasize a word or a group of words.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "Unique identifier. Typically used as a target for another component’s controls to associate an accessible label with an action.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "TextSize", + "description": "Size of the text", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/Text/Text.ts", + "syntaxKind": "PropertySignature", + "name": "visibility", + "value": "Visibility", + "description": "Changes the visibility of the element.\n\n`hidden` visually hides the component while keeping it accessible to assistive technology, such as screen readers. Hidden elements don't take any visual space contrary to CSS visibility: hidden;", + "isOptional": true + } + ], + "value": "export interface TextProps extends VisibilityProps {\n /**\n * Size of the text\n */\n size?: TextSize;\n /**\n * Use to emphasize a word or a group of words.\n */\n emphasis?: Emphasis;\n /**\n * Set the semantic of the component’s content\n */\n accessibilityRole?: TextAccessibilityRole;\n /**\n * Unique identifier. Typically used as a target for another component’s controls\n * to associate an accessible label with an action.\n */\n id?: string;\n /**\n * Changes the visual appearance\n */\n appearance?: Extract<\n Appearance,\n | 'accent'\n | 'subdued'\n | 'info'\n | 'success'\n | 'warning'\n | 'critical'\n | 'decorative'\n >;\n}" + }, + "TextAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "TextAccessibilityRole", + "value": "'address' | 'deletion' | 'marking' | {type: 'abbreviation'; for?: string} | {type: 'directional-override'; direction: 'ltr' | 'rtl'} | {type: 'datetime'; machineReadable?: string} | 'stress' | 'offset' | 'strong'", + "description": "" + }, + "AccessibilityVisibility": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AccessibilityVisibility", + "value": "'hidden'", + "description": "" + }, + "Emphasis": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Emphasis", + "value": "'italic' | 'bold'", + "description": "Use to emphasize a word or a group of words." + }, + "TextSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "TextSize", + "value": "Extract | 'medium'", + "description": "" + }, + "Size": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Size", + "value": "'extraSmall' | 'small' | 'base' | 'large' | 'extraLarge' | 'fill'", + "description": "" + }, + "Visibility": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Visibility", + "value": "'hidden'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "text-default.png", + "codeblock": { + "title": "Basic Text", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Text,\n BlockStack,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <BlockStack inlineAlignment=\"center\">\n <Text size=\"extraSmall\">Total</Text>\n <Text size=\"small\">Total</Text>\n <Text size=\"base\">Total</Text>\n <Text size=\"medium\">Total</Text>\n <Text size=\"large\">Total</Text>\n <Text size=\"extraLarge\">Total</Text>\n </BlockStack>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, Text, BlockStack} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const text = root.createComponent(BlockStack, undefined, [\n root.createComponent(Text, {size: 'extraSmall'}, 'Total'),\n root.createComponent(Text, {size: 'small'}, 'Total'),\n root.createComponent(Text, {size: 'base'}, 'Total'),\n root.createComponent(Text, {size: 'medium'}, 'Total'),\n root.createComponent(Text, {size: 'large'}, 'Total'),\n root.createComponent(Text, {size: 'extraLarge'}, 'Total'),\n ]);\n\n root.appendChild(text);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"accent\" | Conveys emphasis and draws attention to the element. |\n| \"subdued\" | Conveys a subdued or disabled state for the element. |\n| \"info\" | Conveys that the element is informative or has information. |\n| \"success\" | Convey a successful interaction. |\n| \"warning\" | Convey something needs attention or an action needs to be taken. |\n| \"critical\" | Conveys a problem has arisen. |" + }, + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Use larger text to emphasize content that’s not a heading, such as a price total.\n\n- Create contrast between more and less important text with properties such as `size` and `subdued`." + } + ], + "related": [ + { + "name": "Heading", + "subtitle": "Component", + "url": "heading", + "type": "Component" + }, + { + "name": "HeadingGroup", + "subtitle": "Component", + "url": "headinggroup", + "type": "Component" + }, + { + "name": "TextBlock", + "subtitle": "Component", + "url": "textblock", + "type": "Component" + } + ] + }, + { + "name": "TextBlock", + "description": "Text block is used to render a block of text that occupies the full width available, like a paragraph.", + "requires": "", + "thumbnail": "textblock-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "TextBlockProps", + "description": "", + "type": "TextBlockProps", + "typeDefinitions": { + "TextBlockProps": { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "name": "TextBlockProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "appearance", + "value": "'subdued' | 'accent' | 'decorative' | 'info' | 'success' | 'warning' | 'critical'", + "description": "Changes the visual appearance", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "emphasis", + "value": "Emphasis", + "description": "Use to emphasize a word or a group of words.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "InlineAlignment", + "description": "Align text along the main axis.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextBlock/TextBlock.ts", + "syntaxKind": "PropertySignature", + "name": "size", + "value": "TextSize", + "description": "Size of the text", + "isOptional": true + } + ], + "value": "export interface TextBlockProps extends IdProps {\n /**\n * Size of the text\n */\n size?: TextSize;\n /**\n * Use to emphasize a word or a group of words.\n */\n emphasis?: Emphasis;\n /**\n * Changes the visual appearance\n */\n appearance?: Extract<\n Appearance,\n | 'accent'\n | 'subdued'\n | 'info'\n | 'success'\n | 'warning'\n | 'critical'\n | 'decorative'\n >;\n /**\n * Align text along the main axis.\n */\n inlineAlignment?: InlineAlignment;\n}" + }, + "Emphasis": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Emphasis", + "value": "'italic' | 'bold'", + "description": "Use to emphasize a word or a group of words." + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "TextSize": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "TextSize", + "value": "Extract | 'medium'", + "description": "" + }, + "Size": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Size", + "value": "'extraSmall' | 'small' | 'base' | 'large' | 'extraLarge' | 'fill'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Typography and content", + "defaultExample": { + "image": "textblock-default.png", + "codeblock": { + "title": "Basic TextBlock", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n TextBlock,\n BlockStack,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <BlockStack>\n <TextBlock>\n We have a 30-day return policy, which\n means you have 30 days after receiving\n your item to request a return.\n </TextBlock>\n <TextBlock>\n To be eligible for a return, your item\n must be in the same condition that you\n received it, unworn or unused, with tags,\n and in its original packaging. You’ll also\n need the receipt or proof of purchase.\n </TextBlock>\n </BlockStack>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n TextBlock,\n BlockStack,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const textBlock = root.createComponent(BlockStack, undefined, [\n root.createComponent(\n TextBlock,\n undefined,\n 'We have a 30-day return policy, which means you have 30 days after receiving your item to request a return.',\n ),\n root.createComponent(\n TextBlock,\n undefined,\n 'To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase.',\n ),\n ]);\n\n root.appendChild(textBlock);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "appearance", + "title": "Appearance", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"accent\" | Conveys emphasis and draws attention to the element. |\n| \"subdued\" | Conveys a subdued or disabled state for the element. |\n| \"info\" | Conveys that the element is informative or has information. |\n| \"success\" | Convey a successful interaction. |\n| \"warning\" | Convey something needs attention or an action needs to be taken. |\n| \"critical\" | Conveys a problem has arisen. |" + }, + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Create contrast between more and less important text with properties such as `size`, `emphasis`, and `appearance`." + } + ], + "related": [ + { + "name": "Heading", + "subtitle": "Component", + "url": "heading", + "type": "Component" + }, + { + "name": "HeadingGroup", + "subtitle": "Component", + "url": "headinggroup", + "type": "Component" + }, + { + "name": "Text", + "subtitle": "Component", + "url": "text", + "type": "Component" + } + ] + }, + { + "name": "TextField", + "description": "Use a text field to get text input from a customer.", + "requires": "", + "thumbnail": "textfield-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "TextFieldProps", + "description": "", + "type": "TextFieldProps", + "typeDefinitions": { + "TextFieldProps": { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "name": "TextFieldProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityDescription", + "value": "string", + "description": "A detailed description for screen readers.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "accessory", + "value": "string | RemoteFragment", + "description": "Any content to render at the end of the text field. Commonly used to display an icon that opens a tooltip providing more information about the field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "autocomplete", + "value": "Autocomplete | boolean", + "description": "A hint as to the intended content of the field.\n\nWhen set to `true`, this property indicates that the field should support autofill, but you do not have any more semantic information on the intended contents.\n\nWhen set to `false`, you are indicating that this field contains sensitive information, or contents that are never saved, like one-time codes.\n\nAlternatively, you can provide an `Autocomplete` object, which describes the specific data you would like to be entered into this field during autofill.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "controlledValue", + "value": "T", + "description": "In rare cases, like the PhoneField component, we completely control state. In those cases, there is never a difference between the `value` prop of the field and the current value in the field, and so this component never considers the field to have changed. Use the `controlledValue` prop to provide the value that should be shown to the buyer in those circumstances, but where the `value` prop will continue to be used as the comparison value to determine whether the field has changed. This value will usually be set to the last committed, unformatted value for the controlled input.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the field can be modified.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "error", + "value": "string", + "description": "Indicate an error to the user. The field will be given a specific stylistic treatment to communicate problems that have to be resolved immediately.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "icon", + "value": "IconSource | {source: IconSource; position?: 'start' | 'end'}", + "description": "An icon to render at the start or end of the field. It will render at the start by default.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the field. When no `id` is set, a globally unique value will be used instead.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "label", + "value": "string", + "description": "Content to use as the field label. This value is also used as the placeholder when the field is empty." + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "maxLength", + "value": "number", + "description": "Specifies the maximum number of characters allowed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "multiline", + "value": "boolean | number", + "description": "Whether the field supports multiple lines of input. Set a `number` to define the default lines of the input.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "name", + "value": "string", + "description": "An identifier for the field that is unique within the nearest containing `Form` component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "MethodSignature", + "name": "onBlur", + "value": "() => void", + "description": "Callback when focus is removed.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: T) => void", + "description": "Callback when the buyer has **finished editing** a field. Unlike `onChange` callbacks you may be familiar with from Polaris or other React component libraries, this callback is **not** run on every change to the input. Text fields are “partially controlled” components, which means that while the buyer edits the field, its state is controlled by the component. Once the buyer has signalled that they have finished editing the field (typically, by blurring the field), `onChange` is called if the input actually changed from the most recent `value` property. At that point, you are expected to store this “committed value” in state, and reflect it in the text field’s `value` property.\n\nThis state management model is important given how UI Extensions are rendered. UI Extension components run on a separate thread from the UI, so they can’t respond to input synchronously. A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components) is to have the component be the source of truth for the input `value`, and update the `value` on every user input. The delay in responding to events from a UI extension is only a few milliseconds, but attempting to strictly store state with this delay can cause issues if a user types quickly, or if the buyer is using a lower-powered device. Having the UI thread take ownership for “in progress” input, and only synchronizing when the user is finished with a field, avoids this risk.\n\nIt can still sometimes be useful to be notified when the user makes any input in the field. If you need this capability, you can use the `onInput` prop. However, never use that property to create tightly controlled state for the `value`.\n\nThis callback is called with the current value of the field. If the value of a field is the same as the current `value` prop provided to the field, the `onChange` callback will not be run.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "MethodSignature", + "name": "onFocus", + "value": "() => void", + "description": "Callback when input is focused.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "MethodSignature", + "name": "onInput", + "value": "(value: T) => void", + "description": "Callback when the user makes any changes in the field. As noted in the documentation for `onChange`, you must not use this to update `state` — use the `onChange` callback for that purpose. Use the `onInput` prop when you need to do something as soon as the buyer makes a change, like clearing validation errors that apply to the field as soon as the user begins making the necessary adjustments.\n\nThis callback is called with the current value of the field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "prefix", + "value": "string", + "description": "Text content to render before the value.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "readonly", + "value": "boolean", + "description": "Whether the field is read-only.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "required", + "value": "boolean", + "description": "Whether the field needs a value. This requirement adds semantic value to the field, but it will not cause an error to appear automatically. If you want to present an error when this field is empty, you can do so with the `error` prop.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "suffix", + "value": "string", + "description": "Text content to render at the end of the text field.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "Type", + "description": "The content type a buyer will enter into the field. This type is used to provide semantic value to the field and, where possible, will provide the buyer with a better editing experience for the content type.\n\nNote that the type property does not change the way the text field’s value will be provided in `onChange` or `onInput`; a text field with a type of `'number'` will still provide the exact user entry, as a string, to those callbacks. The type also does not perform any form of automatic validation. If you want to perform validation, use the `error` property.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The current value for the field. If omitted, the field will be empty. You should update this value in response to the `onChange` callback.", + "isOptional": true + } + ], + "value": "export interface TextFieldProps {\n /**\n * A unique identifier for the field. When no `id` is set,\n * a globally unique value will be used instead.\n */\n id?: string;\n /**\n * An icon to render at the start or end of the field.\n * It will render at the start by default.\n */\n icon?: IconSource | {source: IconSource; position?: 'start' | 'end'};\n /**\n * An identifier for the field that is unique within the nearest\n * containing `Form` component.\n */\n name?: string;\n /**\n * Content to use as the field label. This value is also used as the placeholder\n * when the field is empty.\n */\n label: string;\n /**\n * Text content to render before the value.\n */\n prefix?: string;\n /**\n * Text content to render at the end of the text field.\n */\n suffix?: string;\n /**\n * Any content to render at the end of the text field. Commonly used\n * to display an icon that opens a tooltip providing more information about the field.\n */\n accessory?: string | RemoteFragment;\n /**\n * A detailed description for screen readers.\n */\n accessibilityDescription?: string;\n /**\n * The current value for the field. If omitted, the field will be empty. You should\n * update this value in response to the `onChange` callback.\n */\n value?: T;\n /**\n * In rare cases, like the PhoneField component, we completely control state.\n * In those cases, there is never a difference between the `value` prop of the field\n * and the current value in the field, and so this component never considers the\n * field to have changed. Use the `controlledValue` prop to provide the value that\n * should be shown to the buyer in those circumstances, but where the `value` prop\n * will continue to be used as the comparison value to determine whether the field\n * has changed. This value will usually be set to the last committed, unformatted value\n * for the controlled input.\n */\n controlledValue?: T;\n /**\n * The content type a buyer will enter into the field. This type is used to provide\n * semantic value to the field and, where possible, will provide the buyer with\n * a better editing experience for the content type.\n *\n * Note that the type property does not change the way the text field’s value will\n * be provided in `onChange` or `onInput`; a text field with a type of `'number'`\n * will still provide the exact user entry, as a string, to those callbacks. The\n * type also does not perform any form of automatic validation. If you want to\n * perform validation, use the `error` property.\n */\n type?: Type;\n /**\n * Whether the field needs a value. This requirement adds semantic value\n * to the field, but it will not cause an error to appear automatically.\n * If you want to present an error when this field is empty, you can do\n * so with the `error` prop.\n */\n required?: boolean;\n /**\n * Indicate an error to the user. The field will be given a specific stylistic treatment\n * to communicate problems that have to be resolved immediately.\n */\n error?: string;\n /**\n * Whether the field supports multiple lines of input.\n * Set a `number` to define the default lines of the input.\n */\n multiline?: boolean | number;\n /**\n * A hint as to the intended content of the field.\n *\n * When set to `true`, this property indicates that the field should support\n * autofill, but you do not have any more semantic information on the intended\n * contents.\n *\n * When set to `false`, you are indicating that this field contains sensitive\n * information, or contents that are never saved, like one-time codes.\n *\n * Alternatively, you can provide an `Autocomplete` object, which describes the\n * specific data you would like to be entered into this field during autofill.\n */\n autocomplete?: Autocomplete | boolean;\n /**\n * Whether the field can be modified.\n */\n disabled?: boolean;\n /**\n * Whether the field is read-only.\n */\n readonly?: boolean;\n /**\n * Specifies the maximum number of characters allowed.\n */\n maxLength?: number;\n /**\n * Callback when input is focused.\n */\n onFocus?(): void;\n /**\n * Callback when focus is removed.\n */\n onBlur?(): void;\n /**\n * Callback when the buyer has **finished editing** a field. Unlike `onChange`\n * callbacks you may be familiar with from Polaris or other React component libraries,\n * this callback is **not** run on every change to the input. Text fields are\n * “partially controlled” components, which means that while the buyer edits the\n * field, its state is controlled by the component. Once the buyer has signalled that\n * they have finished editing the field (typically, by blurring the field), `onChange`\n * is called if the input actually changed from the most recent `value` property. At\n * that point, you are expected to store this “committed value” in state, and reflect\n * it in the text field’s `value` property.\n *\n * This state management model is important given how UI Extensions are rendered. UI Extension components\n * run on a separate thread from the UI, so they can’t respond to input synchronously.\n * A pattern popularized by [controlled React components](https://reactjs.org/docs/forms.html#controlled-components)\n * is to have the component be the source of truth for the input `value`, and update\n * the `value` on every user input. The delay in responding to events from a UI\n * extension is only a few milliseconds, but attempting to strictly store state with\n * this delay can cause issues if a user types quickly, or if the buyer is using a\n * lower-powered device. Having the UI thread take ownership for “in progress” input,\n * and only synchronizing when the user is finished with a field, avoids this risk.\n *\n * It can still sometimes be useful to be notified when the user makes any input in\n * the field. If you need this capability, you can use the `onInput` prop. However,\n * never use that property to create tightly controlled state for the `value`.\n *\n * This callback is called with the current value of the field. If the value of a field\n * is the same as the current `value` prop provided to the field, the `onChange` callback\n * will not be run.\n */\n onChange?(value: T): void;\n /**\n * Callback when the user makes any changes in the field. As noted in the documentation\n * for `onChange`, you must not use this to update `state` — use the `onChange`\n * callback for that purpose. Use the `onInput` prop when you need to do something\n * as soon as the buyer makes a change, like clearing validation errors that apply to\n * the field as soon as the user begins making the necessary adjustments.\n *\n * This callback is called with the current value of the field.\n */\n onInput?(value: T): void;\n}" + }, + "Autocomplete": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "name": "Autocomplete", + "description": "A descriptor for selecting the data a field would like to receive during autocomplete. This attribute is modeled off of a limited set of the autocomplete values supported in browsers.", + "members": [ + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "field", + "value": "AutocompleteField", + "description": "The type of data that should be inserted into a field supporting autocomplete." + }, + { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "PropertySignature", + "name": "group", + "value": "AutocompleteGroup", + "description": "The contact information “group” the autocomplete data should be sourced from.", + "isOptional": true + } + ], + "value": "export interface Autocomplete {\n /**\n * The contact information “group” the autocomplete data should be sourced from.\n */\n group?: AutocompleteGroup;\n /**\n * The type of data that should be inserted into a field supporting autocomplete.\n */\n field: AutocompleteField;\n}" + }, + "AutocompleteField": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteField", + "value": "'name' | 'honorific-prefix' | 'given-name' | 'additional-name' | 'family-name' | 'honorific-suffix' | 'nickname' | 'username' | 'new-password' | 'current-password' | 'one-time-code' | 'organization-title' | 'organization' | 'street-address' | 'address-line1' | 'address-line2' | 'address-line3' | 'address-level4' | 'address-level3' | 'address-level2' | 'address-level1' | 'country' | 'country-name' | 'postal-code' | 'credit-card-name' | 'credit-card-given-name' | 'credit-card-additional-name' | 'credit-card-family-name' | 'credit-card-number' | 'credit-card-expiry' | 'credit-card-expiry-month' | 'credit-card-expiry-year' | 'credit-card-security-code' | 'credit-card-type' | 'transaction-currency' | 'transaction-amount' | 'language' | 'birthday' | 'birthday-day' | 'birthday-month' | 'birthday-year' | 'sex' | 'url' | 'photo' | 'telephone' | 'telephone-country-code' | 'telephone-national' | 'telephone-area-code' | 'telephone-local' | 'telephone-local-prefix' | 'telephone-local-suffix' | 'telephone-extension' | 'email' | 'instant-message' | 'home telephone' | 'home telephone-country-code' | 'home telephone-national' | 'home telephone-area-code' | 'home telephone-local' | 'home telephone-local-prefix' | 'home telephone-local-suffix' | 'home telephone-extension' | 'home email' | 'home instant-message' | 'work telephone' | 'work telephone-country-code' | 'work telephone-national' | 'work telephone-area-code' | 'work telephone-local' | 'work telephone-local-prefix' | 'work telephone-local-suffix' | 'work telephone-extension' | 'work email' | 'work instant-message' | 'mobile telephone' | 'mobile telephone-country-code' | 'mobile telephone-national' | 'mobile telephone-area-code' | 'mobile telephone-local' | 'mobile telephone-local-prefix' | 'mobile telephone-local-suffix' | 'mobile telephone-extension' | 'mobile email' | 'mobile instant-message' | 'fax telephone' | 'fax telephone-country-code' | 'fax telephone-national' | 'fax telephone-area-code' | 'fax telephone-local' | 'fax telephone-local-prefix' | 'fax telephone-local-suffix' | 'fax telephone-extension' | 'fax email' | 'fax instant-message' | 'pager telephone' | 'pager telephone-country-code' | 'pager telephone-national' | 'pager telephone-area-code' | 'pager telephone-local' | 'pager telephone-local-prefix' | 'pager telephone-local-suffix' | 'pager telephone-extension' | 'pager email' | 'pager instant-message'", + "description": "" + }, + "AutocompleteGroup": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AutocompleteGroup", + "value": "'shipping' | 'billing'", + "description": "" + }, + "IconSource": { + "filePath": "src/surfaces/checkout/components/Icon/Icon.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "IconSource", + "value": "'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowUpRight' | 'arrowDown' | 'bag' | 'bullet' | 'calendar' | 'camera' | 'caretDown' | 'cart' | 'cashDollar' | 'categories' | 'checkmark' | 'chevronLeft' | 'chevronRight' | 'chevronUp' | 'chevronDown' | 'clipboard' | 'clock' | 'close' | 'creditCard' | 'critical' | 'delete' | 'delivered' | 'delivery' | 'disabled' | 'discount' | 'email' | 'error' | 'errorFill' | 'external' | 'filter' | 'geolocation' | 'gift' | 'giftFill' | 'grid' | 'hamburger' | 'hollowCircle' | 'horizontalDots' | 'image' | 'info' | 'infoFill' | 'list' | 'lock' | 'magnify' | 'map' | 'marker' | 'minus' | 'mobile' | 'note' | 'orderBox' | 'pen' | 'plus' | 'profile' | 'question' | 'questionFill' | 'reorder' | 'reset' | 'return' | 'savings' | 'settings' | 'star' | 'starFill' | 'starHalf' | 'store' | 'success' | 'truck' | 'upload' | 'verticalDots' | 'warning' | 'warningFill'", + "description": "" + }, + "Type": { + "filePath": "src/surfaces/checkout/components/TextField/TextField.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Type", + "value": "'text' | 'email' | 'number' | 'telephone'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "textfield-default.png", + "codeblock": { + "title": "Basic TextField", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n TextField,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <TextField label=\"Last name\" />;\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, TextField} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const textfield = root.createComponent(TextField, {\n label: 'Last name',\n });\n\n root.appendChild(textfield);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "- Clearly label text fields so that it’s obvious what customers should enter.\n\n- Label text fields as Optional when input isn’t required. For example, use the label First name (optional).\n\n- Don’t have optional fields pass true to the required property." + } + ], + "related": [] + }, + { + "name": "ToggleButton", + "description": "Options inside a [ToggleButtonGroup](/docs/api/checkout-ui-extensions/components/forms/togglebuttongroup).", + "thumbnail": "togglebutton-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ToggleButtonProps", + "description": "", + "type": "ToggleButtonProps", + "typeDefinitions": { + "ToggleButtonProps": { + "filePath": "src/surfaces/checkout/components/ToggleButton/ToggleButton.ts", + "name": "ToggleButtonProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/ToggleButton/ToggleButton.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label used for buyers using assistive technologies. When set, any `children` supplied to this component will not be announced to screen reader users.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ToggleButton/ToggleButton.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Disables the button, disallowing any interaction.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ToggleButton/ToggleButton.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the toggle button." + }, + { + "filePath": "src/surfaces/checkout/components/ToggleButton/ToggleButton.ts", + "syntaxKind": "MethodSignature", + "name": "onPress", + "value": "() => void", + "description": "Callback when button is pressed.", + "isOptional": true + } + ], + "value": "export interface ToggleButtonProps {\n /**\n * A unique identifier for the toggle button.\n */\n id: string;\n /**\n * A label used for buyers using assistive technologies. When set, any\n * `children` supplied to this component will not be announced to screen reader users.\n */\n accessibilityLabel?: string;\n /**\n * Disables the button, disallowing any interaction.\n */\n disabled?: boolean;\n /**\n * Callback when button is pressed.\n */\n onPress?(): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "togglebutton-default.png", + "codeblock": { + "title": "Basic ToggleButton", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n ToggleButton,\n ToggleButtonGroup,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <ToggleButtonGroup\n value=\"none\"\n onChange={(value) => {\n console.log(\n `onChange event with value: ${value}`,\n );\n }}\n >\n <ToggleButton id=\"none\">None</ToggleButton>\n </ToggleButtonGroup>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n ToggleButtonGroup,\n ToggleButton,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const toggleButtonGroup = root.createComponent(\n ToggleButtonGroup,\n {\n value: 'none',\n onChange: (value) => {\n console.log(`onChange event with value: ${value}`);\n },\n },\n [root.createComponent(ToggleButton, {id: 'none'}, 'None')],\n );\n\n root.appendChild(toggleButtonGroup);\n});\n", + "language": "js" + } + ] + } + }, + "related": [ + { + "name": "ToggleButtonGroup", + "subtitle": "Component", + "url": "togglebuttongroup", + "type": "Component" + } + ] + }, + { + "name": "ToggleButtonGroup", + "description": "`ToggleButtonGroup` allows you to make a single choice out of the number of options provided. This is similar to the [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) component, but without controls such as checkbox or radio button.\n\nYou can utilize our layout components to arrange `ToggleButtonGroup`.", + "thumbnail": "togglebuttongroup-thumbnail.png", + "requires": "", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ToggleButtonGroupProps", + "description": "", + "type": "ToggleButtonGroupProps", + "typeDefinitions": { + "ToggleButtonGroupProps": { + "filePath": "src/surfaces/checkout/components/ToggleButtonGroup/ToggleButtonGroup.ts", + "name": "ToggleButtonGroupProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/ToggleButtonGroup/ToggleButtonGroup.ts", + "syntaxKind": "PropertySignature", + "name": "disabled", + "value": "boolean", + "description": "Whether the button group is disabled.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/ToggleButtonGroup/ToggleButtonGroup.ts", + "syntaxKind": "MethodSignature", + "name": "onChange", + "value": "(value: T) => void", + "description": "A callback that is run whenever one of the buttons is pressed. This callback is called with a string or array of strings indicating the ids of buttons that should now be selected. When this component is [controlled](https://reactjs.org/docs/forms.html#controlled-components), you must store this value in state and reflect it back in the `value` prop." + }, + { + "filePath": "src/surfaces/checkout/components/ToggleButtonGroup/ToggleButtonGroup.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "An id of the selected button." + } + ], + "value": "export interface ToggleButtonGroupProps {\n /**\n * An id of the selected button.\n */\n value: T;\n /**\n * Whether the button group is disabled.\n */\n disabled?: boolean;\n /**\n * A callback that is run whenever one of the buttons is pressed. This callback\n * is called with a string or array of strings indicating the ids of buttons\n * that should now be selected. When this component is\n * [controlled](https://reactjs.org/docs/forms.html#controlled-components),\n * you must store this value in state and reflect it back in the `value` prop.\n */\n onChange(value: T): void;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Forms", + "defaultExample": { + "image": "togglebuttongroup-default.png", + "codeblock": { + "title": "Basic ToggleButtonGroup", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n BlockStack,\n InlineLayout,\n Text,\n ToggleButton,\n ToggleButtonGroup,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <ToggleButtonGroup\n value=\"none\"\n onChange={(value) => {\n console.log(\n `onChange event with value: ${value}`,\n );\n }}\n >\n <InlineLayout spacing=\"base\">\n <ToggleButton id=\"none\">\n <View\n blockAlignment=\"center\"\n inlineAlignment=\"center\"\n minBlockSize=\"fill\"\n >\n None\n </View>\n </ToggleButton>\n <ToggleButton id=\"points-100\">\n <BlockStack\n inlineAlignment=\"center\"\n spacing=\"none\"\n >\n <Text>100</Text>\n <Text appearance=\"subdued\">\n points\n </Text>\n </BlockStack>\n </ToggleButton>\n <ToggleButton id=\"points-200\">\n <BlockStack\n inlineAlignment=\"center\"\n spacing=\"none\"\n >\n <Text>200</Text>\n <Text appearance=\"subdued\">\n points\n </Text>\n </BlockStack>\n </ToggleButton>\n <ToggleButton id=\"points-300\">\n <BlockStack\n inlineAlignment=\"center\"\n spacing=\"none\"\n >\n <Text>300</Text>\n <Text appearance=\"subdued\">\n points\n </Text>\n </BlockStack>\n </ToggleButton>\n </InlineLayout>\n </ToggleButtonGroup>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n ToggleButtonGroup,\n ToggleButton,\n InlineLayout,\n View,\n BlockStack,\n Text,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const toggleButtonGroup = root.createComponent(\n ToggleButtonGroup,\n {\n value: 'none',\n onChange: (value) => {\n console.log(`onChange event with value: ${value}`);\n },\n },\n [\n root.createComponent(InlineLayout, {spacing: 'base'}, [\n root.createComponent(\n ToggleButton,\n {id: 'none'},\n root.createComponent(\n View,\n {\n blockAlignment: 'center',\n inlineAlignment: 'center',\n minBlockSize: 'fill',\n },\n 'None',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'points-100'},\n root.createComponent(\n BlockStack,\n {inlineAlignment: 'center', spacing: 'none'},\n [\n root.createComponent(Text, undefined, '100'),\n root.createComponent(Text, {appearance: 'subdued'}, 'points'),\n ],\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'points-200'},\n root.createComponent(\n BlockStack,\n {inlineAlignment: 'center', spacing: 'none'},\n [\n root.createComponent(Text, undefined, '200'),\n root.createComponent(Text, {appearance: 'subdued'}, 'points'),\n ],\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'points-300'},\n root.createComponent(\n BlockStack,\n {inlineAlignment: 'center', spacing: 'none'},\n [\n root.createComponent(Text, undefined, '300'),\n root.createComponent(Text, {appearance: 'subdued'}, 'points'),\n ],\n ),\n ),\n ]),\n ],\n );\n\n root.appendChild(toggleButtonGroup);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "ToggleButtonGroup is a component designed for streamlined single-choice selection, without any additional details associated with the selection. If you need to allow multiple selections or present associated details, it is recommended to use [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) instead.", + "sectionSubContent": [ + { + "title": "Label and order", + "sectionContent": "Use descriptive and concise labels for each Toggle button, and maintain consistency in the terminology used across options. Arrange the Toggle buttons in a logical order that makes sense to users. Consider factors such as alphabetical order, chronological order, or order of importance, depending on the context." + }, + { + "title": "Number of Toggle buttons", + "sectionContent": "Avoid overwhelming users with too many Toggle buttons. Ideally, limit the number of choices to a manageable amount, typically between 2 and 7, to prevent decision fatigue and maintain clarity." + } + ] + } + ], + "examples": { + "description": "", + "examples": [ + { + "image": "togglebuttongroup-time-picking.png", + "description": "The ToggleButtonGroup component is ideal for a small set of options. It allows for easy scanning of available choices. Also the component’s big tap target makes it a good choice for enhanced mobile experience. However, in a grid layout, having more than 6 ToggleButtons can get overwhelming and take up too much vertical space. When there are more than 6 choices, consider using the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component instead. ", + "codeblock": { + "title": "Displaying a small set of time choices", + "tabs": [ + { + "code": "import {\n reactExtension,\n Grid,\n ToggleButton,\n ToggleButtonGroup,\n View,\n} from '@shopify/ui-extensions-react/checkout';\n\nexport default reactExtension(\n 'purchase.checkout.block.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <ToggleButtonGroup\n value=\"time-9am\"\n onChange={(value) => {\n console.log(\n `onChange event with value: ${value}`,\n );\n }}\n >\n <Grid\n columns={['auto', 'auto', 'auto']}\n spacing=\"base\"\n >\n <ToggleButton id=\"time-9am\">\n <View inlineAlignment=\"center\">\n 9:00 AM\n </View>\n </ToggleButton>\n <ToggleButton id=\"time-10am\">\n <View inlineAlignment=\"center\">\n 10:00 AM\n </View>\n </ToggleButton>\n <ToggleButton id=\"time-11am\">\n <View inlineAlignment=\"center\">\n 11:00 AM\n </View>\n </ToggleButton>\n <ToggleButton id=\"time-1pm\">\n <View inlineAlignment=\"center\">\n 1:00 PM\n </View>\n </ToggleButton>\n <ToggleButton id=\"time-2pm\">\n <View inlineAlignment=\"center\">\n 2:00 PM\n </View>\n </ToggleButton>\n <ToggleButton id=\"time-3pm\">\n <View inlineAlignment=\"center\">\n 3:00 PM\n </View>\n </ToggleButton>\n </Grid>\n </ToggleButtonGroup>\n );\n}\n", + "language": "jsx", + "title": "React" + }, + { + "code": "import {\n extension,\n Grid,\n ToggleButtonGroup,\n ToggleButton,\n View,\n} from '@shopify/ui-extensions/checkout';\n\nexport default extension(\n 'purchase.checkout.block.render',\n (root) => {\n const toggleButtonGroup =\n root.createComponent(\n ToggleButtonGroup,\n {\n value: 'time-9am',\n onChange: (value) => {\n console.log(\n `onChange event with value: ${value}`,\n );\n },\n },\n [\n root.createComponent(\n Grid,\n {\n columns: ['auto', 'auto', 'auto'],\n spacing: 'base',\n },\n [\n root.createComponent(\n ToggleButton,\n {id: 'time-9am'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '9:00 AM',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'time-10am'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '10:00 AM',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'time-11am'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '11:00 AM',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'time-1pm'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '1:00 PM',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'time-2pm'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '2:00 PM',\n ),\n ),\n root.createComponent(\n ToggleButton,\n {id: 'time-3pm'},\n root.createComponent(\n View,\n {inlineAlignment: 'center'},\n '3:00 PM',\n ),\n ),\n ],\n ),\n ],\n );\n\n root.appendChild(toggleButtonGroup);\n },\n);\n", + "language": "js", + "title": "JavaScript" + } + ] + } + } + ] + }, + "related": [ + { + "name": "ToggleButton", + "subtitle": "Component", + "url": "togglebutton", + "type": "Component" + } + ] + }, + { + "name": "Tooltip", + "description": "Tooltips are floating labels that briefly explain the function of a user interface element. They must be specified inside the `overlay` prop of an activator component. Currently, activator components are `Button`, `Link`, and `Pressable`.\n\nThe library automatically applies the [WAI-ARIA Tooltip Widget pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) to both the activator and the tooltip content. Expect screen readers to read the tooltip content when the user focuses the activator.", + "requires": "", + "thumbnail": "tooltip-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "TooltipProps", + "description": "", + "type": "TooltipProps", + "typeDefinitions": { + "TooltipProps": { + "filePath": "src/surfaces/checkout/components/Tooltip/Tooltip.ts", + "name": "TooltipProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/Tooltip/Tooltip.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + } + ], + "value": "export interface TooltipProps extends IdProps {}" + } + } + } + ], + "category": "UI components", + "subCategory": "Overlays", + "defaultExample": { + "image": "tooltip-default.png", + "codeblock": { + "title": "Basic Tooltip", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Icon,\n Pressable,\n Tooltip,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <Pressable\n overlay={\n <Tooltip>\n In case we need to contact you about\n your order\n </Tooltip>\n }\n >\n <Icon source=\"questionFill\" />\n </Pressable>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {\n extension,\n Icon,\n Pressable,\n Tooltip,\n} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const tooltipFragment = root.createFragment();\n const tooltip = root.createComponent(\n Tooltip,\n {},\n 'In case we need to contact you about your order',\n );\n tooltipFragment.appendChild(tooltip);\n const pressable = root.createComponent(\n Pressable,\n {overlay: tooltipFragment},\n [root.createComponent(Icon, {source: 'questionFill'})],\n );\n\n root.appendChild(pressable);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "best-practices", + "title": "Best Practices", + "sectionContent": "Use tooltips if:\n\n- It’s used for showing information only.\n\n- The information contained in it is not needed by someone to complete their checkout.\n\n- The information can be written in a sentence." + } + ], + "related": [] + }, + { + "name": "View", + "description": "View is a generic container component. Its contents will always be their “natural” size, so this component can be useful in layout components (like `Grid`, `BlockStack`, `InlineStack`) that would otherwise stretch their children to fit.", + "requires": "", + "thumbnail": "view-thumbnail.png", + "isVisualComponent": true, + "type": "", + "definitions": [ + { + "title": "ViewProps", + "description": "", + "type": "ViewProps", + "typeDefinitions": { + "ViewProps": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "ViewProps", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityLabel", + "value": "string", + "description": "A label that describes the purpose or contents of the element. When set, it will be announced to buyers using assistive technologies and will provide them with more context.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityRole", + "value": "ViewLikeAccessibilityRole", + "description": "Sets the semantic meaning of the component’s content. When set, the role will be used by assistive technologies to help buyers navigate the page.\n\n\nFor example:\n\n- In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n\n- In an HTML host a `listItem` string will render: `
  • `", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "accessibilityVisibility", + "value": "AccessibilityVisibility", + "description": "Changes the visibility of the element to assistive technologies.\n\n`hidden` hides the component from assistive technology (for example, a screen reader) but remains visually visible.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "background", + "value": "MaybeConditionalStyle", + "description": "Adjust the background.", + "isOptional": true, + "defaultValue": "'transparent'" + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockAlignment", + "value": "MaybeResponsiveConditionalStyle<\n Extract\n >", + "description": "Position children along the cross axis", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "border", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the border style.\n\nTo shorten the code, it is possible to specify all the border style properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`\n\n- `['base', 'none']` means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`\n\n- `['base', 'none', 'dotted', 'base']` means blockStart border style is `base`, inlineEnd border style is `none`, blockEnd border style is `dotted` and blockStart border style is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "borderRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "", + "isOptional": true, + "isPrivate": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "borderWidth", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the border width.\n\nTo shorten the code, it is possible to specify all the border width properties in one property.\n\nFor example:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`\n\n- `['base', 'medium']` means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `medium`\n\n- `['base', 'medium', 'medium', 'base']` means blockStart border width is `base`, inlineEnd border width is `medium`, blockEnd border width is `medium` and blockStart border width is `base`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "cornerRadius", + "value": "MaybeResponsiveConditionalStyle<\n MaybeShorthandProperty\n >", + "description": "Adjust the corner radius.\n\nProvide a single value to apply the same corner radius to all four corners, two values to apply different corner radii to opposing corners, or four values to apply different corner radii to each individual corner.\n\nFor example:\n\n- `base` means all 4 corner radii are `base`\n\n- `['base', 'none']` means the StartStart and EndEnd corner radii are `base`, StartEnd and EndStart corner radii are `none`. When the context’s language direction is left to right, StartStart and EndEnd corners are the top left and bottom right corners\n while StartEnd and EndStart corners are the top right and bottom left corners.\n\n- `['base', 'none', 'small', 'base']` means StartStart corner radius is `base`, StartEnd corner radius is `none`, EndEnd corner radius is `small` and EndStart corner radius is `base`\n\nA `borderRadius` alias is available for this property. When both are specified, `cornerRadius` takes precedence.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "display", + "value": "MaybeResponsiveConditionalStyle", + "description": "Changes the display of the component.\n\n\n`inline` the component starts on the same line as preceding inline content and allows subsequent content to continue on the same line.\n\n`block` the component starts on its own new line and fills its parent.\n\n`auto` resets the component to its initial value. The actual value depends on the component and context.\n\n`none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.", + "isOptional": true, + "defaultValue": "'auto'" + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "id", + "value": "string", + "description": "A unique identifier for the component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineAlignment", + "value": "MaybeResponsiveConditionalStyle", + "description": "Position children along the main axis", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineSize", + "value": "MaybeResponsiveConditionalStyle<'fill'>", + "description": "Adjust the inline size.\n\n`fill`: takes all the available space.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "maxBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "maxInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the maximum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of maxInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/max-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "minBlockSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the block size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\n\nSee [MDN explanation of minBlockSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-block-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "minInlineSize", + "value": "MaybeResponsiveConditionalStyle<\n number | `${number}%` | 'fill'\n >", + "description": "Adjust the minimum inline size.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages.\n\n`fill`: takes all the available space.\\\n\nSee [MDN explanation of minInlineSize](https://developer.mozilla.org/en-US/docs/Web/CSS/min-inline-size).", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "opacity", + "value": "Opacity", + "description": "Sets the opacity of the View. The opacity will be applied to the background as well as all the children of the View. Use carefully as this could decrease the contrast ratio between the background and foreground elements, resulting in unreadable and inaccessible text.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "overflow", + "value": "'hidden' | 'visible'", + "description": "Sets the overflow behavior of the element.\n\n`hidden`: clips the content when it is larger than the element’s container. The element will not be scrollable and the users will not be able to access the clipped content by dragging or using a scroll wheel.\n\n`visible`: the content that extends beyond the element’s container is visible.", + "isOptional": true, + "defaultValue": "'visible'" + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "padding", + "value": "MaybeResponsiveConditionalStyle>", + "description": "Adjust the padding.\n\nTo shorten the code, it is possible to specify all the padding properties in one property.\n\n\nExamples:\n\n- `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`\n\n- [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`\n\n- [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and blockStart padding is `tight`", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "position", + "value": "MaybeResponsiveConditionalStyle", + "description": "Changes how the `View` is positioned. When setting `position`, set each axis only once.\n\n``` // Allowed; sets the `block` and `inline` axes once each ```\n\n``` // Allowed; sets the `inline` and `block` axes once each ```\n\n``` // Not allowed; sets the `block` axis twice ```\n\n``` // Not allowed; sets the `inline` axis twice ```", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "translate", + "value": "MaybeResponsiveConditionalStyle", + "description": "Specifies a two-dimensional translation of the View.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "visibility", + "value": "Visibility", + "description": "Changes the visibility of the element.\n\n`hidden` visually hides the component while keeping it accessible to assistive technology, such as screen readers. Hidden elements don't take any visual space contrary to CSS visibility: hidden;", + "isOptional": true + } + ], + "value": "export interface ViewProps\n extends Pick,\n BorderProps,\n CornerProps,\n IdProps,\n SizingProps,\n SpacingProps,\n VisibilityProps {\n /**\n * Changes the display of the component.\n *\n *\n * `inline` the component starts on the same line as preceding inline content and allows subsequent content to continue on the same line.\n *\n * `block` the component starts on its own new line and fills its parent.\n *\n * `auto` resets the component to its initial value. The actual value depends on the component and context.\n *\n * `none` hides the component and removes it from the accessibility tree, making it invisible to screen readers.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/display\n *\n * @defaultValue 'auto'\n */\n display?: MaybeResponsiveConditionalStyle;\n /**\n * Sets the opacity of the View. The opacity will be applied to the background as well as all\n * the children of the View. Use carefully as this could decrease the contrast ratio between\n * the background and foreground elements, resulting in unreadable and inaccessible text.\n */\n opacity?: Opacity;\n /**\n * A label that describes the purpose or contents of the element. When set,\n * it will be announced to buyers using assistive technologies and will\n * provide them with more context.\n */\n accessibilityLabel?: string;\n /**\n * Sets the semantic meaning of the component’s content. When set,\n * the role will be used by assistive technologies to help buyers\n * navigate the page.\n *\n *\n * For example:\n *\n * - In an HTML host a `['listItem', 'separator']` tuple will render: `
  • `\n *\n * - In an HTML host a `listItem` string will render: `
  • `\n */\n accessibilityRole?: ViewLikeAccessibilityRole;\n /**\n * Changes how the `View` is positioned. When setting `position`, set each axis only once.\n *\n * ```\n * // Allowed; sets the `block` and `inline` axes once each\n * ```\n *\n * ```\n * // Allowed; sets the `inline` and `block` axes once each\n * ```\n *\n * ```\n * // Not allowed; sets the `block` axis twice\n * ```\n *\n * ```\n * // Not allowed; sets the `inline` axis twice\n * ```\n */\n position?: MaybeResponsiveConditionalStyle;\n /**\n * Specifies a two-dimensional translation of the View.\n */\n translate?: MaybeResponsiveConditionalStyle;\n /**\n * Position children along the cross axis\n */\n blockAlignment?: MaybeResponsiveConditionalStyle<\n Extract\n >;\n /**\n * Position children along the main axis\n */\n inlineAlignment?: MaybeResponsiveConditionalStyle;\n /**\n * Adjust the inline size.\n *\n * `fill`: takes all the available space.\n */\n inlineSize?: MaybeResponsiveConditionalStyle<'fill'>;\n /**\n * Sets the overflow behavior of the element.\n *\n * `hidden`: clips the content when it is larger than the element’s container.\n * The element will not be scrollable and the users will not be able\n * to access the clipped content by dragging or using a scroll wheel.\n *\n * `visible`: the content that extends beyond the element’s container is visible.\n *\n * @default 'visible'\n */\n overflow?: 'hidden' | 'visible';\n}" + }, + "ViewLikeAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewLikeAccessibilityRole", + "value": "NonPresentationalAccessibilityRole | [NonPresentationalAccessibilityRole, NonPresentationalAccessibilityRole]", + "description": "" + }, + "NonPresentationalAccessibilityRole": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "NonPresentationalAccessibilityRole", + "value": "'main' | 'header' | 'footer' | 'section' | 'complementary' | 'navigation' | 'orderedList' | 'listItem' | 'unorderedList' | 'separator' | 'status' | 'alert'", + "description": "" + }, + "AccessibilityVisibility": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "AccessibilityVisibility", + "value": "'hidden'", + "description": "" + }, + "MaybeConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "ConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface ConditionalStyle<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: ConditionalValue[];\n}" + }, + "ConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface ConditionalValue<\n T,\n AcceptedConditions extends BaseConditions = Conditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "Background": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Background", + "value": "'transparent' | 'base' | 'subdued'", + "description": "" + }, + "MaybeResponsiveConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeResponsiveConditionalStyle", + "value": "T | ConditionalStyle", + "description": "A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles.\n\nTo learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation." + }, + "ViewportSizeCondition": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "ViewportSizeCondition", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: T; }", + "description": "" + } + ], + "value": "export interface ViewportSizeCondition {\n viewportInlineSize: {min: T};\n}" + }, + "BlockAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BlockAlignment", + "value": "Alignment | 'baseline'", + "description": "" + }, + "Alignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Alignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "MaybeShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "MaybeShorthandProperty", + "value": "T | ShorthandProperty", + "description": "" + }, + "ShorthandProperty": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ShorthandProperty", + "value": "[T, T] | [T, T, T, T]", + "description": "" + }, + "BorderStyle": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderStyle", + "value": "'base' | 'dashed' | 'dotted' | 'none'", + "description": "" + }, + "CornerRadius": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadius", + "value": "'base' | 'small' | 'large' | 'fullyRounded' | 'none' | CornerRadiusDeprecated", + "description": "" + }, + "CornerRadiusDeprecated": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "CornerRadiusDeprecated", + "value": "'tight' | 'loose'", + "description": "" + }, + "BorderWidth": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "BorderWidth", + "value": "'base' | 'medium' | 'thick'", + "description": "" + }, + "Display": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Display", + "value": "'none' | 'auto' | 'inline' | 'block'", + "description": "" + }, + "InlineAlignment": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "InlineAlignment", + "value": "'start' | 'center' | 'end'", + "description": "" + }, + "Opacity": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Opacity", + "value": "10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90", + "description": "" + }, + "Spacing": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Spacing", + "value": "'none' | 'extraTight' | 'tight' | 'base' | 'loose' | 'extraLoose'", + "description": "" + }, + "Position": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Position", + "value": "PositionBlockStartInlineStart | PositionBlockStartInlineEnd | PositionBlockEndInlineStart | PositionBlockEndInlineEnd", + "description": "" + }, + "PositionBlockStartInlineStart": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "PositionBlockStartInlineStart", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockEnd", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockStart", + "value": "Coordinate", + "description": "Adjust the block start offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineEnd", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineStart", + "value": "Coordinate", + "description": "Adjust the inline start offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "PositionType", + "description": "Changes how the `View` is positioned.", + "isOptional": true, + "defaultValue": "'relative'" + } + ], + "value": "interface PositionBlockStartInlineStart\n extends PositionBlockStart,\n PositionInlineStart,\n PositionTypeProperty {\n blockEnd?: undefined;\n inlineEnd?: undefined;\n}" + }, + "Coordinate": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Coordinate", + "value": "number | `${number}%`", + "description": "" + }, + "PositionType": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "PositionType", + "value": "'absolute' | 'relative' | 'sticky'", + "description": "" + }, + "PositionBlockStartInlineEnd": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "PositionBlockStartInlineEnd", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockEnd", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockStart", + "value": "Coordinate", + "description": "Adjust the block start offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineEnd", + "value": "Coordinate", + "description": "Adjust the inline end offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineStart", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "PositionType", + "description": "Changes how the `View` is positioned.", + "isOptional": true, + "defaultValue": "'relative'" + } + ], + "value": "interface PositionBlockStartInlineEnd\n extends PositionBlockStart,\n PositionInlineEnd,\n PositionTypeProperty {\n blockEnd?: undefined;\n inlineStart?: undefined;\n}" + }, + "PositionBlockEndInlineStart": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "PositionBlockEndInlineStart", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockEnd", + "value": "Coordinate", + "description": "Adjust the block end offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockStart", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineEnd", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineStart", + "value": "Coordinate", + "description": "Adjust the inline start offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "PositionType", + "description": "Changes how the `View` is positioned.", + "isOptional": true, + "defaultValue": "'relative'" + } + ], + "value": "interface PositionBlockEndInlineStart\n extends PositionBlockEnd,\n PositionInlineStart,\n PositionTypeProperty {\n blockStart?: undefined;\n inlineEnd?: undefined;\n}" + }, + "PositionBlockEndInlineEnd": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "PositionBlockEndInlineEnd", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockEnd", + "value": "Coordinate", + "description": "Adjust the block end offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "blockStart", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineEnd", + "value": "Coordinate", + "description": "Adjust the inline end offset.\n\n`number`: size in pixels.\n\n`` `${number}%` ``: size in percentages. It refers to the block size of the parent component.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inlineStart", + "value": "undefined", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "type", + "value": "PositionType", + "description": "Changes how the `View` is positioned.", + "isOptional": true, + "defaultValue": "'relative'" + } + ], + "value": "interface PositionBlockEndInlineEnd\n extends PositionBlockEnd,\n PositionInlineEnd,\n PositionTypeProperty {\n blockStart?: undefined;\n inlineStart?: undefined;\n}" + }, + "Translate": { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "name": "Translate", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "block", + "value": "number | `${number}%`", + "description": "Adjust the translation on the cross axis.\n\nA percentage value refers to the block size of the View.", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/components/View/View.ts", + "syntaxKind": "PropertySignature", + "name": "inline", + "value": "number | `${number}%`", + "description": "Adjust the translation on the main axis.\n\nA percentage value refers to the inline size of the View.", + "isOptional": true + } + ], + "value": "export interface Translate {\n /**\n * Adjust the translation on the cross axis.\n *\n * A percentage value refers to the block size of the View.\n */\n block?: number | `${number}%`;\n /**\n * Adjust the translation on the main axis.\n *\n * A percentage value refers to the inline size of the View.\n */\n inline?: number | `${number}%`;\n}" + }, + "Visibility": { + "filePath": "src/surfaces/checkout/components/shared.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "Visibility", + "value": "'hidden'", + "description": "" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "image": "view-default.png", + "codeblock": { + "title": "Basic View", + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension(\n 'customer-account.page.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return (\n <View padding=\"base\" border=\"base\">\n View\n </View>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {extension, View} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const view = root.createComponent(\n View,\n {border: 'base', padding: 'base'},\n 'View',\n );\n\n root.appendChild(view);\n});\n", + "language": "js" + } + ] + } + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "accessibility-roles", + "title": "Accessibility roles", + "sectionContent": "| Value | Description |\n| --- | --- |\n| \"main\" | Used to indicate the primary content. |\n| \"header\" | Used to indicate the component is a header. |\n| \"footer\" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| \"section\" | Used to indicate a generic section. |\n| \"complementary\" | Used to designate a supporting section that relates to the main content. |\n| \"navigation\" | Used to identify major groups of links used for navigating. |\n| \"orderedList\" | Used to identify a list of ordered items. |\n| \"listItem\" | Used to identify an item inside a list of items. |\n| \"unorderedList\" | Used to identify a list of unordered items. |\n| \"separator\" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| \"status\" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| \"alert\" | Used for important, and usually time-sensitive, information. |" + } + ], + "related": [ + { + "subtitle": "Utility", + "name": "StyleHelper", + "url": "/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper", + "type": "utility" + } + ] + }, + { + "name": "StyleHelper", + "description": "This is a helper for authoring conditional values for property styles.\n\nWrite complex conditional styles based on one or more conditions, such as viewport sizes and interactive states, in a concise and expressive way.", + "requires": "", + "isVisualComponent": false, + "type": "", + "definitions": [ + { + "title": "StyleHelper", + "description": "", + "type": "DocsStyle", + "typeDefinitions": { + "DocsStyle": { + "filePath": "src/surfaces/checkout/style/style.ts", + "name": "DocsStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/style.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "(defaultValue: T) => StylesConditionalStyle", + "description": "Sets an optional default value to use when no other condition is met." + }, + { + "filePath": "src/surfaces/checkout/style/style.ts", + "syntaxKind": "PropertySignature", + "name": "when", + "value": "(conditions: StylesConditions, value: T) => StylesConditionalStyle", + "description": "Adjusts the style based on different conditions. All conditions, expressed as a literal object, must be met for the associated value to be applied.\n\nThe `when` method can be chained together to build more complex styles." + } + ], + "value": "export interface DocsStyle {\n /**\n * Sets an optional default value to use when no other condition is met.\n *\n * @param defaultValue The default value\n * @returns The chainable condition style\n */\n default: (defaultValue: T) => StylesConditionalStyle;\n /**\n * Adjusts the style based on different conditions. All conditions, expressed\n * as a literal object, must be met for the associated value to be applied.\n *\n * The `when` method can be chained together to build more complex styles.\n *\n * @param conditions The condition(s)\n * @param value The conditional value that can be applied if the conditions are met\n * @returns The chainable condition style\n */\n when: (\n conditions: StylesConditions,\n value: T,\n ) => StylesConditionalStyle;\n}" + }, + "StylesConditionalStyle": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditionalStyle", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditionals", + "value": "StylesConditionalValue[]", + "description": "An array of conditional values." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "default", + "value": "T", + "description": "The default value applied when none of the conditional values specified in `conditionals` are met.", + "isOptional": true + } + ], + "value": "export interface StylesConditionalStyle<\n T,\n AcceptedConditions extends StylesBaseConditions = StylesBaseConditions,\n> {\n /**\n * The default value applied when none of the conditional values\n * specified in `conditionals` are met.\n */\n default?: T;\n /**\n * An array of conditional values.\n */\n conditionals: StylesConditionalValue[];\n}" + }, + "StylesConditionalValue": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditionalValue", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "conditions", + "value": "AcceptedConditions", + "description": "The conditions that must be met for the value to be applied. At least one condition must be specified." + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "value", + "value": "T", + "description": "The value that will be applied if the conditions are met." + } + ], + "value": "export interface StylesConditionalValue<\n T,\n AcceptedConditions extends StylesBaseConditions = StylesBaseConditions,\n> {\n /**\n * The conditions that must be met for the value to be applied. At least one\n * condition must be specified.\n */\n conditions: AcceptedConditions;\n /**\n * The value that will be applied if the conditions are met.\n */\n value: T;\n}" + }, + "StylesBaseConditions": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesBaseConditions", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "focus", + "value": "true", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "hover", + "value": "true", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "resolution", + "value": "1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: ViewportInlineSize; }", + "description": "", + "isOptional": true + } + ], + "value": "export interface StylesBaseConditions {\n viewportInlineSize?: {min: ViewportInlineSize};\n hover?: true;\n focus?: true;\n resolution?: 1 | 1.3 | 1.5 | 2 | 2.6 | 3 | 3.5 | 4;\n}" + }, + "ViewportInlineSize": { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "TypeAliasDeclaration", + "name": "ViewportInlineSize", + "value": "'extraSmall' | 'small' | 'medium' | 'large'", + "description": "" + }, + "StylesConditions": { + "filePath": "src/surfaces/checkout/style/types.ts", + "name": "StylesConditions", + "description": "", + "members": [ + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "focus", + "value": "true", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "hover", + "value": "true", + "description": "", + "isOptional": true + }, + { + "filePath": "src/surfaces/checkout/style/types.ts", + "syntaxKind": "PropertySignature", + "name": "viewportInlineSize", + "value": "{ min: ViewportInlineSize; }", + "description": "", + "isOptional": true + } + ], + "value": "export interface StylesConditions {\n viewportInlineSize?: {min: ViewportInlineSize};\n hover?: true;\n focus?: true;\n}" + } + } + } + ], + "category": "UI components", + "subCategory": "Layout and structure", + "defaultExample": { + "codeblock": { + "tabs": [ + { + "title": "React", + "code": "import {\n reactExtension,\n Style,\n View,\n} from '@shopify/ui-extensions-react/customer-account';\n\nexport default reactExtension('customer-account.page.render', () => (\n <Extension />\n));\n\nfunction Extension() {\n return (\n <View\n maxInlineSize={Style.default(200)\n .when({viewportInlineSize: {min: 'small'}}, 300)\n .when({viewportInlineSize: {min: 'medium'}}, 400)\n .when({viewportInlineSize: {min: 'large'}}, 800)}\n >\n Responsive Content\n </View>\n );\n}\n", + "language": "tsx" + }, + { + "title": "JS", + "code": "import {Style, View, extension} from '@shopify/ui-extensions/customer-account';\n\nexport default extension('customer-account.page.render', (root) => {\n const view = root.createComponent(\n View,\n {\n border: 'base',\n padding: 'base',\n maxInlineSize: Style.default(200)\n .when({viewportInlineSize: {min: 'small'}}, 300)\n .when({viewportInlineSize: {min: 'medium'}}, 400)\n .when({viewportInlineSize: {min: 'large'}}, 800),\n },\n 'Responsive Content',\n );\n\n root.appendChild(view);\n});\n", + "language": "js" + } + ], + "title": "Import the Style helper" + } + }, + "examples": { + "description": "This section provides examples of conditions.", + "examples": [ + { + "description": "Default styling can be combined with specific conditions. In this example, the Grid's children will be stacked by default and side by side on viewports above the small breakpoint.", + "codeblock": { + "title": "Default Style With Conditions", + "tabs": [ + { + "title": "React", + "code": "<Grid\n columns={Style.default('fill').when({viewportInlineSize: {min: 'small'}}, [\n '30%',\n '70%',\n ])}\n>\n <View>Content</View>\n <View>Content</View>\n</Grid>\n", + "language": "tsx" + } + ] + } + }, + { + "description": "Using simple conditional styling enables you to specify a styling change when a condition is met. In this example, the View's padding will be loose on hover.", + "codeblock": { + "title": "Simple Condition", + "tabs": [ + { + "title": "React", + "code": "<Pressable\n onPress={() => alert('press')}\n border={Style.default(['base', 'dotted']).when(\n {viewportInlineSize: {min: 'small'}},\n ['base', 'dotted', 'none', 'base'],\n )}\n>\n Content\n</Pressable>\n", + "language": "tsx" + } + ] + } + }, + { + "description": "Using the `display` property with conditional styles enables you to hide content for certain viewport sizes. In this example, the View will be hidden on small and above screen sizes.", + "codeblock": { + "title": "Conditionally hiding content", + "tabs": [ + { + "title": "React", + "code": "<View\n display={Style.default('auto').when(\n {viewportInlineSize: {min: 'small'}},\n 'none',\n )}\n>\n Content\n</View>\n", + "language": "tsx" + } + ] + } + } + ] + }, + "subSections": [ + { + "type": "Generic", + "anchorLink": "conditions", + "title": "Conditions", + "sectionContent": "The following conditions are supported for conditional styles.\n\nMultiple conditions can be set on the same `when` method.\n\n \n\n| Name | Type | Description |\n| --- | --- | --- |\n| \"hover\" | true | This condition is met when an element is hovered on with the cursor (mouse pointer). |\n| \"focus\" | true | This condition is met when an element is clicked, tapped on or selected using the Tab key.|\n| viewportInlineSize | {min: \"small\" | \"medium\" | \"large\"} | This condition is met when the device matches the minimum width.|" + } + ], + "related": [ + { + "name": "BlockLayout", + "subtitle": "Component", + "url": "blocklayout", + "type": "Component" + }, + { + "name": "BlockSpacer", + "subtitle": "Component", + "url": "blockspacer", + "type": "Component" + }, + { + "name": "BlockStack", + "subtitle": "Component", + "url": "blockstack", + "type": "Component" + }, + { + "name": "Grid", + "subtitle": "Component", + "url": "grid", + "type": "Component" + }, + { + "name": "GridItem", + "subtitle": "Component", + "url": "griditem", + "type": "Component" + }, + { + "name": "Image", + "subtitle": "Component", + "url": "image", + "type": "Component" + }, + { + "name": "InlineLayout", + "subtitle": "Component", + "url": "inlinelayout", + "type": "Component" + }, + { + "name": "InlineSpacer", + "subtitle": "Component", + "url": "inlinespacer", + "type": "Component" + }, + { + "name": "InlineStack", + "subtitle": "Component", + "url": "inlinestack", + "type": "Component" + }, + { + "name": "List", + "subtitle": "Component", + "url": "list", + "type": "Component" + }, + { + "name": "Pressable", + "subtitle": "Component", + "url": "pressable", + "type": "Component" + }, + { + "name": "ScrollView", + "subtitle": "Component", + "url": "scrollview", + "type": "Component" + }, + { + "name": "SkeletonImage", + "subtitle": "Component", + "url": "skeletonimage", + "type": "Component" + }, + { + "name": "View", + "subtitle": "Component", + "url": "view", + "type": "Component" + } + ] } ] \ No newline at end of file diff --git a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_category_pages.json b/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_category_pages.json deleted file mode 100644 index 7617e84762..0000000000 --- a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_category_pages.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "category": "components", - "sections": [ - { - "type": "Generic", - "anchorLink": "additional-components", - "title": "Additional components", - "sectionContent": "In addition to the components below, you can also use checkout components to build customer account UI extensions.", - "sectionCard": [ - { - "type": "blocks", - "name": "Checkout components", - "subtitle": "More components", - "url": "/docs/api/checkout-ui-extensions/components" - } - ] - } - ] - } -] \ No newline at end of file diff --git a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_static_pages.json b/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_static_pages.json deleted file mode 100644 index 2bc152da26..0000000000 --- a/packages/ui-extensions/docs/surfaces/customer-account/generated/generated_static_pages.json +++ /dev/null @@ -1,848 +0,0 @@ -[ - { - "title": "Configuration", - "description": "\nWhen you create a [customer account UI extension](/api/customer-account-ui-extensions/), an [app extension configuration](/docs/apps/app-extensions/configuration) `shopify.extension.toml` file is automatically generated in your extension's directory.\n\nThis guide describes [extension targeting](#targets), [capabilities](#capabilities), [metafields](#metafields), and the [settings](#settings-definition) you can configure in the app extension configuration.\n", - "id": "configuration", - "sections": [ - { - "type": "Generic", - "anchorLink": "how-it-works", - "title": "How it works", - "sectionContent": "\nYou define properties for your customer account UI extension in the extension configuration file. The `shopify.extension.toml` file contains the extension's configuration, which includes the extension name, targets, capabilities, and settings.\n\nWhen an extension is published to Shopify, the contents of the settings file are pushed alongside the extension.\n", - "codeblock": { - "title": "shopify.extension.toml", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "api_version = \"unstable\"\n\n[[extensions]]\ntype = \"ui_extension\"\nname = \"My customer account extension\"\nhandle = \"customer-account-ui\"\n\n[[extensions.targeting]]\ntarget = \"customer-account.order-status.block.render\"\nmodule = \"./OrderStatusBlockExtension.jsx\"\n\n[extensions.capabilities]\nnetwork_access = true\napi_access = true\n\n[[extensions.metafields]]\nnamespace = \"my-namespace\"\nkey = \"my-key\"\n[[extensions.metafields]]\nnamespace = \"my-namespace\"\nkey = \"my-other-key\"\n\n[extensions.settings]\n[[extensions.settings.fields]]\nkey = \"field_key\"\ntype = \"boolean\"\nname = \"field-name\"\n[[extensions.settings.fields]]\nkey = \"field_key_2\"\ntype = \"number_integer\"\nname = \"field-name-2\"\n", - "language": "toml" - } - ] - }, - "sectionNotice": [ - { - "title": "Tip", - "sectionContent": "\nYou can configure more than one type of extension within a configuration file.\n", - "type": "info" - } - ], - "sectionCard": [ - { - "name": "App extension configuration", - "subtitle": "Learn more", - "url": "/docs/apps/app-extensions/configuration", - "type": "gear" - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "targets", - "title": "Targets", - "sectionContent": "\n[Targets](/docs/api/customer-account-ui-extensions/extension-targets-overview) represent where your customer account UI extension will be injected. You may have one or many targets defined in your app extension configuration using the `targeting` field.\n\nAlong with the `target`, Shopify needs to know which code to execute for it. You specify the path to your code file by using the `module` property.\n\nFor block extension targets, you can [define the default placement](/docs/apps/build/customer-accounts/extension-placement#define-default-placement) for your extension.\n\n ", - "accordionContent": [ - { - "title": "Supporting a single extension target", - "description": "\n Your code should have a default export if it only supports a single extension target.\n ", - "codeblock": { - "title": "Single extension target", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[[extensions.targeting]]\ntarget = \"customer-account.order-status.block.render\"\nmodule = \"./Extension.jsx\"\n\n# ...\n", - "language": "toml" - }, - { - "title": "Extension.jsx", - "code": "// ...\n\nexport default reactExtension(\n 'customer-account.order-status.block.render',\n <Extension />,\n);\n\nfunction Extension() {\n // ...\n}\n", - "language": "jsx" - } - ] - } - }, - { - "title": "Supporting multiple extension targets", - "description": "\n You can support multiple extension targets within a single configuration file. However, you must provide a separate file per extension target using the `export default` declaration.\n ", - "codeblock": { - "title": "Multiple extension targets", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[[extensions.targeting]]\ntarget = \"customer-account.page.render\"\nmodule = \"./FullPageExtension.jsx\"\n\n[[extensions.targeting]]\ntarget = \"customer-account.order-status.block.render\"\nmodule = \"./BlockExtension.jsx\"\n\n# ...\n", - "language": "toml" - }, - { - "title": "FullPageExtension.jsx", - "code": "// ...\n\n// ./FullPageExtension.jsx\nexport default reactExtension(\n 'customer-account.page.render',\n <FullPageExtension />,\n);\n\nfunction FullPageExtension() {\n // ...\n}\n", - "language": "jsx" - }, - { - "title": "BlockExtension.jsx", - "code": "// ...\n\n// ./BlockExtension.jsx\nexport default reactExtension(\n 'customer-account.order-status.block.render',\n <BlockExtension />,\n);\n\nfunction BlockExtension() {\n // ...\n}\n", - "language": "jsx" - } - ] - } - } - ] - }, - { - "type": "Generic", - "anchorLink": "capabilities", - "title": "Capabilities", - "sectionContent": "\nDefines the [capabilities](/docs/api/customer-account-ui-extensions/apis/extension#standardapi-propertydetail-extension) associated with your extension.\n| Property | Description |\n|---|---|\n| [`api_access`](#api-access) | Allows your extension to query the Storefront API.\n| [`network_access`](#network-access) | Allows your extension make external network calls.\n| [`collect_buyer_consent`](#collect-buyer-consent) | Allows your extension to collect buyer consent for specific policies such as SMS marketing.\n ", - "codeblock": { - "title": "Capabilities", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[extensions.capabilities]\napi_access = true\nnetwork_access = true\n\n[extensions.capabilities.collect_buyer_consent]\ncustomer_privacy = true\n\n# ...\n\n", - "language": "toml" - } - ] - } - }, - { - "type": "Generic", - "anchorLink": "api-access", - "title": "Storefront API access", - "sectionContent": "The following section describes the use cases of the `api_access` capability and the [Storefront API](/api/storefront) access scopes.", - "codeblock": { - "title": "Enable Storefront API access", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[extensions.capabilities]\napi_access = true\n\n# ...\n", - "language": "toml" - } - ] - }, - "sectionCard": [ - { - "name": "API access examples", - "subtitle": "See", - "url": "/docs/api/customer-account-ui-extensions/apis/storefront-api#examples", - "type": "blocks" - } - ], - "sectionSubContent": [ - { - "title": "When to use Storefront API access", - "sectionContent": "API access is used when your extension needs to retrieve data from the [Storefront API](/api/storefront). For example, you may need to fetch product data, check the product tags on an item in the order summary.\n\n> Tip:\n> Shopify handles the authentication for all API calls from an extension.\n" - }, - { - "title": "Methods for accessing the Storefront API", - "sectionContent": "Enabling the `api_access` capability allows you to use the Order Status API [`query`](/docs/api/customer-account-ui-extensions/apis/storefront-api#orderstatusapi-propertydetail-query) method and the global `fetch` to retrieve data from the [Storefront API](/api/storefront) without manually managing token aquisition and refresh.\n\n`query` lets you request a single GraphQL response from the Storefront API.\n\nIf you prefer to construct GraphQL requests yourself or you would like to use a full-featured GraphQL client such as Apollo or urql, our custom `fetch` global automatically appends the required access tokens.\n\nThe GraphQL client of your choice shouldn’t use any DOM APIs, as they aren’t available in a customer account UI extension's Web Worker.\n\n> Note: Both `query` and `fetch` will work for calling the Storefront API with the `api_access` capability enabled. If you are using `fetch` to get data external to Shopify, refer to the [`network_access`](/api/customer-account-ui-extensions/configuration#network-access) capability." - }, - { - "title": "Storefront API access scopes", - "sectionContent": "\nYour extensions will have the following unauthenticated access scopes to the Storefront API:\n\n- unauthenticated_read_product_publications\n- unauthenticated_read_collection_publications\n- unauthenticated_read_product_listings\n- unauthenticated_read_product_tags\n- unauthenticated_read_selling_plans\n- unauthenticated_read_collection_listings\n- unauthenticated_read_metaobjects\n" - } - ] - }, - { - "type": "Generic", - "anchorLink": "network-access", - "title": "Network access", - "sectionContent": "\nThe following section describes use cases for requesting network access, alternatives to requesting network access, and steps for completing a request for network access.\n> Caution:\n> If your extension specifies the `network_access` capability, you must request access in order to publish your extension.\n", - "codeblock": { - "title": "Enable network access", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[extensions.capabilities]\nnetwork_access = true\n\n# ...\n", - "language": "toml" - } - ] - }, - "sectionSubContent": [ - { - "title": "When to request network access", - "sectionContent": "If you need to get data that you can't currently get from Shopify, then you should request network access. For example, you might need to fetch additional data to render loyalty points." - }, - { - "title": "Alternatives to network access", - "sectionContent": "\nInstead of fetching data with an external network call, consider retrieving the data from a metafield. Your app can use the [Customer Account API](/docs/api/customer) to write to [metafields](/docs/api/customer/latest/objects/Metafield) on the customer, order, company, or company location.\n\nAn app with the ability to query the Admin API can also write to [metafields](/api/admin-graphql/latest/objects/metafield) on the shop or product.\n\nRetrieving data from metafields is faster because it doesn't require an external network call. Instead, you can rely on Shopify for the uptime, scaling, and durability of the data storage.\n" - }, - { - "title": "Complete a request for network access", - "sectionContent": "\n1. Go to your [Partner Dashboard](https://partners.shopify.com/current/apps).\n2. Click the name of the app that you want to change.\n3. Click **API access**.\n4. Under **Allow network access in checkout and account UI extensions**, click **Allow network access**\n\n Your request is automatically approved and your app is immediately granted the approval scope that's required for your customer account UI extension to make external network calls.\n\n5. Add network_access = true to the [extensions.capabilities] section of your extension's configuration file." - }, - { - "title": "Required CORS headers", - "sectionContent": "\nSince UI extensions run in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API), they have a null origin. They do not share the storefront or customer account's origin. For network calls to succeed, your server must support [cross-origin resource sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for null origins by including this response header:\n\nAccess-Control-Allow-Origin: *\n" - }, - { - "title": "App Proxy", - "sectionContent": "\nUI extensions can make fetch requests to [App Proxy](/docs/apps/online-store/app-proxies) URLs, but there are some differences and limitations related to the security context within which UI extensions run.\n\nUI extension requests made to the App Proxy will execute as CORS requests. See _Required CORS headers_ above for information about requirements related to CORS.\n\nUI extension requests made to the App Proxy will not assign the logged_in_customer_id query parameter. Instead use a [session token](/docs/api/customer-account-ui-extensions/apis/standardapi#properties-propertydetail-sessiontoken) which provides the sub claim for the logged in customer.\n\nUI extension requests made to the App Proxy of password protected shops is not supported. Extension requests come from a web worker which does not share the same session as the parent window.\n\nThe App Proxy doesn't handle all [HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods). Specifically, CONNECT and TRACE are unsupported.\n" - }, - { - "title": "Security considerations", - "sectionContent": "\nWhen processing HTTP requests on your API server, you cannot guarantee that your own extension will have made every request. When responding with sensitive data, keep in mind that requests could originate from anywhere on the Internet.\n\nYour extension can pass a [session token](/docs/api/customer-account-ui-extensions/apis/session-token) to your API server but this only guarantees the integrity of its claims. It does not guarantee the request itself originated from Shopify. For example, your API server could trust the session token's `sub` claim (the customer ID) but it could not trust a `?customer_id=` query parameter.\n" - } - ] - }, - { - "type": "Generic", - "anchorLink": "collect-buyer-consent", - "title": "Collect buyer consent", - "sectionContent": "If your extension utilizes the [Customer Privacy API](/docs/api/customer-account-ui-extensions/apis/customer-privacy) to collecting buyer consent, you must first declare that capability in your configuration file.", - "sectionSubContent": [ - { - "title": "Customer Privacy", - "sectionContent": "In order to collect customer privacy consent, you'll need to add `customer_privacy = true` in your toml configuration. This will let you use our [Customer Privacy API](/docs/api/customer-account-ui-extensions/apis/customer-privacy)." - } - ], - "codeblock": { - "title": "Collect buyer consent", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "# ...\n\n[extensions.capabilities.collect_buyer_consent]\ncustomer_privacy = true\n\n# ...\n\n", - "language": "toml" - } - ] - } - }, - { - "type": "Generic", - "anchorLink": "metafields", - "title": "Metafields", - "sectionContent": "\nAll customer account UI extension [targets](/docs/api/customer-account-ui-extensions/targets) can read and write to metafields using the [Customer Account API](/docs/api/customer-account-ui-extensions/apis/customer-account-api). Learn more about [writing to metafields](/docs/apps/build/customer-accounts/metafields).\n\nAccess to metafields on a read-only basis through the [Order Status API](/docs/api/customer-account-ui-extensions/apis/order-status-api/metafields) is available to order status [targets](/api/customer-account-ui-extensions/targets) and is defined in your configuration. Customer account UI extensions are configured for metafields similarly to checkout UI extensions. [Learn more](/docs/api/checkout-ui-extensions/configuration#metafields).\n" - }, - { - "type": "Markdown", - "anchorLink": "settings-definition", - "title": "Settings definition", - "sectionContent": "The settings for a customer account UI extension define a set of fields that the merchant will be able to set a value for from the [checkout editor](/apps/checkout/test-ui-extensions#test-the-extension-in-the-checkout-editor). You can use validation options to apply additional constraints to the data that the setting can store, such as a minimum or maximum value. \n\n Each settings definition can include up to 20 settings. \n\n > Note: \n > All setting inputs are optional. You should code the extension so that it still works if the merchant hasn't set a value for the setting.", - "sectionSubContent": [ - { - "title": "Properties", - "sectionContent": "The following table describes the properties that you can use to define a setting:\n\n | Property | Required? | Description | Example |\n|---|---|---|---|\n| `key` | Yes | The key of the setting. When a merchant configures a value for this setting, the value will be exposed under this `key` when running your extension |
    \"banner_title\"
    |\n| `type` | Yes | The [type](#supported-setting-types) of setting. |
    \"single_line_text_field\"
    |\n| `name` | Yes | The name of the setting. `name` is displayed to the merchant in the checkout editor. |
    \"Banner title\"
    |\n| `description` | No | The description of the setting. `description` is displayed to the merchant in the checkout editor. |
    \"Enter a title for the banner.\"
    |\n| `validations` | No | Constraints on the setting input that Shopify validates. |
    validations: 
    name = \"max\",
    value = \"25\"
    |" - }, - { - "title": "Supported setting types", - "sectionContent": "The setting type determines the type of information that the setting can store. The setting types have built-in validation on the setting input. \n\n Settings can have the following types: \n\n| Type | Description | Example value |\n|---|---|---|\n| `boolean` | A true or false value. |
    true
    |\n| `date` | A date in ISO 8601 format without a presumed time zone. |
    2022-02-02
    |\n| `date_time` | A date and time in ISO 8601 format without a presumed time zone. |
    2022-01-01T12:30:00
    |\n| `single_line_text_field` | A single line string. |
    Canada
    |\n| `multi_line_text_field` | A multi-line string. |
    Canada
    United States
    Brazil
    Australia
    |\n| `number_integer` | A whole number in the range of +/-9,007,199,254,740,991. |
    10
    |\n| `number_decimal` | A number with decimal places in the range of +/-9,999,999,999,999.999999999. |
    10.4
    |\n| `variant_reference` | A globally-unique identifier (GID) for a product variant. |
    gid://shopify/ProductVariant/1
     |"
    -          },
    -          {
    -            "title": "Validation options",
    -            "sectionContent": "Each setting can include validation options. Validation options enable you to apply additional constraints to the data that a setting can store, such as a minimum or maximum value, or a regular expression. The setting's `type` determines the available validation options. \n\n You can include a validation option for a setting using the validation `name` and a corresponding `value`. The appropriate value depends on the setting type to which the validation applies.\n\n The following table outlines the available validation options with supported types for applying constraints to a setting:\n\n | Validation option | Description | Supported types | Example |\n|---|---|---|---|\n| Minimum length | The minimum length of a text value. | 
    • single_line_text_field
    • multi_line_text_field
    |
    [[extensions.settings.fields.validations]]
    name = \"min\"
    value = \"8\"
    |\n| Maximum length | The maximum length of a text value. |
    • single_line_text_field
    • multi_line_text_field
    |
    [[extensions.settings.fields.validations]]
    name = \"max\"
    value = \"25\"
    |\n| Regular expression | A regular expression. Shopify supports [RE2](https://github.com/google/re2/wiki/Syntax). |
    • single_line_text_field
    • multi_line_text_field
    |
    [[extensions.settings.fields.validations]]
    name = \"regex\"
    value = \"(@)(.+)$\"
    |\n| Choices | A list of up to 128 predefined options that limits the values allowed for the metafield. | `single_line_text_field` |
    [[extensions.settings.fields.validations]]
    name = \"choices\"
    value = \"[\\"red\\", \\"green\\", \\"blue\\"]\"
    |\n| Minimum date | The minimum date in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. | `date` |
    [[extensions.settings.fields.validations]]
    name = \"min\"
    value = \"2022-01-01\"
    |\n| Maximum date | The maximum date in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. | `date` |
    [[extensions.settings.fields.validations]]
    name = \"max\"
    value = \"2022-03-03\"
    |\n| Minimum datetime | The minimum date and time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. | `date_time` |
    [[extensions.settings.fields.validations]]
    name = \"min\"
    value = \"2022-03-03T16:30:00\"
    |\n| Maximum datetime | The maximum date and time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. | `date_time` |
    [[extensions.settings.fields.validations]]
    name = \"max\"
    value = \"2022-03-03T17:30:00\"
    |\n| Minimum integer | The minimum integer number. | `number_integer` |
    [[extensions.settings.fields.validations]]
    name = \"min\"
    value = \"9\"
    |\n| Maximum integer | The maximum integer number. | `number_integer` |
    [[extensions.settings.fields.validations]]
    name = \"max\"
    value = \"15\"
    |\n| Minimum decimal | The minimum decimal number. | `number_decimal` |
    [[extensions.settings.fields.validations]]
    name = \"min\"
    value = \"0.5\"
    |\n| Maximum decimal | The maximum decimal number. | `number_decimal` |
    [[extensions.settings.fields.validations]]
    name = \"max\"
    value = \"1.99\"
    |\n| Maximum precision | The maximum number of decimal places to store for a decimal number. | `number_decimal` |
    [[extensions.settings.fields.validations]]
    name = \"max_precision\"
    value = \"2\"
    |" - } - ] - }, - { - "type": "Generic", - "anchorLink": "example-settings-definition", - "title": "Example settings definition", - "sectionContent": "The following example shows a settings definition that defines a setting named `banner_title` of type `single_line_text_field`. When the merchant sets a value for this setting from the checkout editor, Shopify validates that the provided value is between 5 and 20 characters in length \n\n", - "sectionCard": [ - { - "name": "Settings example code", - "subtitle": "See", - "url": "/docs/api/customer-account-ui-extensions/apis/order-status-api/settings#examples", - "type": "blocks" - } - ], - "codeblock": { - "title": "Example settings", - "tabs": [ - { - "title": "shopify.extension.toml", - "code": "api_version = \"unstable\"\n\n[[extensions]]\nname = \"My customer account ui extension\"\nhandle = \"customer-account-ui\"\ntype = \"ui_extension\"\n\n[extensions.settings]\n\n[[extensions.settings.fields]]\nkey = \"banner_title\"\ntype = \"single_line_text_field\"\nname = \"Banner title\"\ndescription = \"Enter a title for the banner.\"\n\n[[extensions.settings.fields.validations]]\nname = \"min\"\nvalue = \"5\"\n[[extensions.settings.fields.validations]]\nname = \"max\"\nvalue = \"20\"\n", - "language": "toml" - } - ] - } - } - ] - }, - { - "title": "Error handling", - "description": "You can use standard web techniques to handle errors in [customer account UI extensions](/api/customer-account-ui-extensions/) but you may need to account for how they run inside of a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).", - "id": "error-handling", - "sections": [ - { - "type": "Generic", - "anchorLink": "handling-any-error", - "title": "Handling any error", - "sectionContent": "Add an `unhandledrejection` listener for promise rejections or an `error` listener for other exceptions like Javascript runtime errors or failures to load a resource.", - "codeblock": { - "title": "Handling any error", - "tabs": [ - { - "code": "// For unhandled promise rejections\nself.addEventListener(\n 'unhandledrejection',\n (error) => {\n console.warn(\n 'event unhandledrejection',\n error,\n );\n },\n);\n\n// For other exceptions\nself.addEventListener('error', (error) => {\n console.warn('event error', error);\n});\n", - "language": "ts" - } - ] - } - }, - { - "type": "Generic", - "anchorLink": "third-party-libraries", - "title": "Third party libraries", - "sectionContent": "\nYou can use error reporting libraries like [Bugsnag](https://www.bugsnag.com/) or [Sentry](https://sentry.io/). However, they might require extra configuration because UI extensions run inside of a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API).\n\n> Tip:\n> You must request [network access](/api/customer-account-ui-extensions/configuration#network-access) to transmit errors to a third party service.\n" - }, - { - "type": "Generic", - "anchorLink": "sentry", - "title": "Sentry (recommended)", - "sectionContent": "\nInitialize Sentry following their [Web Worker guide](https://docs.sentry.io/platforms/javascript/configuration/webworkers/). We recommend disabling the default integrations to be sure it will run within a Web Worker. You'll need to add event listeners manually.\n\nIf you are writing your UI extension in React, you can follow Sentry's [React integration guide](https://docs.sentry.io/platforms/javascript/guides/react/) to get additional context on errors thrown while rendering your components. Integrations like tracing do not currently run in Web Workers ([issue](https://github.com/getsentry/sentry-javascript/issues/5289)).", - "codeblock": { - "title": "Sentry", - "tabs": [ - { - "code": "import {\n reactExtension,\n Banner,\n} from '@shopify/ui-extensions-react/customer-account';\nimport * as Sentry from '@sentry/browser';\n\nSentry.init({\n dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',\n defaultIntegrations: false,\n});\n\nself.addEventListener(\n 'unhandledrejection',\n (error) => {\n Sentry.captureException(\n new Error(error.reason.stack),\n );\n },\n);\n\nself.addEventListener('error', (error) => {\n Sentry.captureException(\n new Error(error.message),\n );\n});\n\n// Your normal extension code.\nexport default reactExtension(\n 'customer-account.order-status.block.render',\n () => <Extension />,\n);\n\nfunction Extension() {\n return <Banner>Your extension</Banner>;\n}\n", - "language": "ts" - } - ] - } - }, - { - "type": "Generic", - "anchorLink": "bugsnag", - "title": "Bugsnag", - "sectionContent": "\nFollow [Bugsnag's documentation](https://docs.bugsnag.com/platforms/javascript/) to install it for your extension. Bugsnag adds event listeners by default so there's no need to add them manually.\n\nIf you use the [CDN version](https://docs.bugsnag.com/platforms/javascript/cdn-guide/), you'll need to add polyfill code (see example) before importing Bugsnag because it tries to access some variables that are not available in Web Workers ([details](https://github.com/bugsnag/bugsnag-js/issues/1506)).\n\nIf you are writing your UI extension in React, you can follow Bugsnag's [React integration guide](https://docs.bugsnag.com/platforms/javascript/legacy/react/) to get additional context on errors thrown while rendering your components.", - "codeblock": { - "title": "Bugsnag", - "tabs": [ - { - "code": "/**\n * The CDN version of Bugsnag requires this polyfill.\n */\n(() => {\n const document = {\n documentElement: {\n outerHTML: '',\n createElement: () => ({}),\n clientWidth: 0,\n clientHeight: 0,\n },\n addEventListener: () => {},\n };\n const history = {};\n const window = self;\n self.window = window;\n window.document = document;\n window.history = history;\n})();\n", - "language": "ts" - } - ] - } - } - ] - }, - { - "title": "Targets Overview", - "description": "\nA [target](/docs/apps/app-extensions/configuration#targets) represents where your customer account UI extension will appear.\n\nYou register for targets in your [configuration file](/docs/api/checkout-ui-extensions/configuration), and you include a JavaScript function that will run at that location in customer accounts.\n ", - "id": "extension-targets-overview", - "sections": [ - { - "type": "Generic", - "anchorLink": "static-extension-targets", - "title": "Static extension targets", - "image": "target-overview-static-extension-targets", - "altText": "The background of the entire diagram is a light red, which is the color that represents static extension targets. In the center is a solid-line box that says Core Feature. Above and below it, connected to the Core Feature by a lock icon, there are two red dotted-line boxes that contain example names of static extension targets, indicating that they are always tied to the Core Feature.", - "sectionContent": "Static extension targets render immediately before or after most core customer account features.\n \n\nWhen a core customer account feature isn't rendered, neither are the static extension targets tied to it.\n \n\nChoose static extension targets when your content and functionality is closely related to a core customer account feature.\n ", - "sectionCard": [ - { - "name": "Extension targets", - "subtitle": "API reference", - "url": "/docs/api/customer-account-ui-extensions/targets", - "type": "blocks" - } - ] - }, - { - "type": "Generic", - "anchorLink": "block-extension-targets", - "title": "Block extension targets", - "sectionContent": "Block extension targets render between core customer account features. Block extensions are always rendered, regardless of what other elements of the customer account are present.\n\nBlock extension targets always support multiple placements. Each placement has an associated placement reference that represents its location on the page. For example, the block extension target `customer-account.order-status.block.render` supports seven placements. The placement references include `PAGE_TITLE`, `ORDER_SUMMARY1`, and more.\n\nYou can use placement references as URL parameters to [test block extensions](/docs/apps/build/customer-accounts/test#block-targets) in all supported placements on a page. You can also use placement references to [define the default placement](/docs/apps/build/app-extensions/configure-app-extensions#customer-account-ui-extensions) of an extension for merchants.", - "altText": "The background of the entire diagram is a light purple, which is the color that represents block extension targets. In the center is a solid-line box that says Core Feature. Above and below it, not connected to the Core Feature, there are two purple dotted-line boxes that contain example names of block extension targets, indicating that they render between core features, regardless of whether that core feature is rendered or not.", - "sectionCard": [ - { - "name": "Extension targets", - "subtitle": "API reference", - "url": "/docs/api/customer-account-ui-extensions/targets", - "type": "blocks" - }, - { - "name": "Placement references", - "subtitle": "Learn more", - "url": "/docs/apps/build/customer-accounts/extension-placement#placement-references", - "type": "resource" - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "order-index", - "title": "Order index", - "sectionContent": "The **Order index** page is where customers can view and manage all their past and current orders.", - "accordionContent": [ - { - "title": "Orders", - "description": "The page contains one block extension that merchants can place above the page title or below the order list.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-index-orders.png", - "altText": "The desktop and mobile view of the Order index page, with the customer-account.order-index.block.render extension target shown in purple dotted-line boxes above the page title, and below the list of orders, indicating that it's a block extension target with multiple placements available." - }, - { - "title": "Order action menu", - "description": "Actions available on specific order\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-action-menu-extension.png", - "altText": "The desktop and mobile view of the order action menu on the Order index page. The menu label is \"Manage\", and contains one menu item that says \"Request return\". The menu also contains a red dotted-line box that says customer-account.order.action.menu-item.render, representing the static extension target that's available in this menu." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "order-status", - "title": "Order status", - "sectionContent": "The **Order status** page is where customers can view, track, and manage a specific order.", - "accordionContent": [ - { - "title": "Order status", - "description": "For tracking order statuses, and any updates regarding the delivery, pickup, or return of items.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-status-extension.png", - "altText": "The desktop and mobile view of the Order status page. Above and below the page title, there is a purple dotted-line box that indicates the available placements for the block extension target on this page." - }, - { - "title": "Order details", - "description": "Customer, shipping, and billing information associated with the order.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-details-extension.png", - "altText": "The desktop and mobile view of the Order details card on the Order status page, which includes contact information, payment, shipping address, billing address, and more. Above and below the Order details card there is a purple dotted-line box that indicates the available placements for the block extension target on this page. Inside the Order details card is a red dotted-line box that indicates the static extension target available in this location." - }, - { - "title": "Payment status", - "description": "Depending on the payment status of the order, relevant payment information and action items may be displayed here. For example, for orders with payment terms, the amount due, the due data, and a **Pay now** button is displayed.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-payment-status.png", - "altText": "The desktop and mobile view of the payment status card. Inside the card, below the payment status information, there is a red dotted-line box that says customer-account.order-status.payment-details.render-after, indicating the static extension target available in this location." - }, - { - "title": "Order summary", - "description": "Summary of the items, discounts, and order total.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-summary.png", - "altText": "The desktop and mobile view of the order summary card on the Order status page, which includes the images and names of the items in the order, their cost, and the calculations of subtotal, shipping, taxes, and total for the order. Under every item, there is a red dotted-line box that says customer-account.order-status.cart-line-item.render-after, indicating the static extension target available in this location. Under the entire list of items, there is one red dotted-line box that says customer-account.order-status.cart-line-list.render-after, indicating another static extension target available in this location. A purple dotted-line box that says customer-account.order-status.block-render is shown above the list of items, below the list of items, and below the, indicating the multiple placements available for this block extension target." - }, - { - "title": "Order action menu", - "description": "Actions available on a specific order.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-status-order-action-menu-extension.png", - "altText": "The desktop and mobile video of the order action menu on the Order status page. The menu label is \"Manage\", and contains one menu item that says \"Request return\". The menu also contains a red dotted-line box that says customer-account.order.action.menu-item.render, representing the static extension target that's available in this menu." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "profile-default", - "title": "Profile (Default)", - "sectionContent": "The **Profile** page is where customers view and edit their personal information.", - "accordionContent": [ - { - "title": "Customer details", - "description": "The customer's name and contact information.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-customer-details-extension.png", - "altText": "The desktop and mobile view of the Profile page. Above the page title, and below the section of the page that contains the customer's name, email, and phone number, there are purple dotted-line boxes that indicate the available placements for the block extension target on this page." - }, - { - "title": "Addresses", - "description": "The customer's personal addresses.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-addresses-extension.png", - "altText": "The desktop and mobile view of the addresses section of the Profile page. Inside the addresses card, under the customer's saved addresses, there's a red dotted-line box that says customer-account.profile.addresses.render-after, indicating the static extension target available in this location." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "profile-b2b", - "title": "Profile (B2B)", - "sectionContent": "For B2B customers, the **Profile** page includes information about the customer, company, and the company location(s) the customer has access to. Currently, extensions can be developed using these targets, but merchants cannot enable them via the Checkout and Accounts Editor. We recommend relying on [Profile (Default) targets](/docs/api/customer-account-ui-extensions/extension-targets-overview#profile-default) and the [companyLocation field](/docs/api/customer/latest/queries/companyLocation) to create a similar experience.", - "accordionContent": [ - { - "title": "Customer details", - "description": "The customer's name and contact information.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-customer-details-extension.png", - "altText": "The desktop and mobile view of the Profile page. Above the page title, and below the section of the page that contains the customer's name, email, and phone number, there are purple dotted-line boxes that indicate the available placements for the block extension target on this page." - }, - { - "title": "Company details", - "description": "The company name. This extension target can be used to add more information about the company.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-company-details-extension.png", - "altText": "The desktop and mobile view of the company section of the Profile page. The header of the section says \"Celadon\" which is an example company name. Under the header, there is a red dotted-line box that says customer-account.profile.company-details.render-after, indicating the static extension target available in this location." - }, - { - "title": "Company location details", - "description": "The shipping address, billing address, and payment details associated with each specific company location.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-company-location-details-extension.png", - "altText": "The desktop and mobile view of the section of the B2B Profile page that contains details about the company location. Under the addresses section, there's a red dotted-line box that says customer-account.profile.company-location-addresses.render-after, indicating the static extension target available in this location. Under the payment methods section, there's another red dotted-line box that says customer-account.profile.company-location-payment.render-after, indicating a static extension target available in this location." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "order-action-menu-extension-target", - "title": "Order action menu", - "sectionContent": "Order-related actions that customers can access from both the **Order index** and **Order status** page.", - "accordionContent": [ - { - "title": "Order index page", - "description": "Where customers can view and manage all their past and current orders.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-index-page-extension.png", - "altText": "The desktop and mobile view of the Order index page that contains a list of all orders. In the Manage menu, there's a red dotted-line box that says customer-account.order-action-menu-item.render, indicating the static extension target available in this location." - }, - { - "title": "Order status page", - "description": "Where customers can view, track, and manage a specific order.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-status-page-extension.png", - "altText": "The desktop and mobile view of the Order status page that contains details about a specific order. In the Manage menu, there's a red dotted-line box that says customer-account.order-action-menu-item.render, indicating the static extension target available in this location." - }, - { - "title": "Order action modal", - "description": "A modal that can rendered to complete an order action flow.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).\n ", - "image": "target-overview-order-action-render-extension.png", - "altText": "The desktop and mobile views of the customer-account.order.action.render extension target." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "full-page-extension-target", - "title": "Full-page extension", - "sectionContent": "Build new pages for customer accounts. Full-page extensions render in the main content area—below the header, and above the footer.", - "accordionContent": [ - { - "title": "Full-page extension", - "description": "This full-page extension target is for building pages that are **not** tied to a specific order. For example, a Wishlist page.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).", - "image": "target-overview-full-page-extension.png", - "altText": "A desktop view of the customer-account.page.render full-page extension target that renders between the header and footer." - }, - { - "title": "Full-page extension (order-specific)", - "description": "This full-page extension target is for building pages that are tied to a specific order. For example, a Request Return page. \n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).", - "image": "target-overview-full-page-order-specific-extension.png", - "altText": "A desktop view of the customer-account.order.page.render full-page extension target that renders between the header and footer." - } - ] - }, - { - "type": "GenericAccordion", - "anchorLink": "footer", - "title": "Footer", - "sectionContent": "The section at the bottom of all customer account pages, where customers can find links to store policies.", - "accordionContent": [ - { - "title": "Footer", - "description": "A static extension target that renders in the footer, below the links to store policies. Since the footer appears across all customer account pages, this is an ideal location for elements like cookie consent banners that need to be visible across the entire customer accounts experience.\n \nSee all [extension targets](/docs/api/customer-account-ui-extensions/targets).", - "image": "target-overview-footer-extension.png", - "altText": "A desktop view of the customer-account.footer.render-after extension target that renders in the footer." - } - ] - } - ] - }, - { - "title": "Customer account UI extensions", - "description": "\n Customer account UI extensions let app developers build custom functionality that merchants can install at defined points on the **Order index**, **Order status**, and **Profile** pages in customer accounts.\n\n \n\n > Shopify Plus: \n>Some static extensions on the Profile page only render for B2B customers. B2B on Shopify is only available on the [Shopify Plus](https://www.shopify.com/plus) plan. [See B2B Profile targets](/api/customer-account-ui-extensions/unstable/extension-targets-overview#profile-b2b)\n ", - "id": "customer-account-ui-extensions", - "image": "/assets/landing-pages/templated-apis/customer-account-ui-extensions/customer-account-ui.png", - "darkImage": "/assets/landing-pages/templated-apis/customer-account-ui-extensions/customer-account-ui-dark.png", - "mobileImage": "/assets/landing-pages/templated-apis/customer-account-ui-extensions/customer-account-ui-mobile.png", - "mobileDarkImage": "/assets/landing-pages/templated-apis/customer-account-ui-extensions/customer-account-ui-mobile-dark.png", - "sections": [ - { - "type": "Generic", - "anchorLink": "scaffolding-extension", - "title": "Scaffolding an extension", - "sectionContent": "Use Shopify CLI to [generate a new extension](/apps/tools/cli/commands#generate-extension) in the directory of your app.", - "sectionCard": [ - { - "name": "Getting started", - "subtitle": "Navigate to", - "url": "/docs/apps/customer-accounts/getting-started", - "type": "blocks" - } - ], - "codeblock": { - "title": "Scaffolding", - "tabs": [ - { - "title": "npm", - "code": "npm init @shopify/app@latest\ncd your-app\nnpm run shopify app generate extension\n", - "language": "bash" - }, - { - "title": "yarn", - "code": "yarn create @shopify/app\ncd your-app\nyarn shopify app generate extension\n", - "language": "bash" - }, - { - "title": "pnpm", - "code": "pnpm create @shopify/app\ncd your-app\npnpm shopify app generate extension\n", - "language": "bash" - } - ] - }, - "initialLanguage": "bash" - }, - { - "type": "Generic", - "anchorLink": "extension-targets", - "title": "Extension targets", - "sectionContent": "Extension targets provide locations for customer account UI extensions to appear.\n \n\nExtension UIs are rendered using [remote UI](https://github.com/Shopify/remote-ui),\n a fast and secure environment for custom [(non-DOM)](#security) UIs.", - "sectionCard": [ - { - "name": "Extension targets", - "subtitle": "Overview", - "url": "/api/customer-account-ui-extensions/extension-targets-overview", - "type": "blocks" - } - ], - "image": "extension-targets.png", - "altText": "The Profile page with a purple dotted-line box above the page title that says \"Extension targets\".", - "codeblock": { - "title": "Extension targets", - "tabs": [ - { - "title": "React", - "code": "import {\n reactExtension,\n Banner,\n useTranslate,\n} from '@shopify/ui-extensions-react/customer-account';\n\nreactExtension('customer-account.order-index.block.render', () => (\n <App />\n));\n\nfunction App() {\n const translate = useTranslate();\n return <Banner>{translate('welcomeMessage')}</Banner>;\n}\n", - "language": "tsx" - }, - { - "title": "JavaScript", - "code": "import {\n extension,\n Banner,\n} from '@shopify/ui-extensions/customer-account';\n\nextension(\n 'customer-account.order-status.block.render',\n (root, api) => {\n const banner = root.createComponent(\n Banner,\n {},\n api.i18n.translate('welcomeMessage'),\n );\n root.appendChild(banner);\n },\n);\n", - "language": "js" - } - ] - }, - "initialLanguage": "tsx" - }, - { - "type": "Generic", - "anchorLink": "configuration-file", - "title": "Configuration file", - "sectionContent": "When you create a customer account UI extension, the shopify.extension.toml file is automatically generated in your customer account UI extension directory. It contains the extension's configuration, which includes the extension name, extension targets, metafields, capabilities and settings definition.", - "sectionCard": [ - { - "name": "Configuration guide", - "subtitle": "Navigate to", - "url": "/api/customer-account-ui-extensions/configuration", - "type": "gear" - } - ], - "codeblock": { - "title": "shopify.ui.extension.example.toml", - "tabs": [ - { - "title": "toml", - "code": "api_version = \"unstable\"\n\n[[extensions]]\nname = \"My customer account ui extension\"\nhandle = \"customer-account-ui\"\ntype = \"ui_extension\"\n\n[[extensions.targeting]]\ntarget = \"customer-account.order-status.block.render\"\nmodule = \"./Extension.jsx\"\n", - "language": "toml" - } - ] - }, - "initialLanguage": "yaml" - }, - { - "type": "Generic", - "anchorLink": "extension-apis", - "title": "Extension APIs", - "sectionContent": "APIs enable customer account UI extensions to get information about the customer or related objects and to perform actions. For example, you can use APIs to retrieve previous orders of the customer so that you can offer related products as upsells.\n\nExtensions use JavaScript to read and write data and call external services, and natively render UIs built using Shopify's checkout and customer account components.", - "sectionCard": [ - { - "name": "Customer account UI extensions APIs", - "subtitle": "Navigate to", - "url": "/api/customer-account-ui-extensions/apis", - "type": "blocks" - } - ], - "codeblock": { - "title": "Extension APIs", - "tabs": [ - { - "title": "React", - "code": "import {\n reactExtension,\n Banner,\n useTranslate,\n} from '@shopify/ui-extensions-react/customer-account';\n\nreactExtension(\n 'customer-account.order-status.block.render',\n () => <App />,\n);\n\nfunction App() {\n const translate = useTranslate();\n return <Banner>{translate('welcomeMessage')}</Banner>;\n}\n", - "language": "tsx" - }, - { - "title": "JavaScript", - "code": "import {\n extension,\n Banner,\n} from '@shopify/ui-extensions/customer-account';\n\nextension(\n 'customer-account.order-status.block.render',\n (root, api) => {\n renderApp(root, api);\n },\n);\n\nfunction renderApp(root, api) {\n // In case of a re-render, remove previous children.\n for (const child of root.children) {\n root.removeChild(child);\n }\n\n const banner = root.createComponent(\n Banner,\n {},\n api.i18n.translate('welcomeMessage'),\n );\n root.appendChild(banner);\n}\n", - "language": "js" - } - ] - }, - "initialLanguage": "tsx" - }, - { - "type": "Generic", - "anchorLink": "ui-components", - "title": "UI components", - "image": "ui-components.gif", - "altText": "An animation of a card that contains an image, heading, description, and button, shifting and transforming into highly customized versions of the same UI to reflect each merchant's unique branding.", - "sectionContent": "Customer account UI extensions declare their interface using supported UI components. Shopify renders the UI natively so it's performant, accessible, and works in all of customer account supported browsers.\n \n\nComponents are designed to be flexible, enabling you to layer and mix them to create highly-customized app extensions that feel seamless within the customer account experience. All components that will inherit a merchant's brand settings and the CSS cannot be altered or overridden.\n \n\nTo build customer account UI extensions, you can use checkout components, and customer account components.", - "sectionCard": [ - { - "name": "Checkout components", - "subtitle": "API Reference", - "url": "/api/checkout-ui-extensions/components", - "type": "blocks" - }, - { - "name": "Customer account components", - "subtitle": "API Reference", - "url": "/api/customer-account-ui-extensions/components", - "type": "blocks" - }, - { - "name": "Figma UI kit", - "subtitle": "UI Reference", - "url": "https://www.figma.com/community/file/1304881365343613949/checkout-and-account-components", - "type": "library" - } - ], - "codeblock": { - "title": "UI components", - "tabs": [ - { - "title": "React", - "code": "import {\n reactExtension,\n BlockStack,\n InlineStack,\n Button,\n Image,\n Text,\n} from '@shopify/ui-extensions-react/customer-account';\n\nreactExtension(\n 'customer-account.order-status.block.render',\n () => <App />,\n);\n\nfunction App() {\n return (\n <InlineStack>\n <Image source=\"/url/for/image\" />\n <BlockStack>\n <Text size=\"large\">Heading</Text>\n <Text size=\"small\">Description</Text>\n </BlockStack>\n <Button\n onPress={() => {\n console.log('button was pressed');\n }}\n >\n Button\n </Button>\n </InlineStack>\n );\n}\n", - "language": "tsx" - }, - { - "title": "JavaScript", - "code": "import {\n extension,\n BlockStack,\n Button,\n Image,\n InlineStack,\n Text,\n} from '@shopify/ui-extensions/customer-account';\n\nextension(\n 'customer-account.order-status.block.render',\n (root) => {\n const inlineStack = root.createComponent(\n InlineStack,\n {},\n [\n root.createComponent(Image, {\n source: '/url/for/image',\n }),\n root.createComponent(BlockStack, {}, [\n root.createComponent(\n Text,\n {size: 'large'},\n 'Heading',\n ),\n root.createComponent(\n Text,\n {size: 'small'},\n 'Description',\n ),\n ]),\n root.createComponent(\n Button,\n {\n onPress: () => {\n console.log('button was pressed');\n },\n },\n 'Button',\n ),\n ],\n );\n\n void root.appendChild(inlineStack);\n },\n);\n", - "language": "js" - } - ] - }, - "initialLanguage": "tsx" - }, - { - "type": "GenericAccordion", - "anchorLink": "custom-protocols", - "title": "Custom protocols", - "sectionContent": "Custom protocols make it easier to navigate to common locations, and construct URLs.", - "accordionContent": [ - { - "title": "Shopify protocol", - "description": "Use the `shopify:customer-account` protocol when you want to construct a URL with a root of customer accounts.", - "codeblock": { - "title": "shopify:customer-account", - "tabs": [ - { - "title": "Link to Order Index page", - "code": "<Link to=\"shopify:customer-account/orders\" />\n", - "language": "tsx" - }, - { - "title": "Fetch data", - "code": "fetch(\n 'shopify:customer-account/api/unstable/graphql.json',\n {\n method: 'POST',\n body: JSON.stringify(simpleOrderQuery),\n },\n);\n", - "language": "js" - } - ] - }, - "initialLanguage": "tsx" - }, - { - "title": "Relative URLs", - "description": "Relative URLs are relative to your extension and are useful when you want to link to a route in your extension.", - "codeblock": { - "title": "/relative/urls", - "tabs": [ - { - "title": "Link to route in your extension", - "code": "<Link to={`/subscriptions/${subscription.id}`} />\n", - "language": "tsx" - } - ] - } - }, - { - "title": "Extension Protocol", - "description": "Triggers a navigation to an extension using the `extension:` protocol. The handle is the handle of the extension that will be navigated to in the same application. Build a [full-page extension](/docs/api/customer-account-ui-extensions/extension-targets-overview#full-page-extension-target) to create a new page in customer accounts and handle the navigation.", - "codeblock": { - "title": "extension:handle", - "tabs": [ - { - "title": "Link to a route of an extension", - "code": "<Link\n to={`extension:${extension.handle}/${path}`}\n>\n To full-page extension\n</Link>;\n\n<Link\n to={`extension:${extension.handle}/customer-account.order.page.render/${orderId}/${path}`}\n>\n To full-page extension (order-specific)\n</Link>;\n", - "language": "tsx" - } - ] - } - } - ] - }, - { - "type": "Generic", - "anchorLink": "security", - "title": "Security", - "sectionContent": "\nCustomer account UI extensions are a safe and secure way to customize the appearance and functionality of the customer account pages without compromising the security of customer data.\n- They run in an isolated sandbox, separate from the customer account page and other UI extensions.\n- They don't have access to sensitive payment information or the customer account page itself (HTML or other assets).\n- They are limited to specific UI components and APIs that are exposed by the platform.\n- They have limited access to [global web APIs](https://github.com/Shopify/ui-extensions/blob/unstable/documentation/runtime-environment.md).\n- Apps that wish to access [protected customer data](/docs/apps/store/data-protection/protected-customer-data), must submit an application and are subject to strict security guidelines and review proccesses by Shopify.\n", - "sectionNotice": [ - { - "title": "Constraints", - "sectionContent": "\nYou can't override the CSS for UI components. The customer account UI extension will always render the merchant's own branding as shown in the image in the UI components section above.\n\nCustomer account UI extensions don't have access to the DOM and can't return DOM nodes. They can't return `
    ` elements, for example. Building an arbitrary tree of HTML and loading additional scripts using script tags are also not supported.\n", - "type": "info" - } - ], - "sectionCard": [ - { - "name": "Rendering extensions", - "subtitle": "Learn more", - "url": "https://shopify.engineering/remote-rendering-ui-extensibility", - "type": "tutorial" - } - ] - }, - { - "type": "Generic", - "anchorLink": "troubleshooting", - "title": "Troubleshooting", - "sectionContent": "Find an end-to-end guide to testing your extensions in [Testing customer account UI extensions](https://shopify.dev/docs/apps/customer-accounts/best-practices/testing-ui-extensions)." - }, - { - "type": "Generic", - "anchorLink": "tutorials", - "title": "Tutorials", - "sectionContent": "Learn how to build customer account UI extensions using APIs and UI components.", - "sectionCard": [ - { - "name": "Inline extensions", - "subtitle": "Tutorial", - "url": "/docs/apps/customer-accounts/build-inline-extensions/order-status", - "type": "blocks" - }, - { - "name": "Order action menu extensions", - "subtitle": "Tutorial", - "url": "/docs/apps/customer-accounts/order-action-menu-extensions/build-order-action-menu-extensions", - "type": "blocks" - }, - { - "name": "Full-page extensions", - "subtitle": "Tutorial", - "url": "/docs/apps/customer-accounts/full-page-extensions/build-full-page-extensions", - "type": "blocks" - }, - { - "name": "Building metafield writes into extensions", - "subtitle": "Tutorial", - "url": "/docs/apps/build/customer-accounts/metafields", - "type": "blocks" - }, - { - "name": "Build Pre-auth Order Status page extensions", - "subtitle": "Tutorial", - "url": "/docs/apps/build/customer-accounts/pre-auth-order-status-page-extensions/build-pre-auth-order-status-page-extensions", - "type": "blocks" - } - ] - }, - { - "type": "Resource", - "anchorLink": "resources", - "title": "Resources", - "resources": [ - { - "name": "UX guidelines", - "subtitle": "Best practices for designing consistent and useful customer account UI extensions.", - "url": "/docs/apps/customer-accounts/best-practices/ux-guidelines", - "type": "star" - }, - { - "name": "Tutorials", - "subtitle": "Learn how to build inline, full-page, or order action menu extensions in customer accounts.", - "url": "/docs/apps/customer-accounts", - "type": "growth" - }, - { - "name": "Localizing UI extensions", - "subtitle": "Learn how to localize your customer account UI extension for international merchants and customers.", - "url": "/api/customer-account-ui-extensions/apis/localization", - "type": "globe" - } - ] - } - ] - } -] \ No newline at end of file diff --git a/packages/ui-extensions/package.json b/packages/ui-extensions/package.json index 4e1ea18d82..61cf133594 100644 --- a/packages/ui-extensions/package.json +++ b/packages/ui-extensions/package.json @@ -8,7 +8,7 @@ "docs:checkout": "bash ./docs/surfaces/checkout/build-docs.sh", "docs:point-of-sale": "bash ./docs/surfaces/point-of-sale/build-docs.sh", "docs:point-of-sale:dev": "nodemon --watch src/surfaces/point-of-sale/ --watch docs/surfaces/point-of-sale/ -e ts,tsx,json,png,txt --ignore '**/generated/**' --exec 'yarn docs:point-of-sale'", - "docs:customer-account": "bash ./docs/surfaces/customer-account/build-docs.sh" + "docs:customer-account": "node ./docs/surfaces/customer-account/build-docs.mjs" }, "main": "index.js", "module": "index.mjs", diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Avatar/Avatar.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Avatar/Avatar.doc.ts index 6d1c0d7597..13ac136b44 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/Avatar/Avatar.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Avatar/Avatar.doc.ts @@ -16,7 +16,8 @@ const data: ReferenceEntityTemplateSchema = { filePath: 'components/Avatar/Avatar.ts', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Media and visuals', defaultExample: { image: 'avatar-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Badge/Badge.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/Badge.doc.ts new file mode 100644 index 0000000000..9a693ccae7 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/Badge.doc.ts @@ -0,0 +1,76 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Badge', + description: + 'Use badges to highlight contextual information, like a label or a status, about an object. An object can be anything that has a status or label attributed to it, like an order or subscription.', + isVisualComponent: true, + thumbnail: 'badge-thumbnail.png', + requires: '', + type: '', + definitions: [ + { + title: 'BadgeProps', + description: '', + type: 'BadgeProps', + }, + ], + category: 'UI components', + subCategory: 'Feedback and status indicators', + + defaultExample: { + image: 'badge-default.png', + codeblock: { + title: 'Basic Badge', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-badge.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [ + { + image: 'badge-status.png', + codeblock: { + title: 'Using the Badge component as a status indicator', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Badge/examples/status-badge.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/status-badge.example.ts', + language: 'js', + }, + ], + }, + }, + ], + }, + + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + + sectionContent: + '- Aim for one word per badge.\n\n- For complex states that require 2 words, use sentence case.\n\n- For status badge labels, use an adjective (for example, "Available" or "Complete") or a verb in the past tense (for example, "Delivered" or "Delayed")\n\n- Use the tone prop to indicate the level of importance. `subdued` provides the least emphasis, while `critical` indicates the highest level of urgency.\n\n- Write a useful `accessibilityLabel` so that customers using assistive technology can access the full meaning of the badge in context. For badges with the `critical` tone, include information that conveys the urgency of the badge (for example, "Warning" or "Alert").\n\n- A badge should always be attributed to an object on the page.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.ts new file mode 100644 index 0000000000..2086769f3d --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/basic-badge.example.ts @@ -0,0 +1,7 @@ +import {extension, Badge} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const badge = root.createComponent(Badge, undefined, 'Available'); + + root.appendChild(badge); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/status-badge.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/status-badge.example.ts new file mode 100644 index 0000000000..458ba3b0a9 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Badge/examples/status-badge.example.ts @@ -0,0 +1,39 @@ +import { + extension, + Badge, + BlockStack, + Text, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const container = root.createComponent( + BlockStack, + { + border: 'base', + padding: 'large200', + spacing: 'base', + borderRadius: 'large', + }, + [ + root.createComponent(BlockStack, {spacing: 'none'}, [ + root.createComponent( + Text, + {size: 'large', emphasis: 'bold'}, + 'Subscription', + ), + root.createComponent(Text, undefined, 'Mini garden seeds'), + ]), + + root.createComponent( + BlockStack, + {spacing: 'none', inlineAlignment: 'start'}, + [ + root.createComponent(Text, {emphasis: 'bold'}, '$35.00 monthly'), + root.createComponent(Badge, {tone: 'subdued'}, 'Paused'), + ], + ), + ], + ); + + root.appendChild(container); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Banner/Banner.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Banner/Banner.doc.ts new file mode 100644 index 0000000000..5706b9684b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Banner/Banner.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Banner', + description: + 'Use banners to communicate important messages to customers in a prominent way.', + isVisualComponent: true, + thumbnail: 'banner-thumbnail.png', + requires: '', + type: '', + definitions: [ + { + title: 'BannerProps', + description: '', + type: 'BannerProps', + }, + ], + category: 'UI components', + subCategory: 'Feedback and status indicators', + defaultExample: { + image: 'banner-default.png', + codeblock: { + title: 'Basic Banner', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-banner.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use banners thoughtfully and sparingly, and only for the most important information. Too many banners distract customers from completing checkout.\n\n- Banners are typically displayed at the top of a page or a section, if they relate to specific content. Place banners below the relevant page or section header.\n\n- Include a Button component with next steps when possible.\n\n- Make banners dismissible, unless they contain critical information or an important step that customers need to take.\n\n- Use the `info` banner to update customers about a change or to give them advice.\n\n- Use the `warning` banner to display information that needs attention or that customers need to take action on. Warning banners can be stressful for customers, so be cautious about using them.\n\n- Use the `critical` banner to communicate problems that customers need to resolve immediately to complete checkout.', + }, + { + type: 'Generic', + anchorLink: 'status', + title: 'Status', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "info" | Convey general information or actions that aren’t critical or tied to a particular action.. |\n| "success" | Use rarely, only if you need additional visual confirmation that a non-standard action has been completed successfully, for example adding an item to an order as an upsell. |\n| "warning" | Display information that needs attention or that customers should take action on. Seeing these banners can be stressful for customers so be cautious about using them. Should not block progress to next step. |\n| "critical" | Communicate problems that have to be resolved immediately for customers to complete a task. For example, using a different payment method if card details couldn’t be processed. Seeing these banners can be stressful for customers so be cautious about using them. |', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.ts new file mode 100644 index 0000000000..830efd0b29 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Banner/examples/basic-banner.example.ts @@ -0,0 +1,11 @@ +import {extension, Banner} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const banner = root.createComponent(Banner, { + status: 'critical', + title: + 'Your payment details couldn’t be verified. Check your card details and try again.', + }); + + root.appendChild(banner); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/BlockLayout.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/BlockLayout.doc.ts new file mode 100644 index 0000000000..b97797defe --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/BlockLayout.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'BlockLayout', + description: + 'BlockLayout is used to lay out content over multiple rows.\n\nBy default, all rows fill the available block space, sharing it equally.', + thumbnail: 'blocklayout-thumbnail.png', + isVisualComponent: true, + requires: '', + type: '', + definitions: [ + { + title: 'BlockLayoutProps', + description: '', + type: 'BlockLayoutProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'blocklayout-default.png', + codeblock: { + title: 'Basic BlockLayout', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-blocklayout.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.ts new file mode 100644 index 0000000000..995d94f748 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockLayout/examples/basic-blocklayout.example.ts @@ -0,0 +1,16 @@ +import {extension, BlockLayout, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const blockLayout = root.createComponent( + BlockLayout, + { + rows: [60, 'fill'], + }, + [ + root.createComponent(View, {border: 'base', padding: 'base'}, '60'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'fill'), + ], + ); + + root.appendChild(blockLayout); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/BlockSpacer.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/BlockSpacer.doc.ts new file mode 100644 index 0000000000..b44eb23e03 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/BlockSpacer.doc.ts @@ -0,0 +1,47 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'BlockSpacer', + description: + 'BlockSpacer is used to create empty block space, typically when variable spacing is needed between multiple elements.\n\nNote that you should favor BlockStack when spacing between all elements is the same.', + isVisualComponent: true, + thumbnail: 'blockspacer-thumbnail.png', + requires: '', + type: '', + definitions: [ + { + title: 'BlockSpacerProps', + description: '', + type: 'BlockSpacerProps', + }, + { + title: 'StyleHelper', + description: + 'Style is a helper for authoring conditional values for prop styles.\n\nWrite complex conditional styles based on one or more conditions, such as viewport sizes and interactive states, in a concise and expressive way.', + type: 'DocsStyle', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'blockspacer-default.png', + codeblock: { + title: 'Basic BlockSpacer', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-blockspacer.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.ts new file mode 100644 index 0000000000..c938c45eab --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockSpacer/examples/basic-blockspacer.example.ts @@ -0,0 +1,11 @@ +import {extension, BlockSpacer, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const blockSpacer = root.createComponent(View, undefined, [ + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(BlockSpacer, {spacing: 'loose'}), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + ]); + + root.appendChild(blockSpacer); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/BlockStack.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/BlockStack.doc.ts new file mode 100644 index 0000000000..cc2998a9ab --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/BlockStack.doc.ts @@ -0,0 +1,67 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const disclosureAndAlignment = getExample( + 'ui-components/disclosure-and-alignment', + ['jsx', 'js'], +); + +const data: ReferenceEntityTemplateSchema = { + name: 'BlockStack', + description: 'BlockStack is used to vertically stack elements.', + thumbnail: 'blockstack-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'BlockStackProps', + description: '', + type: 'BlockStackProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'blockstack-default.png', + codeblock: { + title: 'Basic BlockStack', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-blockstack.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [disclosureAndAlignment], + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.ts new file mode 100644 index 0000000000..7e48a27fe1 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/BlockStack/examples/basic-blockstack.example.ts @@ -0,0 +1,11 @@ +import {extension, BlockStack, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const blockStack = root.createComponent(BlockStack, undefined, [ + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + ]); + + root.appendChild(blockStack); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Button/Button.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Button/Button.doc.ts new file mode 100644 index 0000000000..2d6f871288 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Button/Button.doc.ts @@ -0,0 +1,64 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Button', + description: + 'Buttons are used for actions, such as “Add”, “Continue”, “Pay now”, or “Save”.', + thumbnail: 'button-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ButtonProps', + description: '', + type: 'ButtonProps', + }, + ], + category: 'UI components', + subCategory: 'Actions', + defaultExample: { + image: 'button-default.png', + codeblock: { + title: 'Basic Button', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Button/examples/basic-button.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-button.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "critical" | Conveys a problem has arisen. |\n| "monochrome" | Takes the color of its parent.|', + }, + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '**Content Best Practices**\n\n- Clearly label each button to accurately represent the action associated with it.\n\n- Use strong actionable verbs at the beginning of button text to make it clear to the user what action will occur when the button is clicked.\n\n**Hierarchy Best Practices**\n\n- Establish a visual hierarchy between buttons to minimize confusion and help users understand which actions are most important.\n\n- Use only one high-emphasis button (primary button) per context to make it clear that other buttons have less importance.\n\n- Use lower-emphasis buttons for secondary calls to action.\n\n- Use primary buttons for actions that progress users through checkout such as “Pay now” or for concluding an action in a modal such as “Apply”.\n\n- Use secondary buttons to provide alternative actions to the primary button, without disrupting the primary flow such as “Track your order”.\n\n- Use plain buttons for least prominent, non-critical actions such as “Login to your account”.\n\n**When to Use Buttons**\n\n- Use buttons to communicate actions the user can take.\n\n- Use buttons to allow users to interact with the page.\n\n**When Not to Use Buttons**\n\n- Don’t use buttons as navigational elements. Use links instead when the desired action is to take the user to a new page.', + }, + ], + related: [ + { + name: 'Link', + subtitle: 'Component', + url: 'link', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Button/examples/basic-button.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Button/examples/basic-button.example.ts new file mode 100644 index 0000000000..4d8191fb7d --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Button/examples/basic-button.example.ts @@ -0,0 +1,11 @@ +import {extension, Button} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const button = root.createComponent( + Button, + {onPress: () => console.log('onPress event')}, + 'Pay now', + ); + + root.appendChild(button); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Card/Card.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Card/Card.doc.ts index 05349256ec..b8dcb5688c 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/Card/Card.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Card/Card.doc.ts @@ -15,7 +15,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'CardProps', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Layout and structure', defaultExample: { image: 'card-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/Chat.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/Chat.doc.ts new file mode 100644 index 0000000000..4fbe6edd61 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/Chat.doc.ts @@ -0,0 +1,208 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Chat', + description: ` +Use the Chat component to create real-time chat applications. +`, + thumbnail: 'chat-thumbnail.png', + requires: + 'access to the **Chat in checkout extensions** scope. Request access in the Partner Dashboard.', + isVisualComponent: true, + type: 'component', + definitions: [ + { + title: 'ChatProps', + description: '', + type: 'ChatProps', + }, + { + title: 'App Bridge for checkout', + description: ` +The App Bridge script for checkout provides APIs that enables a secure communication channel between the Shopify checkout and the embedded application within the Chat iframe. It also offers convenient methods to perform common actions like resizing the iframe from within the application. + +After App Bridge is [set up](#about-app-bridge) in your app, you have access to the \`shopify\` global variable. This variable exposes the following App Bridge functionalities and configuration information: + `, + type: 'AppBridge', + }, + ], + category: 'UI components', + subCategory: 'Overlays', + defaultExample: { + image: 'chat-component-minimized.png', + codeblock: { + title: 'Basic Chat', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-chat.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'src-and-query-parameters', + title: 'Chat source and query parameters', + sectionContent: ` +The \`src\` of the iframe rendered by Chat is provided by the \`preloads\` \`chat\` key in the extension configuration file. Shopify automatically appends query parameters to the URL which allows developers to verify the authenticity of the request and the identity of the merchant. We guarantee these tokens are valid and signed by Shopify. + +#### id_token +The ID token providing a set of claims as a signed [JSON Web Token (JWT)](https://openid.net/specs/openid-connect-core-1_0.html#IDToken%5C) with a TTL of 5 minutes. It can be used to retrieve merchants information on the backend as well as ensure that requests came from a Shopify authenticated source. See the [ID Token documentation](https://shopify.dev/docs/apps/build/authentication-authorization/session-tokens) for more information. + +#### locale +The locale of the shop that's embedding the app, i.e. \`en-CA\`. This information is also available in the \`shopify\` global variable under \`config\`. + +#### handle +The unique handle name of the UI extension as defined by the developer. This information is also available in the \`shopify\` global variable under \`extension\`. +`, + codeblock: { + title: 'Chat source', + tabs: [ + { + title: 'shopify.extension.toml', + code: './examples/shopify-extension-toml.example.toml', + language: 'toml', + }, + ], + }, + }, + { + type: 'Generic', + anchorLink: 'chat-dimensions', + title: 'Chat dimensions', + image: 'chat-component-iframe-clipping.png', + sectionContent: ` +To provide developers with the most flexibility when it comes to responsive changes, the iframe rendered in the page by \`Chat\` takes the full width and height of the browser window. Only a specific part of the iframe is visible, the rest is clipped. + +The \`inlineSize\` and \`blockSize\` values set on the Chat component or changed through the App Bridge \`resizeTo()\` method dictates the bounding box of the visible part. That box is fixed and positioned in the bottom right corner of the iframe. + +Your application can rely on the window's dimension to change styles or apply specific behaviors to different window sizes. This allow developers to style their app as if as if the application would be outside an iframe. For example, CSS media queries can now work within the iframe. +`, + }, + { + type: 'Generic', + anchorLink: 'about-app-bridge', + title: 'Getting started with App Bridge for checkout', + sectionContent: ` +You must add App Bridge to your hosted chat application by including the script tag pointing to the \`app-bridge-checkout.js\` as the first script in the \`\` section as seen in the example. The script loads directly from Shopify and keeps itself up-to-date. + `, + codeblock: { + title: 'Hosted chat application', + tabs: [ + { + code: './examples/include-app-bridge.example.html', + language: 'html', + }, + ], + }, + }, + { + type: 'Generic', + anchorLink: 'global-variable', + title: 'App Bridge\u2019s global variable', + sectionContent: ` +After App Bridge is set up in your app, you have access to the \`shopify\` global variable. This variable exposes various App Bridge functionalities, such as resizing the iframe or retrieving details of the shop. + +The [reference](#app%20bridge%20for%20checkout) above list all the available methods and properties. + +Alternatively, to explore all the functionality available on the \`shopify\` global variable: + +* Open the Chrome developer console while in checkout. +* Switch the frame context to your app's iframe. +* Enter \`shopify\` in the console. +`, + codeblock: { + title: 'shopify', + tabs: [ + { + title: 'config', + code: './examples/app-bridge-shopify-config.example.js', + language: 'js', + }, + ], + }, + }, + { + type: 'Generic', + anchorLink: 'app-bridge-css-api', + title: 'App Bridge\u2019s CSS API', + sectionContent: ` +Since the Chat iframe is clipped and fills the whole window as seen in the previous section, using percentage based sizes for its UI elements will most likely resolves in clipped content. As mentioned in the UX guidelines, Chat is constraint to specific [maximum sizes on large and small screens](/docs/apps/build/checkout/chat/ux-for-chat#build-within-the-chat-component-dimensions) set by Shopify. Setting a 100% width on an element will not be constraint to the visible size of the iframe, but to the whole window. + +To remediate this issue, through App Bridge we offer a set of [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) with all the maximum dimensions defined in our UX guidelines. You can use these custom properties whether in Javascript or in the CSS of you application to set protections against overflowing content while using percentage based sizes. Using these properties will also reduce regressions if Shopify ever changes the maximum dimensions. +`, + codeblock: { + title: 'App Bridge CSS API', + tabs: [ + { + title: 'Custom properties', + code: './examples/app-bridge-css.example.css', + language: 'css', + }, + { + title: 'style.css', + code: './examples/chat-custom-properties-css.example.css', + language: 'css', + }, + ], + }, + }, + ], + examples: { + description: '', + examples: [ + { + description: + 'A very common action in your application will be to request a resize of the iframe. This is done through the App Bridge `resizeTo()` method. The following example resizes the iframe following the click of an activator button to show a dialog window.', + codeblock: { + title: 'Resize the Chat iframe from the hosted application', + tabs: [ + { + title: 'UI Extension', + code: './examples/app-bridge-resize.example.tsx', + language: 'tsx', + }, + { + title: 'Hosted chat application', + code: './examples/app-bridge-resize.example.html', + language: 'html', + }, + ], + }, + }, + { + description: ` +Information can be passed between the hosted application and the UI extension through App Bridge. [Extensions API](/docs/api/customer-account-ui-extensions/unstable#extension-apis) are available in the UI extension and can be shared through that method. + `, + codeblock: { + title: + 'Communicate information between the hosted application and the UI extension', + tabs: [ + { + title: 'UI Extension', + code: './examples/app-bridge-communication.example.tsx', + language: 'tsx', + }, + { + title: 'Hosted chat application', + code: './examples/app-bridge-communication.example.js', + language: 'js', + }, + ], + }, + }, + ], + }, + + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.js b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.js new file mode 100644 index 0000000000..8451403216 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.js @@ -0,0 +1,18 @@ +// Create a variable to store the buyer's first name. +// We'll be able to use this to personalize the chat experience. +let buyerFirstName; + +// In the hosted application Javascript, listen for messages from the UI extension. +shopify.extension.port.onmessage = async (event) => { + // if the message's data has a ping action, respond with a pong + if (event.data.action === 'ping') { + buyerFirstName = event.data.buyer.firstName; + + await shopify.extension.port.postMessage({ + action: 'pong', + }); + } +}; + +// Ensure the messagePort is ready to start sending and receiving messages. +shopify.extension.port.start(); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.tsx new file mode 100644 index 0000000000..ac1b154899 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-communication.example.tsx @@ -0,0 +1,34 @@ +import { + reactExtension, + Chat, +} from '@shopify/ui-extensions-react/customer-account'; +import {retain} from '@remote-ui/rpc'; +import type {ReadyEvent} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension('customer-account.page.render', () => ( + +)); + +function Extension() { + let postMessage; + + return ( + { + postMessage = postMessageParam; + retain(postMessage); + + postMessage({ + action: 'ping', + }); + }} + onMessage={(event: Event) => { + if (event.data.action === 'pong') { + console.log('Messaging channel successful'); + } + }} + /> + ); +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-css.example.css b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-css.example.css new file mode 100644 index 0000000000..3a1d2c3064 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-css.example.css @@ -0,0 +1,16 @@ +:root { + --shopify-checkout-chat-minimized-max-inline-size: 224px; + --shopify-checkout-chat-minimized-max-block-size: 72px; + --shopify-checkout-chat-maximized-max-inline-size: 415px; + --shopify-checkout-chat-maximized-max-block-size: 700px; + + @media screen and (max-width: 569px) { + --shopify-checkout-chat-maximized-max-inline-size: 100dvi; + --shopify-checkout-chat-maximized-max-block-size: 93dvb; + + @supports not (inline-size: 100dvi) { + --shopify-checkout-chat-maximized-max-inline-size: 100vi; + --shopify-checkout-chat-maximized-max-block-size: 93vb; + } + } +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.html b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.html new file mode 100644 index 0000000000..34b5cfe1de --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.html @@ -0,0 +1,48 @@ + + + + + + + + + How can we help you today? + + + + + + + diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.tsx new file mode 100644 index 0000000000..4c64b9c6a3 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-resize.example.tsx @@ -0,0 +1,9 @@ +import {reactExtension, Chat} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension('customer-account.page.render', () => ( + +)); + +function Extension() { + return ; +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-shopify-config.example.js b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-shopify-config.example.js new file mode 100644 index 0000000000..54096e0254 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/app-bridge-shopify-config.example.js @@ -0,0 +1,2 @@ +shopify.config.locale; +// => 'en-CA' diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.ts new file mode 100644 index 0000000000..6fea923fa9 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/basic-chat.example.ts @@ -0,0 +1,13 @@ +import {extension, Chat} from '@shopify/ui-extensions/customer-account'; + +// This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file. +// Its value will be used as the `src` attribute of the Chat component. + +export default extension('customer-account.page.render', (root) => { + const chat = root.createComponent(Chat, { + inlineSize: 100, + blockSize: 50, + }); + + root.appendChild(chat); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/chat-custom-properties-css.example.css b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/chat-custom-properties-css.example.css new file mode 100644 index 0000000000..20e873a61c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/chat-custom-properties-css.example.css @@ -0,0 +1,9 @@ +.activator { + inline-size: 100%; + max-inline-size: var(--shopify-checkout-chat-minimized-max-inline-size); +} + +.dialog { + inline-size: 100%; + max-inline-size: var(--shopify-checkout-chat-maximized-max-inline-size); +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/include-app-bridge.example.html b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/include-app-bridge.example.html new file mode 100644 index 0000000000..ca6f00eb3b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/include-app-bridge.example.html @@ -0,0 +1,3 @@ + + + diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/shopify-extension-toml.example.toml b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/shopify-extension-toml.example.toml new file mode 100644 index 0000000000..7760a9a1c6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Chat/examples/shopify-extension-toml.example.toml @@ -0,0 +1,5 @@ +[[extensions.targeting]] +target = "purchase.checkout.chat.render" + + [extensions.targeting.preloads] + chat = "https://my-chat-application.com" diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/Checkbox.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/Checkbox.doc.ts new file mode 100644 index 0000000000..1b2ab25b8b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/Checkbox.doc.ts @@ -0,0 +1,49 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const checkboxLinks = getExample('ui-components/checkbox-links', ['jsx', 'js']); + +const data: ReferenceEntityTemplateSchema = { + name: 'Checkbox', + description: + 'Use checkboxes to give customers a single binary option, such as signing up for marketing, or agreeing to terms and conditions.', + thumbnail: 'checkbox-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'CheckboxProps', + description: '', + type: 'CheckboxProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'checkbox-default.png', + codeblock: { + title: 'Basic Checkbox', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-checkbox.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [checkboxLinks], + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.ts new file mode 100644 index 0000000000..748708c209 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Checkbox/examples/basic-checkbox.example.ts @@ -0,0 +1,11 @@ +import {extension, Checkbox} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const checkbox = root.createComponent( + Checkbox, + {id: 'checkbox', name: 'checkbox'}, + 'Save this information for next time', + ); + + root.appendChild(checkbox); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Choice/Choice.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Choice/Choice.doc.ts new file mode 100644 index 0000000000..d72e6e27d2 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Choice/Choice.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Choice', + description: + 'Options inside a `ChoiceList`.\n\nThe wrapping `ChoiceList` component will dictate if the choice renders as radio buttons or checkboxes.', + thumbnail: 'choice-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ChoiceProps', + description: '', + type: 'ChoiceProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'choice-default.png', + codeblock: { + title: 'Basic Choice', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-choice.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Include a title that either tells customers what to do or explains their available options.\n\n- Label options clearly based on what the option will do.\n\n- Avoid options that contradict each other when you’re allowing for multiple selections.', + }, + ], + related: [ + { + name: 'ChoiceList', + subtitle: 'Component', + url: 'choicelist', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.ts new file mode 100644 index 0000000000..0b0fe19fb6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Choice/examples/basic-choice.example.ts @@ -0,0 +1,39 @@ +import { + extension, + ChoiceList, + Choice, + InlineStack, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const choiceList = root.createComponent( + ChoiceList, + { + name: 'ship', + value: 'ship-1', + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [root.createComponent(Choice, {id: 'ship-1'}, 'Ship')], + ); + + const multipleChoiceList = root.createComponent( + ChoiceList, + { + name: 'gift', + value: ['gift-1'], + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [root.createComponent(Choice, {id: 'gift-1'}, 'Gift message')], + ); + + const layout = root.createComponent(InlineStack, undefined, [ + choiceList, + multipleChoiceList, + ]); + + root.appendChild(layout); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/ChoiceList.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/ChoiceList.doc.ts new file mode 100644 index 0000000000..bbb6e3324f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/ChoiceList.doc.ts @@ -0,0 +1,103 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ChoiceList', + description: + 'Use choice lists to present a list of choices where buyers can make a single selection or multiple selections.', + thumbnail: 'choicelist-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ChoiceListProps', + description: '', + type: 'ChoiceListProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'choicelist-default.png', + codeblock: { + title: 'Basic ChoiceList', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-choicelist.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: '', + sectionSubContent: [ + { + title: 'Content', + sectionContent: `- Include a title that either tells customers what to do or explains their available options.\n\n- Label options clearly based on what the option will do.\n\n- Avoid options that contradict each other when you’re allowing for multiple selections.`, + }, + { + title: 'Types of choices', + sectionContent: + "![A screenshot of two examples for base and group variants](/assets/landing-pages/templated-apis/checkout-ui-extensions/ui-components/choicelist-bp-choicetypes.png)\n- The `base` variant is suitable for straightforward options, such as binary choices like 'yes' or 'no' answers. For simple options that require minimal visual emphasis, the base variant is the recommended choice.\n- The `group` variant provides increased emphasis on choices through the use of colors, borders, and dividers. If the goal is to draw attention to the available options, the group variant is the ideal choice.", + }, + { + title: 'Flexibility vs. cohesive experience', + sectionContent: + '- The `base` variant offers the flexibility to compose ChoiceLists with custom layouts, allowing for greater design composition possibilities.\n- Given the high level of flexibility offered by the `base` variant, prioritizing accessibility in the implementation is crucial. It is recommended to avoid using buttons or pressable components within the choices.\n- The `group` variant adheres to a defined structure and provides excellent adaptability to align with the merchant’s brand. It is the ideal choice when strong cohesion with the merchant’s branding is required. Additionally, depending on the placement of the `ChoiceList`, Checkout will automatically update its appearance to seamlessly adapt to the surface it is on.', + }, + { + title: 'Using details', + sectionContent: + '![A screenshot of an example of using details](/assets/landing-pages/templated-apis/checkout-ui-extensions/ui-components/choicelist-bp-details.png)\n- The `details` area should be used only when additional input is required from the customer, specifically related to the choice they have made.\n- If the `details` area contains lengthy content, consider placing it outside of the `ChoiceList` to ensure that customers can easily digest the information.', + }, + { + title: 'Long lists of options', + sectionContent: + '- When faced with a considerable number of options, customers may feel overwhelmed, and it can consume valuable interface space. To address this, consider utilizing components like the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component to condense options, or employ the [Disclosure](/docs/api/checkout-ui-extensions/components/interactive/disclosure) component to progressively reveal more choices upon customer request. Strategies such as paging, filtering, and searching can be employed to enhance usability.', + }, + { + title: 'Clickable rows', + sectionContent: + '- If an entire row needs to be clickable, utilize the `group` variant, as it is specifically designed to enable clickable rows. In this scenario, the base variant may not provide the desired functionality, as only its content elements can be clicked, not the entire row. Attempting to use buttons or pressables to make an entire row clickable could lead to accessibility issues.', + }, + ], + }, + ], + examples: { + description: '', + examples: [ + getExample('ui-components/choicelist-survey', ['jsx', 'js']), + getExample('ui-components/choicelist-details', ['jsx', 'js']), + getExample('ui-components/choicelist-time-picking', ['jsx', 'js']), + ], + }, + related: [ + { + name: 'Choice', + subtitle: 'Component', + url: 'choice', + type: 'Component', + }, + { + name: 'Checkbox', + subtitle: 'Component', + url: 'checkbox', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.ts new file mode 100644 index 0000000000..995b1f0957 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ChoiceList/examples/basic-choicelist.example.ts @@ -0,0 +1,81 @@ +import { + extension, + InlineStack, + ChoiceList, + Choice, + BlockStack, + Icon, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const inlineStack = root.createComponent(InlineStack, undefined, [ + root.createComponent( + ChoiceList, + { + name: 'group-single', + variant: 'group', + value: 'ship', + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [ + root.createComponent( + Choice, + { + secondaryContent: root.createComponent(Icon, {source: 'truck'}), + id: 'ship', + }, + 'Ship', + ), + root.createComponent( + Choice, + { + secondaryContent: root.createComponent(Icon, {source: 'marker'}), + id: 'ship-to-pickup-point', + }, + 'Ship to pickup point', + ), + root.createComponent( + Choice, + { + secondaryContent: root.createComponent(Icon, {source: 'store'}), + id: 'pick-up', + }, + 'Pick up in store', + ), + ], + ), + root.createComponent( + ChoiceList, + { + name: 'base-multiple', + value: ['remember-me'], + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [ + root.createComponent(BlockStack, undefined, [ + root.createComponent( + Choice, + {id: 'remember-me'}, + 'Save this information for next time', + ), + root.createComponent( + Choice, + {id: 'email-me'}, + 'Email me with news and offers', + ), + root.createComponent( + Choice, + {id: 'text-me'}, + 'Text me with news and offers', + ), + ]), + ], + ), + ]); + + root.appendChild(inlineStack); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/ClipboardItem.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/ClipboardItem.doc.ts new file mode 100644 index 0000000000..41d5be8d68 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/ClipboardItem.doc.ts @@ -0,0 +1,75 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ClipboardItem', + description: + 'Enables clipboard functionality when its `id` is referenced by the `activateTarget` property of a `Button`, `Pressable`, or `Link` component. When activated, it copies the text to the clipboard and displays a `Tooltip` confirmation. \n\n `ClipboardItem` is a non-rendering component.', + requires: '', + isVisualComponent: true, + thumbnail: 'clipboard-basic.png', + type: '', + definitions: [ + { + title: 'ClipboardItemProps', + description: '', + type: 'ClipboardItemProps', + }, + ], + category: 'UI components', + subCategory: 'Actions', + defaultExample: { + image: 'clipboard-basic.png', + codeblock: { + title: 'Basic Copy to Clipboard', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-clipboarditem.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [ + getExample('ui-components/clipboarditem-qrcode', ['jsx', 'js']), + getExample('ui-components/clipboarditem-oncopy', ['jsx', 'js']), + ], + }, + related: [ + { + name: 'Button', + subtitle: 'Component', + url: 'button', + type: 'Component', + }, + { + name: 'Pressable', + subtitle: 'Component', + url: 'pressable', + type: 'Component', + }, + { + name: 'Link', + subtitle: 'Component', + url: 'link', + type: 'Component', + }, + { + name: 'QR Code', + subtitle: 'Component', + url: 'qrcode', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.ts new file mode 100644 index 0000000000..3c19ca0ea6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ClipboardItem/examples/basic-clipboarditem.example.ts @@ -0,0 +1,21 @@ +import { + extension, + ClipboardItem, + Button, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const button = root.createComponent( + Button, + { + activateTarget: 'discount-code', + }, + 'Copy discount code', + ); + const clipboardItem = root.createComponent(ClipboardItem, { + text: 'SAVE 25', + id: 'discount-code', + }); + root.appendChild(button); + root.appendChild(clipboardItem); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/ConsentCheckbox.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/ConsentCheckbox.doc.ts new file mode 100644 index 0000000000..206ca7e8fb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/ConsentCheckbox.doc.ts @@ -0,0 +1,72 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ConsentCheckbox', + description: + "Use buyer consent checkboxes for collecting the buyer's approval for a given policy.", + thumbnail: 'consent-checkbox-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ConsentCheckboxProps', + description: '', + type: 'ConsentCheckboxProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'consent-checkbox-default.png', + codeblock: { + title: 'Basic ConsentCheckbox', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-consent-checkbox.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: + "Use buyer consent checkboxes in conjunction with buyer consent phone fields for collecting the buyer's approval for a given policy.\n\nThe consent phone field is not required in order to use the consent checkbox component. This example demonstrates how they can be used together.", + examples: [ + { + image: 'consent-combo-example.png', + codeblock: { + title: 'ConsentCheckbox with ConsentPhoneField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/with-consent-phone-field-consent-checkbox.example.ts', + language: 'js', + }, + ], + }, + }, + ], + }, + related: [ + { + name: 'ConsentCheckbox', + subtitle: 'Component', + url: 'consent-checkbox', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.ts new file mode 100644 index 0000000000..64fc9b5cc7 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/basic-consent-checkbox.example.ts @@ -0,0 +1,11 @@ +import {extension, ConsentCheckbox} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const consentCheckbox = root.createComponent( + ConsentCheckbox, + {policy: 'sms-marketing'}, + 'Text me with news and promotions', + ); + + root.appendChild(consentCheckbox); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.ts new file mode 100644 index 0000000000..cbf8bedc4f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentCheckbox/examples/with-consent-phone-field-consent-checkbox.example.ts @@ -0,0 +1,43 @@ +import { + extension, + BlockStack, + ConsentCheckbox, + ConsentPhoneField, + InlineStack, + InlineSpacer, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const consentCheckbox = root.createComponent( + ConsentCheckbox, + { + policy: 'sms-marketing', + }, + 'Text me with news and offers', + ); + + const inlineSpacer = root.createComponent(InlineSpacer, { + spacing: 'extraTight', + }); + + const consentPhoneField = root.createComponent(ConsentPhoneField, { + label: 'Phone', + policy: 'sms-marketing', + }); + + const inlineStack = root.createComponent( + InlineStack, + { + inlineAlignment: 'start', + padding: ['none', 'none', 'none', 'tight'], + }, + [inlineSpacer, consentPhoneField], + ); + + const layout = root.createComponent(BlockStack, undefined, [ + consentCheckbox, + inlineStack, + ]); + + root.appendChild(layout); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/ConsentPhoneField.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/ConsentPhoneField.doc.ts new file mode 100644 index 0000000000..1ff432afcb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/ConsentPhoneField.doc.ts @@ -0,0 +1,72 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ConsentPhoneField', + description: + 'Display a phone field for customers to sign up for text message marketing, noting that the phone field value will be automatically saved during checkout.', + thumbnail: 'consent-phonefield-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ConsentPhoneFieldProps', + description: '', + type: 'ConsentPhoneFieldProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'consent-phonefield-default.png', + codeblock: { + title: 'Basic ConsentPhoneField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-consent-phone-field.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: + "Use buyer consent phone fields in conjunction with buyer consent checkboxes for collecting the buyer's approval for a given policy.\n\nThe consent phone field component is not required in order to use the consent checkbox component. This example demonstrates how they can be used together.", + examples: [ + { + image: 'consent-combo-example.png', + codeblock: { + title: 'ConsentCheckbox with ConsentPhoneField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/with-consent-checkbox-consent-phone-field.example.ts', + language: 'js', + }, + ], + }, + }, + ], + }, + related: [ + { + name: 'ConsentCheckbox', + subtitle: 'Component', + url: 'consent-checkbox', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.ts new file mode 100644 index 0000000000..e4c048fd1e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/basic-consent-phone-field.example.ts @@ -0,0 +1,10 @@ +import {extension, ConsentPhoneField} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const consentPhoneField = root.createComponent(ConsentPhoneField, { + label: 'Phone', + policy: 'sms-marketing', + }); + + root.appendChild(consentPhoneField); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.ts new file mode 100644 index 0000000000..cbf8bedc4f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ConsentPhoneField/examples/with-consent-checkbox-consent-phone-field.example.ts @@ -0,0 +1,43 @@ +import { + extension, + BlockStack, + ConsentCheckbox, + ConsentPhoneField, + InlineStack, + InlineSpacer, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const consentCheckbox = root.createComponent( + ConsentCheckbox, + { + policy: 'sms-marketing', + }, + 'Text me with news and offers', + ); + + const inlineSpacer = root.createComponent(InlineSpacer, { + spacing: 'extraTight', + }); + + const consentPhoneField = root.createComponent(ConsentPhoneField, { + label: 'Phone', + policy: 'sms-marketing', + }); + + const inlineStack = root.createComponent( + InlineStack, + { + inlineAlignment: 'start', + padding: ['none', 'none', 'none', 'tight'], + }, + [inlineSpacer, consentPhoneField], + ); + + const layout = root.createComponent(BlockStack, undefined, [ + consentCheckbox, + inlineStack, + ]); + + root.appendChild(layout); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.doc.ts index 0737874823..3df8e78ccc 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/CustomerAccountAction/CustomerAccountAction.doc.ts @@ -27,7 +27,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'Docs_CustomerAccountAction_Button_SecondaryAction', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Actions', defaultExample: { image: 'customeraccountaction-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DateField/DateField.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DateField/DateField.doc.ts new file mode 100644 index 0000000000..8756e97043 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DateField/DateField.doc.ts @@ -0,0 +1,49 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'DateField', + description: 'Use a date field to get a date input from a customer.', + thumbnail: 'datefield-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'DateFieldProps', + description: '', + type: 'DateFieldProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'datefield-default.png', + codeblock: { + title: 'Basic DateField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-datefield.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use clear and concise labels for the DateField component to help customers understand what information is expected.\n\n**When to use a DateField**\n\n- Use when the dates are memorable to the customer.\n\n- Use when all dates are available to be chosen by the customer.\n\n**When not to use a DateField**\n\n- Don’t use when customers require a visual representation of the dates, rather than manual entry, consider using a DatePicker component instead.\n\n- Don’t use when date availability logic is in place. Customers may find it difficult to determine which dates are available if they’re typing. Use a DatePicker instead.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.ts new file mode 100644 index 0000000000..7a5fb92ac6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DateField/examples/basic-datefield.example.ts @@ -0,0 +1,9 @@ +import {extension, DateField} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const datefield = root.createComponent(DateField, { + label: 'Select a date', + }); + + root.appendChild(datefield); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/DatePicker.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/DatePicker.doc.ts new file mode 100644 index 0000000000..7918018814 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/DatePicker.doc.ts @@ -0,0 +1,50 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'DatePicker', + description: + 'The DatePicker component is a calendar picker UI that allows users to select a single date or a date range', + thumbnail: 'datepicker-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'DatePickerProps', + description: '', + type: 'DatePickerProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'datepicker-default.png', + codeblock: { + title: 'Basic DatePicker', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-datepicker.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + 'By adhering to these design guidelines, the DatePicker component can offer a seamless and efficient method for users to select dates, thereby enhancing the overall user experience.\n\n- Default to showing today’s date if available.\n\n- Display the first available date when selecting future dates.\n\n- To minimize errors, the process of selecting a date range may require multiple steps. Therefore, providing a way for users to explicitly confirm their selection is recommended.\n\n**When to use a DatePicker**\n\nThe DatePicker component is well-suited for the following scenarios:\n\n- Specifying shipping or delivery dates\n\n- Scheduling pick-up dates\n\n- Booking dates for service providers\n\n- Selecting event dates for ticket offerings\n\n- Specifying rental dates to determine start and end dates for renting a product\n\n**When not to use a DatePicker component**\n\nA DatePicker component might not be the most appropriate choice in the following situations:\n\n- When the date to be entered is several years in the future or the past.\n\n- When the date is easily memorable and can be quickly typed using the keyboard e.g. Date of birth.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.ts new file mode 100644 index 0000000000..1be0201dcc --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DatePicker/examples/basic-datepicker.example.ts @@ -0,0 +1,9 @@ +import {extension, DatePicker} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const datepicker = root.createComponent(DatePicker, { + selected: '2021-06-01', + }); + + root.appendChild(datepicker); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/Disclosure.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/Disclosure.doc.ts new file mode 100644 index 0000000000..e00d17bd50 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/Disclosure.doc.ts @@ -0,0 +1,61 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const disclosureAndAlignment = getExample( + 'ui-components/disclosure-and-alignment', + ['jsx', 'js'], +); + +const data: ReferenceEntityTemplateSchema = { + name: 'Disclosure', + description: + 'Disclosure is an optionally controlled component used to put long sections of information under content blocks that users can expand or collapse by pressing an activator. The activator can be specified as children using an action component (`Button`, `Link` or `Pressable`) or a form control (`Checkbox` or `Switch`) component. The content blocks can be specified as children inside a structure component (`View`, `InlineLayout`, `BlockStack`, `Grid`, etc.).\n\nThe library automatically applies the [WAI-ARIA Accordion pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/) to both the activator and the toggled content.', + thumbnail: 'disclosure-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'DisclosureProps', + description: '', + type: 'DisclosureProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'disclosure-default.png', + codeblock: { + title: 'Basic Disclosure', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-disclosure.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [disclosureAndAlignment], + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Disclosures should be initiated by the buyer.\n\n- Use disclosures to hide content until they are relevant to the buyer.\n\n- Avoid hiding critical information that buyers need to complete their checkout.\n\n- Keep content inside disclosures concise.\n\n- Avoid nesting of disclosures.\n\n- Keep the activator and the content it toggles in close proximity to each other.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.ts new file mode 100644 index 0000000000..c43f82c704 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Disclosure/examples/basic-disclosure.example.ts @@ -0,0 +1,19 @@ +import { + extension, + Button, + View, + Disclosure, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const disclosure = root.createComponent(Disclosure, {}, [ + root.createComponent(Button, {toggles: 'one'}, 'Toggle'), + root.createComponent( + View, + {border: 'base', padding: 'base', id: 'one'}, + 'Content', + ), + ]); + + root.appendChild(disclosure); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Divider/Divider.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Divider/Divider.doc.ts new file mode 100644 index 0000000000..cd881f23f3 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Divider/Divider.doc.ts @@ -0,0 +1,41 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Divider', + description: + 'A divider separates content and represents a thematic break between elements.', + thumbnail: 'divider-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'DividerProps', + description: '', + type: 'DividerProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'divider-default.png', + codeblock: { + title: 'Basic Divider', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-divider.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.ts new file mode 100644 index 0000000000..3aa02a41a4 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Divider/examples/basic-divider.example.ts @@ -0,0 +1,7 @@ +import {extension, Divider} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const divider = root.createComponent(Divider); + + root.appendChild(divider); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/DropZone.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/DropZone.doc.ts new file mode 100644 index 0000000000..2f9e9edbbc --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/DropZone.doc.ts @@ -0,0 +1,68 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'DropZone', + description: `DropZone allows file uploads through drag-and-drop functionality into a designated area on a page, or by activating a button. At present, DropZone does not offer image upload preview capabilities. The use of object URLs directly in an image component is not possible due to the extension and host operating on separate domains. + \n Any element focused within the Dropzone component, including child elements such as the 'Add file' button, will initiate the file selector when the Enter or Spacebar key is pressed. + `, + thumbnail: 'dropzone-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'DropZoneProps', + description: '', + type: 'DropZoneProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'dropzone-preview.png', + altText: + 'An image showcasing the DropZone component with a button to add files with error and dragged over states.', + codeblock: { + title: 'DropZone', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-react.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-DropZone-js.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: ` +### File storage + +File storage for uploads must be implemented separately. Metafields and the corresponding [Checkout API](https://shopify.dev/docs/api/checkout-ui-extensions/latest/apis/metafields) or [Customer Accounts API](https://shopify.dev/docs/api/customer/latest/mutations/metafieldsSet) can be utilized to store references to files alongside the relevant objects. + +### Mobile + +Remember that the drag and drop feature won’t be effective on mobile devices. Adding a button can offer additional context and guide users through the next steps. + +An example showing DropZone with custom content optimized for mobile devices + +### Minimum size + +To prevent cut-off text and spacing issues, the minimum size of a Dropzone should be 100px by 100px. + +An example showing DropZone with correct minimum size + `, + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-js.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-js.example.ts new file mode 100644 index 0000000000..9a0d33c63e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/DropZone/examples/basic-DropZone-js.example.ts @@ -0,0 +1,9 @@ +import {DropZone, extension} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const dropZone = root.createComponent(DropZone, { + accept: 'image/*', + }); + + root.appendChild(dropZone); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Form/Form.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Form/Form.doc.ts new file mode 100644 index 0000000000..549dbe6c2b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Form/Form.doc.ts @@ -0,0 +1,50 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Form', + description: + 'The form component should be used to wrap one or more form controls. This component provides an "implicit submit" behavior, where customers can submit the form from any input by pressing "Enter" on their keyboards. This behavior is widely expected, and should be respected as often as possible.\n\nUnlike an HTML `form` element, this component does not support configuring the descendant fields to be submitted via HTTP automatically. Instead, you must provide an `onSubmit` callback that will perform the necessary HTTP requests in JavaScript.', + thumbnail: 'form-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'FormProps', + description: '', + type: 'FormProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'form-default.png', + codeblock: { + title: 'Basic Form', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Form/examples/basic-form.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-form.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Wrap around all form input elements.\n\n- Forms can have only one submit button and it must be at the end of the form.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Form/examples/basic-form.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Form/examples/basic-form.example.ts new file mode 100644 index 0000000000..15a53c7c99 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Form/examples/basic-form.example.ts @@ -0,0 +1,48 @@ +import { + extension, + BlockSpacer, + Button, + Form, + Grid, + GridItem, + TextField, + View, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const fields = root.createComponent( + Grid, + {columns: ['50%', '50%'], spacing: 'base'}, + [ + root.createComponent( + View, + undefined, + root.createComponent(TextField, {label: 'First name'}), + ), + root.createComponent( + View, + undefined, + root.createComponent(TextField, {label: 'Last name'}), + ), + root.createComponent( + GridItem, + {columnSpan: 2}, + root.createComponent(TextField, {label: 'Company'}), + ), + ], + ); + const spacer = root.createComponent(BlockSpacer, {spacing: 'base'}); + const button = root.createComponent( + Button, + {accessibilityRole: 'submit'}, + 'Submit', + ); + + const form = root.createComponent( + Form, + {onSubmit: () => console.log('onSubmit event')}, + [fields, spacer, button], + ); + + root.appendChild(form); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Grid/Grid.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Grid/Grid.doc.ts new file mode 100644 index 0000000000..0cb43e6b12 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Grid/Grid.doc.ts @@ -0,0 +1,63 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Grid', + description: + 'Grid is used to lay out content in a matrix of rows and columns.', + thumbnail: 'grid-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'GridProps', + description: '', + type: 'GridProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'grid-default.png', + codeblock: { + title: 'Basic Grid', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-grid.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + name: 'GridItem', + subtitle: 'Component', + url: 'grid', + type: 'Component', + }, + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.ts new file mode 100644 index 0000000000..90425a8b0c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Grid/examples/basic-grid.example.ts @@ -0,0 +1,45 @@ +import {extension, Grid, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const grid = root.createComponent( + Grid, + { + columns: ['20%', 'fill', 'auto'], + rows: [300, 'auto'], + }, + [ + root.createComponent( + View, + {border: 'base', padding: 'base'}, + '20% / 300', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'fill / 300', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'auto / 300', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + '20% / auto', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'fill / auto', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'auto / auto', + ), + ], + ); + + root.appendChild(grid); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/GridItem.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/GridItem.doc.ts new file mode 100644 index 0000000000..d72271df6e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/GridItem.doc.ts @@ -0,0 +1,63 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'GridItem', + description: + 'GridItem can be used as children of Grid.\n\nIt offers a way to span the element across a number of columns and rows.', + thumbnail: 'griditem-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'GridItemProps', + description: '', + type: 'GridItemProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'griditem-default.png', + codeblock: { + title: 'Basic GridItem', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-griditem.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + name: 'Grid', + subtitle: 'Component', + url: 'grid', + type: 'Component', + }, + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.ts new file mode 100644 index 0000000000..25e49ca0b4 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/GridItem/examples/basic-griditem.example.ts @@ -0,0 +1,42 @@ +import {extension, Grid, GridItem, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const grid = root.createComponent( + Grid, + { + columns: ['20%', 'fill', 'auto'], + rows: [300, 'auto'], + }, + [ + root.createComponent( + View, + {border: 'base', padding: 'base'}, + '20% / 300', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'fill / 300', + ), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'auto / 300', + ), + root.createComponent(GridItem, {columnSpan: 2}, [ + root.createComponent( + View, + {border: 'base', padding: 'base'}, + '20% + fill / auto', + ), + ]), + root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'auto / auto', + ), + ], + ); + + root.appendChild(grid); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Heading/Heading.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Heading/Heading.doc.ts new file mode 100644 index 0000000000..74475a799f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Heading/Heading.doc.ts @@ -0,0 +1,69 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Heading', + description: + 'Headings control the visual style of headings. Use headings to introduce major sections, like Contact information, Shipping address, or Shipping method.\n\nUnlike HTML headings, you don’t explicitly specify the position of the heading in the document outline. Nest headings within the heading group component to control the document outline structure used by assistive technologies.', + thumbnail: 'heading-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'HeadingProps', + description: '', + type: 'HeadingProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'heading-default.png', + codeblock: { + title: 'Basic Heading', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-heading.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Add a heading at the top of each section that clearly describe what’s below.\n\n- Use the heading to highlight the most important concepts or pieces of information that customers need to know.', + }, + ], + related: [ + { + name: 'HeadingGroup', + subtitle: 'Component', + url: 'headinggroup', + type: 'Component', + }, + { + name: 'Text', + subtitle: 'Component', + url: 'text', + type: 'Component', + }, + { + name: 'TextBlock', + subtitle: 'Component', + url: 'textblock', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.ts new file mode 100644 index 0000000000..1fc7da6afc --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Heading/examples/basic-heading.example.ts @@ -0,0 +1,7 @@ +import {extension, Heading} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const heading = root.createComponent(Heading, undefined, 'Store name'); + + root.appendChild(heading); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/HeadingGroup.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/HeadingGroup.doc.ts new file mode 100644 index 0000000000..9e5976c19c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/HeadingGroup.doc.ts @@ -0,0 +1,63 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'HeadingGroup', + description: + 'Heading group controls the heading level of headings nested within it, like H1, H2, H3.\n\nUse a heading group whenever you use a heading to ensure the experience is the same for screen reader users. When using a heading, any children related to that heading should be nested within the same heading group.', + thumbnail: 'headinggroup-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'headinggroup-default.png', + codeblock: { + title: 'Basic HeadingGroup', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-headinggroup.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use this component to create a content hierarchy within the document outline.', + }, + ], + related: [ + { + name: 'Heading', + subtitle: 'Component', + url: 'heading', + type: 'Component', + }, + { + name: 'Text', + subtitle: 'Component', + url: 'text', + type: 'Component', + }, + { + name: 'TextBlock', + subtitle: 'Component', + url: 'textblock', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.ts new file mode 100644 index 0000000000..d36be5ec4f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/HeadingGroup/examples/basic-headinggroup.example.ts @@ -0,0 +1,20 @@ +import { + extension, + HeadingGroup, + Heading, + View, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const headingGroup = root.createComponent(View, undefined, [ + root.createComponent(Heading, undefined, 'Heading

    '), + root.createComponent(HeadingGroup, undefined, [ + root.createComponent(Heading, undefined, 'Heading

    '), + root.createComponent(HeadingGroup, undefined, [ + root.createComponent(Heading, undefined, 'Heading

    '), + ]), + ]), + ]); + + root.appendChild(headingGroup); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Icon/Icon.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Icon/Icon.doc.ts new file mode 100644 index 0000000000..1cceef7eb7 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Icon/Icon.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Icon', + description: + 'Icons are pictograms or graphic symbols. They can act as wayfinding tools or as a means of communicating functionality.', + thumbnail: 'icon-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'IconProps', + description: '', + type: 'IconProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'icon-default.png', + codeblock: { + title: 'Basic Icon', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-icon.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'icons', + title: 'Icons', + sectionContent: + '', + }, + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "accent" | Conveys emphasis and draws attention to the element. |\n| "interactive" | Conveys that the element is pressable, hoverable or otherwise interactive. |\n| "subdued" | Conveys a subdued or disabled state for the element. |\n| "info" | Conveys that the element is informative or has information. |\n| "success" | Convey a successful interaction. |\n| "warning" | Convey something needs attention or an action needs to be taken. |\n| "critical" | Conveys a problem has arisen. |\n| "monochrome" | Takes the color of its parent.|', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.ts new file mode 100644 index 0000000000..9330733970 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Icon/examples/basic-icon.example.ts @@ -0,0 +1,7 @@ +import {extension, Icon} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const icon = root.createComponent(Icon, {source: 'discount'}); + + root.appendChild(icon); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Image/Image.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Image/Image.doc.ts new file mode 100644 index 0000000000..f1ee095ebd --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Image/Image.doc.ts @@ -0,0 +1,49 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Image', + description: 'Image is used for large format, responsive images.', + thumbnail: 'image-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ImageProps', + description: '', + type: 'ImageProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'image-default.png', + codeblock: { + title: 'Basic Image', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Image/examples/basic-image.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-image.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'loading', + title: 'Loading', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "eager" | Image is loaded immediately, regardless of whether or not the image is currently within the visible viewport. |\n| "lazy" | Image is loaded when it’s within the visible viewport. |', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Image/examples/basic-image.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Image/examples/basic-image.example.ts new file mode 100644 index 0000000000..515747665a --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Image/examples/basic-image.example.ts @@ -0,0 +1,9 @@ +import {extension, Image} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const image = root.createComponent(Image, { + source: 'https://cdn.shopify.com/YOUR_IMAGE_HERE', + }); + + root.appendChild(image); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ImageGroup/ImageGroup.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ImageGroup/ImageGroup.doc.ts index 61ec3b877c..73ea208b69 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/ImageGroup/ImageGroup.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ImageGroup/ImageGroup.doc.ts @@ -15,7 +15,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'ImageGroupProps', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Media and visuals', defaultExample: { image: 'imagegroup-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/InlineLayout.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/InlineLayout.doc.ts new file mode 100644 index 0000000000..411908fccf --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/InlineLayout.doc.ts @@ -0,0 +1,68 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const disclosureAndAlignment = getExample( + 'ui-components/disclosure-and-alignment', + ['jsx', 'js'], +); + +const data: ReferenceEntityTemplateSchema = { + name: 'InlineLayout', + description: + 'InlineLayout is used to lay out content over multiple columns.\n\nBy default, all columns are of equal size and fill the available inline space. Content does not wrap on new rows when not enough columns have been explicitly set, instead they are added as new column and fill the remaining inline space.', + thumbnail: 'inlinelayout-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'InlineLayoutProps', + description: '', + type: 'InlineLayoutProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'inlinelayout-default.png', + codeblock: { + title: 'Basic InlineLayout', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-inlinelayout.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [disclosureAndAlignment], + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.ts new file mode 100644 index 0000000000..903b79f4fb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineLayout/examples/basic-inlinelayout.example.ts @@ -0,0 +1,16 @@ +import {extension, InlineLayout, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const inlineLayout = root.createComponent( + InlineLayout, + { + columns: ['20%', 'fill'], + }, + [ + root.createComponent(View, {border: 'base', padding: 'base'}, '20%'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'fill'), + ], + ); + + root.appendChild(inlineLayout); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/InlineSpacer.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/InlineSpacer.doc.ts new file mode 100644 index 0000000000..b08d62fce5 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/InlineSpacer.doc.ts @@ -0,0 +1,41 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'InlineSpacer', + description: + 'InlineSpacer is used to create empty inline space, typically when variable spacing is needed between multiple elements.\n\nNote that you should favor InlineStack when spacing between all elements is the same.', + isVisualComponent: true, + thumbnail: 'inlinespacer-thumbnail.png', + requires: '', + type: '', + definitions: [ + { + title: 'InlineSpacerProps', + description: '', + type: 'InlineSpacerProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'inlinespacer-default.png', + codeblock: { + title: 'Basic InlineSpacer', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-inlinespacer.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.ts new file mode 100644 index 0000000000..c901e9c7a2 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineSpacer/examples/basic-inlinespacer.example.ts @@ -0,0 +1,20 @@ +import { + extension, + InlineSpacer, + InlineStack, + View, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const inlineSpacer = root.createComponent(InlineStack, {spacing: 'none'}, [ + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(InlineSpacer, {spacing: 'loose'}), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(InlineSpacer, {spacing: 'tight'}), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(InlineSpacer, {spacing: 'base'}), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + ]); + + root.appendChild(inlineSpacer); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/InlineStack.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/InlineStack.doc.ts new file mode 100644 index 0000000000..8e27a1a60b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/InlineStack.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'InlineStack', + description: + 'InlineStack is used to lay out a horizontal row of elements. Elements always wrap.', + isVisualComponent: true, + thumbnail: 'inlinestack-thumbnail.png', + requires: '', + type: '', + definitions: [ + { + title: 'InlineStackProps', + description: '', + type: 'InlineStackProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'inlinestack-default.png', + codeblock: { + title: 'Basic InlineStack', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-inlinestack.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.ts new file mode 100644 index 0000000000..19371d66c4 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/InlineStack/examples/basic-inlinestack.example.ts @@ -0,0 +1,18 @@ +import {extension, InlineStack, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const inlineStack = root.createComponent( + InlineStack, + { + spacing: 'base', + }, + [ + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + root.createComponent(View, {border: 'base', padding: 'base'}, 'View'), + ], + ); + + root.appendChild(inlineStack); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Link/Link.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Link/Link.doc.ts new file mode 100644 index 0000000000..ab61bcb80a --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Link/Link.doc.ts @@ -0,0 +1,64 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Link', + description: + 'Link makes text interactive so customers can perform an action, such as navigating to another location.', + requires: '', + isVisualComponent: true, + thumbnail: 'link-thumbnail.png', + type: '', + definitions: [ + { + title: 'LinkProps', + description: '', + type: 'LinkProps', + }, + ], + category: 'UI components', + subCategory: 'Actions', + defaultExample: { + image: 'link-default.png', + codeblock: { + title: 'Basic Link', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Link/examples/basic-link.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-link.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "monochrome" | Takes the color of its parent.|', + }, + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- If the link isn’t in a paragraph, then consider using a plain button instead for a larger hit area.\n\n- Use links primarily for navigation and use buttons primarily for actions.\n\n- The HTML that renders for the Button and `Link` components includes style and accessibility information. Use these components intentionally and consistently to provide a more inclusive experience for assistive technology users and a more cohesive visual experience for sighted users.', + }, + ], + related: [ + { + name: 'Button', + subtitle: 'Component', + url: 'button', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Link/examples/basic-link.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Link/examples/basic-link.example.ts new file mode 100644 index 0000000000..3f723344f1 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Link/examples/basic-link.example.ts @@ -0,0 +1,11 @@ +import {extension, Link} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const link = root.createComponent( + Link, + {to: 'https://www.shopify.ca/climate/sustainability-fund'}, + 'Sustainability fund', + ); + + root.appendChild(link); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/List/List.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/List/List.doc.ts new file mode 100644 index 0000000000..794c12e59e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/List/List.doc.ts @@ -0,0 +1,58 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'List', + description: + 'Lists display a set of related content. Each list item usually begins with a bullet or a number.', + + requires: '', + thumbnail: 'list-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ListProps', + description: '', + type: 'ListProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'list-default.png', + codeblock: { + title: 'Basic List', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/List/examples/basic-list.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-list.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use lists to break up chunks of related content to make the information easier for customers to scan.\n\n- Phrase list items consistently. Try to start each item with a noun or a verb and be consistent with each item.\n\n- Use bullets for a text-only list of related items that don’t need to be in a specific order.\n\n- Use numbers for a text-only list of related items when you need to communicate order, priority, or sequence.\n\n- Don’t use a marker when only the semantic value of a list matters, such as with a list of links.', + }, + ], + related: [ + { + name: 'ListItem', + subtitle: 'Component', + url: 'listItem', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/List/examples/basic-list.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/List/examples/basic-list.example.ts new file mode 100644 index 0000000000..3a28e41ec6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/List/examples/basic-list.example.ts @@ -0,0 +1,11 @@ +import {extension, List, ListItem} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const list = root.createComponent(List, undefined, [ + root.createComponent(ListItem, undefined, '100% organic cotton'), + root.createComponent(ListItem, undefined, 'Made in Canada'), + root.createComponent(ListItem, undefined, 'Machine washable'), + ]); + + root.appendChild(list); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/ListItem.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/ListItem.doc.ts new file mode 100644 index 0000000000..0519f82686 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/ListItem.doc.ts @@ -0,0 +1,42 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ListItem', + description: + 'List items are used as children of the `List` component.\n\nThey usually begins with a bullet or a number.', + requires: '', + thumbnail: 'listitem-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'listitem-default.png', + codeblock: { + title: 'Basic ListItem', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-listitem.example.ts', + language: 'js', + }, + ], + }, + }, + related: [ + { + name: 'List', + subtitle: 'Component', + url: 'list', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.ts new file mode 100644 index 0000000000..28d8a96f6e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ListItem/examples/basic-listitem.example.ts @@ -0,0 +1,9 @@ +import {extension, List, ListItem} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const list = root.createComponent(List, undefined, [ + root.createComponent(ListItem, undefined, '100% organic cotton'), + ]); + + root.appendChild(list); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Map/Map.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Map/Map.doc.ts new file mode 100644 index 0000000000..bcd066554e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Map/Map.doc.ts @@ -0,0 +1,54 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Map', + description: + 'Use the Map component to provide visual representation of geographic data such as verifying address, package or pickup locations.\n\nPlease note that the merchant or partner has to provide an API key and a set of allowed domains where the map would render.\n\nThe 3 necessary domains needed are:\n\n- `https://*.[MERCHANT-DOMAIN].com`\n\n- `https://shop.app`\n\n- `https://shopify.com` \n\n Where `*` is a wildcard. Learn more about [match patterns](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns).\n\n Please refer to the [Google Maps Platform documentation](https://developers.google.com/maps/documentation/javascript/get-api-key) for more details on how to get an API key.', + requires: '', + thumbnail: 'map-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'MapProps', + description: '', + type: 'MapProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'map-default.png', + codeblock: { + title: 'Basic Map', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Map/examples/basic-map.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-map.example.ts', + language: 'js', + }, + ], + }, + }, + related: [ + { + name: 'MapMarker', + subtitle: 'Component', + url: 'mapmarker', + type: 'Component', + }, + { + name: 'MapPopover', + subtitle: 'Component', + url: 'mappopover', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Map/examples/basic-map.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Map/examples/basic-map.example.ts new file mode 100644 index 0000000000..7b90b1a1cd --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Map/examples/basic-map.example.ts @@ -0,0 +1,13 @@ +import {extension, Map} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const map = root.createComponent(Map, { + apiKey: 'YOUR_API_KEY', + accessibilityLabel: 'Map showing pickup locations', + latitude: -28.024, + longitude: 140.887, + zoom: 4, + }); + + root.appendChild(map); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/MapMarker.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/MapMarker.doc.ts new file mode 100644 index 0000000000..7f648d32e7 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/MapMarker.doc.ts @@ -0,0 +1,62 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'MapMarker', + description: + 'MapMarker represents a specific location or point of interest on a map.', + requires: '', + thumbnail: 'mapmarker-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'MapMarkerProps', + description: '', + type: 'MapMarkerProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'mapmarker-default.png', + codeblock: { + title: 'Basic MapMarker', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-mapmarker.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: `- If your markers are interactive, make sure that the selected marker's icon is different from the rest of the non-selected markers.\n\n- If there are a large number of markers obscuring important features of the map, set the markers to clusterable to help increase the readability of the map.`, + }, + ], + related: [ + { + name: 'Map', + subtitle: 'Component', + url: 'map', + type: 'Component', + }, + { + name: 'MapPopover', + subtitle: 'Component', + url: 'mappopover', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.ts new file mode 100644 index 0000000000..dae5d1d4ca --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/MapMarker/examples/basic-mapmarker.example.ts @@ -0,0 +1,23 @@ +import {extension, Map, MapMarker} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const map = root.createComponent( + Map, + { + apiKey: 'YOUR_API_KEY', + accessibilityLabel: 'Map', + latitude: -28.024, + longitude: 140.887, + zoom: 4, + }, + [ + root.createComponent(MapMarker, { + latitude: -28.024, + longitude: 140.887, + accessibilityLabel: 'Map marker for Innamincka, Australia', + }), + ], + ); + + root.appendChild(map); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/MapPopover.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/MapPopover.doc.ts new file mode 100644 index 0000000000..3609a287df --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/MapPopover.doc.ts @@ -0,0 +1,62 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'MapPopover', + description: + 'MapPopover provides additional information or context about a specific location or point of interest on a map.', + requires: '', + thumbnail: 'mappopover-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'MapPopoverProps', + description: '', + type: 'MapPopoverProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'mappopover-default.png', + codeblock: { + title: 'Basic MapPopover', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-mappopover.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: `- Use to display relevant details such as the name, address, description, or other pertinent information related to the location.\n\n- Ensure that the content displayed in the map popover is brief, relevant, and easy to understand.\n\n- Maintain visual consistency with the overall design of the checkout. `, + }, + ], + related: [ + { + name: 'Map', + subtitle: 'Component', + url: 'map', + type: 'Component', + }, + { + name: 'MapMarker', + subtitle: 'Component', + url: 'mapmarker', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.ts new file mode 100644 index 0000000000..42f238effb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/MapPopover/examples/basic-mappopover.example.ts @@ -0,0 +1,36 @@ +import { + extension, + Map, + MapMarker, + MapPopover, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const popoverFragment = root.createFragment(); + const popover = root.createComponent( + MapPopover, + {}, + 'Blue Mountains National Park store', + ); + popoverFragment.appendChild(popover); + const map = root.createComponent( + Map, + { + apiKey: 'YOUR_API_KEY', + accessibilityLabel: 'Map', + latitude: -28.024, + longitude: 140.887, + zoom: 4, + }, + [ + root.createComponent(MapMarker, { + latitude: -28.024, + longitude: 140.887, + accessibilityLabel: 'Map marker for Innamincka, Australia', + overlay: popoverFragment, + }), + ], + ); + + root.appendChild(map); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Menu/Menu.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Menu/Menu.doc.ts index 09a2356db4..2a3be1108e 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/Menu/Menu.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Menu/Menu.doc.ts @@ -22,7 +22,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'Docs_Menu_Button_Action', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Actions', defaultExample: { image: 'menu-default.png', altText: 'An example of a Menu with three actions.', diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Modal/Modal.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Modal/Modal.doc.ts new file mode 100644 index 0000000000..116c5b01d8 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Modal/Modal.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Modal', + description: + 'Modals are a special type of overlay that shift focus towards a specific action/set of information before the main flow can proceed. They must be specified inside the `overlay` prop of an activator component (`Button`, `Link` or `Pressable`).\n\nThe library automatically applies the [WAI-ARIA Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) to both the activator and the modal content.', + requires: '', + thumbnail: 'modal-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ModalProps', + description: '', + type: 'ModalProps', + }, + ], + category: 'UI components', + subCategory: 'Overlays', + defaultExample: { + image: 'modal-default.png', + codeblock: { + title: 'Basic Modal', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-modal.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + 'Use modals if:\n\n- The information needed to be shown is not critical in completing the checkout process and information cannot be condensed into one sentence.\n\n- The information the buyer is entering requires less than two rows of input fields.\n\n- The information the buyer is entering is not reliant on information on the page (which is underneath the modal and not visible to them).', + }, + ], + related: [ + { + name: 'Ui', + subtitle: 'API', + url: 'ui', + type: 'API', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.ts new file mode 100644 index 0000000000..9074774ff1 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Modal/examples/basic-modal.example.ts @@ -0,0 +1,44 @@ +import { + extension, + Button, + Link, + Modal, + TextBlock, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root, {ui}) => { + const modalFragment = root.createFragment(); + const modal = root.createComponent( + Modal, + {id: 'my-modal', title: 'Return policy', padding: true}, + [ + root.createComponent( + TextBlock, + undefined, + 'We have a 30-day return policy, which means you have 30 days after receiving your item to request a return.', + ), + root.createComponent( + TextBlock, + undefined, + 'To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase.', + ), + root.createComponent( + Button, + { + onPress() { + ui.overlay.close('my-modal'); + }, + }, + 'Close', + ), + ], + ); + modalFragment.appendChild(modal); + const link = root.createComponent( + Link, + {overlay: modalFragment}, + 'Return policy', + ); + + root.appendChild(link); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Page/Page.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Page/Page.doc.ts index 1a82081f62..a56964b358 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/Page/Page.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Page/Page.doc.ts @@ -27,7 +27,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'Docs_Page_Button_SecondaryAction', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Layout and structure', defaultExample: { image: 'page-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/PaymentIcon.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/PaymentIcon.doc.ts new file mode 100644 index 0000000000..61125c6c24 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/PaymentIcon.doc.ts @@ -0,0 +1,55 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'PaymentIcon', + description: + 'Payment icons can be used for displaying payment-related information or features such as a user’s saved or available payment methods.', + thumbnail: 'paymenticon-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'PaymentIconProps', + description: '', + type: 'PaymentIconProps', + }, + { + title: 'PaymentMethod', + description: '', + type: 'PaymentMethod', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'paymenticon-default.png', + codeblock: { + title: 'Basic PaymentIcon', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-paymenticon.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Maintain the interior appearance of the SVG. The branded portion of the payment icon as provided meets the brand guidelines of the payment provider.\n\n- Maintain the border property of the payment icon. It is designed to adapt to merchant branding in Checkout and ensures a consistent appearance across the customer experience.\n\n- The icon size is designed to be displayed consistently across checkout.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.ts new file mode 100644 index 0000000000..2643bdfee8 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/PaymentIcon/examples/basic-paymenticon.example.ts @@ -0,0 +1,7 @@ +import {extension, PaymentIcon} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const paymentIcon = root.createComponent(PaymentIcon, {name: 'shop-pay'}); + + root.appendChild(paymentIcon); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/PhoneField.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/PhoneField.doc.ts new file mode 100644 index 0000000000..b6b1b21c41 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/PhoneField.doc.ts @@ -0,0 +1,41 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'PhoneField', + description: + 'A PhoneField is an input field that merchants can type into optimized for phone numbers with a country code base auto-formatting. The country code is required for the initial render of the field but it can be overriden later by the user either by selecting a country in the country selection dropdown or by manually editing the country phone code directly in the text field.', + requires: '', + isVisualComponent: true, + thumbnail: 'phonefield-thumbnail.png', + type: '', + definitions: [ + { + title: 'PhoneFieldProps', + description: '', + type: 'PhoneFieldProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'phonefield-default.png', + codeblock: { + title: 'Basic PhoneField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-phonefield.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.ts new file mode 100644 index 0000000000..6ac80d2c21 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/PhoneField/examples/basic-phonefield.example.ts @@ -0,0 +1,10 @@ +import {extension, PhoneField} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const phoneField = root.createComponent(PhoneField, { + label: 'Phone', + value: '1 (555) 555-5555', + }); + + root.appendChild(phoneField); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Popover/Popover.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Popover/Popover.doc.ts new file mode 100644 index 0000000000..cc74332c28 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Popover/Popover.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Popover', + description: + 'Popovers are similar to tooltips. They are small overlays that open on demand after a user interaction. The difference is that the popover can contain more content, without cluttering the page. They must be specified inside the `overlay` prop of an activator component (`Button`, `Link` or `Pressable`).\n\nThe library automatically applies the WAI-ARIA Popover Widget pattern to both the activator and the popover content.', + requires: '', + isVisualComponent: true, + thumbnail: 'popover-thumbnail.png', + type: '', + definitions: [ + { + title: 'PopoverProps', + description: '', + type: 'PopoverProps', + }, + ], + category: 'UI components', + subCategory: 'Overlays', + defaultExample: { + image: 'popover-default.png', + codeblock: { + title: 'Basic Popover', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-popover.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + 'Use popovers if:\n\n- The intent is to ask the customer for information.\n\n- It’s possible to use at most two rows of input fields to get the information.', + }, + ], + related: [ + { + name: 'Ui', + subtitle: 'API', + url: 'ui', + type: 'API', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.ts new file mode 100644 index 0000000000..cb4657fbab --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Popover/examples/basic-popover.example.ts @@ -0,0 +1,30 @@ +import { + extension, + Pressable, + Popover, + View, + TextBlock, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const popoverFragment = root.createFragment(); + const popover = root.createComponent(Popover, {}, [ + root.createComponent(View, {maxInlineSize: 200, padding: 'base'}, [ + root.createComponent(TextBlock, {}, 'A thoughtful way to pay'), + root.createComponent(TextBlock, {}, 'Tap don’t type'), + root.createComponent( + TextBlock, + {}, + 'Shop Pay remembers your important details, so you can fill carts, not forms. And everything is encrypted so you can speed safely through checkout.', + ), + ]), + ]); + popoverFragment.appendChild(popover); + const pressable = root.createComponent( + Pressable, + {overlay: popoverFragment}, + 'More info', + ); + + root.appendChild(pressable); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/Pressable.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/Pressable.doc.ts new file mode 100644 index 0000000000..54921145fe --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/Pressable.doc.ts @@ -0,0 +1,48 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Pressable', + description: + 'Pressable is a generic interactive component. It shares the same styling properties as View but also adds pressable behavior, meaning that you can execute some logic in response to user interaction. Use this component for creating interactive elements without the default styling that comes with `Button` and `Link`.', + requires: '', + thumbnail: 'pressable-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'PressableProps', + description: '', + type: 'PressableProps', + }, + ], + category: 'UI components', + subCategory: 'Actions', + defaultExample: { + image: 'pressable-default.png', + codeblock: { + title: 'Basic Pressable', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-pressable.example.ts', + language: 'js', + }, + ], + }, + }, + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.ts new file mode 100644 index 0000000000..8f99d2017a --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Pressable/examples/basic-pressable.example.ts @@ -0,0 +1,27 @@ +import { + extension, + Icon, + InlineLayout, + Pressable, + Text, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const pressable = root.createComponent( + Pressable, + { + border: 'base', + cornerRadius: 'base', + padding: 'base', + onPress: () => console.log('onPress event'), + }, + [ + root.createComponent(InlineLayout, {columns: ['fill', 'auto']}, [ + root.createComponent(Text, {}, 'Details'), + root.createComponent(Icon, {source: 'chevronDown', size: 'small'}), + ]), + ], + ); + + root.appendChild(pressable); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/ProductThumbnail.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/ProductThumbnail.doc.ts new file mode 100644 index 0000000000..2b3a13fa66 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/ProductThumbnail.doc.ts @@ -0,0 +1,50 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ProductThumbnail', + description: + 'Product thumbnail is a representation of a product image. It provides a visual preview of the item, so buyers can quickly identify products.', + thumbnail: 'productthumbnail-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ProductThumbnailProps', + description: '', + type: 'ProductThumbnailProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'productthumbnail-default.png', + codeblock: { + title: 'Basic ProductThumbnail', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-productthumbnail.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '**High-quality images and consistent aspect ratio**\n\n- Use optimized product images that ensure visual clarity and loading speed. Maintain a consistent aspect ratio for product thumbnails to avoid distortion or stretching of the images.\n\n**Consistent visual style and appropriate sizes**\n\n- Keep a consistent visual style for product thumbnails throughout your store. Use appropriate size for product thumbnails depending on the layout and use case. This consistency helps buyers recognize and associate the thumbnails with your product offerings.\n\n**Accessibility considerations**\n\n- Ensure product thumbnails are accessible with descriptive alternative text (alt text).', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.ts new file mode 100644 index 0000000000..72007cab4b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ProductThumbnail/examples/basic-productthumbnail.example.ts @@ -0,0 +1,11 @@ +import {extension, ProductThumbnail} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const paymentIcon = root.createComponent(ProductThumbnail, { + source: + 'https://shopify.dev/assets/api/checkout-extensions/checkout/components/product-thumbnail-example-code.png', + badge: 2, + }); + + root.appendChild(paymentIcon); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Progress/Progress.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Progress/Progress.doc.ts new file mode 100644 index 0000000000..e8e1f41d43 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Progress/Progress.doc.ts @@ -0,0 +1,89 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Progress', + description: 'Use to visually represent the completion of a task or process.', + requires: '', + isVisualComponent: true, + thumbnail: 'progress-thumbnail.png', + type: '', + definitions: [ + { + title: 'ProgressProps', + description: '', + type: 'ProgressProps', + }, + ], + category: 'UI components', + subCategory: 'Feedback and status indicators', + defaultExample: { + image: 'progress-indeterminate.gif', + codeblock: { + title: 'Indeterminate state', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-progress.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: ` +Use components like [TextBlock](../titles-and-text/textblock) or [Text](../titles-and-text/text), along with the Progress component, to display text indicating the status of the progress bar. + +### Loading states + +For loading states, add text to reassure the user that the progress bar is not frozen. + +![A progress bar with "Loading" text](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-loading.png) + +### Error states + +For error states, add text or a [Banner](./banner) to describe the error and next steps. Use the \`critical\` tone property to convey urgency. + +![A progress bar with error text that says "There was a problem with the file upload. Please try again."](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-error.png) + +### Visualize a goal + +Use the Progress component to visualize a goal that's valuable to the customer. + +Here's an example of using a progress bar to show a customer's progress toward the next rewards tier: + +![A progress bar in customer accounts, showing that the customer is on their way to reaching the Botanical maven rewards tier.](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-goal.png) + +Here's an example of using a progress bar to show how much more a customer needs to spend to get free shipping: + +![A progress bar at checkout, showing that the customer is $43 away from free shipping.](/assets/templated-apis-screenshots/checkout-ui-extensions/unstable/progress-free-shipping.png) + `, + }, + ], + examples: { + description: '', + examples: [ + getExample('ui-components/progress-determinate-state', ['jsx', 'js']), + ], + }, + related: [ + { + name: 'Spinner', + subtitle: 'Component', + url: 'spinner', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.ts new file mode 100644 index 0000000000..28c38d7604 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Progress/examples/basic-progress.example.ts @@ -0,0 +1,9 @@ +import {extension, Progress} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const baseProgress = root.createComponent(Progress, { + accessibilityLabel: 'Loading', + }); + + root.appendChild(baseProgress); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/QRCode.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/QRCode.doc.ts new file mode 100644 index 0000000000..9a3dcb5b4a --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/QRCode.doc.ts @@ -0,0 +1,71 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'QRCode', + description: 'Used to quickly access scannable data.', + requires: '', + isVisualComponent: true, + thumbnail: 'qrcode-thumbnail.png', + type: '', + definitions: [ + { + title: 'QRCodeProps', + description: '', + type: 'QRCodeProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'qrcode-default.png', + codeblock: { + title: 'Basic QR Code', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-qrcode.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: ` +- Always test that the QR code is scannable from a smartphone. +- Include a square logo if that’s what your customers are familiar with. +- Increase usability by adding a text description of what the QR code does. +- Always provide an alternate method for customers to access the content of the QR code. + - If the content is a URL, provide a [\`Link\`](/docs/api/checkout-ui-extensions/components/link) nearby. + - If the content is data, provide a [\`Button\`](/docs/api/checkout-ui-extensions/components/button) to copy the data to the clipboard, or show the data in a readonly [\`TextField\`](/docs/api/checkout-ui-extensions/components/textfield).`, + }, + ], + examples: { + description: '', + examples: [ + getExample('ui-components/qrcode-image', ['jsx', 'js']), + getExample('ui-components/qrcode-fill-size', ['jsx', 'js']), + getExample('ui-components/clipboarditem-qrcode', ['jsx', 'js']), + ], + }, + related: [ + { + name: 'ClipboardItem', + subtitle: 'Component', + url: 'clipboarditem', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.ts new file mode 100644 index 0000000000..ac2268fb94 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/QRCode/examples/basic-qrcode.example.ts @@ -0,0 +1,20 @@ +import { + extension, + Link, + QRCode, + TextBlock, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const qrCode = root.createComponent(QRCode, { + content: 'https://shopify.com', + }); + + const textBlock = root.createComponent(TextBlock, null, [ + 'Scan to visit ', + root.createComponent(Link, {to: 'https://shopify.com'}, 'Shopify.com'), + ]); + + root.appendChild(qrCode); + root.appendChild(textBlock); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ResourceItem/ResourceItem.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ResourceItem/ResourceItem.doc.ts index 304a1632cc..e6ed951833 100644 --- a/packages/ui-extensions/src/surfaces/customer-account/components/ResourceItem/ResourceItem.doc.ts +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ResourceItem/ResourceItem.doc.ts @@ -21,7 +21,8 @@ const data: ReferenceEntityTemplateSchema = { type: 'Docs_ResourceItem_Button_Action', }, ], - category: 'components', + category: 'UI components', + subCategory: 'Actions', defaultExample: { image: 'resourceitem-preview.png', altText: diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/ScrollView.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/ScrollView.doc.ts new file mode 100644 index 0000000000..d6d18b96bd --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/ScrollView.doc.ts @@ -0,0 +1,48 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ScrollView', + description: + 'ScrollView is a container for long form content, such as order summary line items, that allows for scrolling so customers can expose more content as they view.', + requires: '', + isVisualComponent: true, + thumbnail: 'scrollview-thumbnail.png', + type: '', + definitions: [ + { + title: 'ScrollViewProps', + description: '', + type: 'ScrollViewProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'scrollview-default.png', + codeblock: { + title: 'Basic Scrollview', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-scrollview.example.ts', + language: 'js', + }, + ], + }, + }, + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.ts new file mode 100644 index 0000000000..98c4b61c4c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ScrollView/examples/basic-scrollview.example.ts @@ -0,0 +1,38 @@ +import {extension, ScrollView, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const scrollView = root.createComponent(ScrollView, {maxBlockSize: 400}, [ + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + root.createComponent( + View, + {border: 'base', padding: 'base', minBlockSize: 50}, + 'View', + ), + ]); + + root.appendChild(scrollView); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Select/Select.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Select/Select.doc.ts new file mode 100644 index 0000000000..d341d9df54 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Select/Select.doc.ts @@ -0,0 +1,76 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Select', + description: + 'Selects let buyers choose one option from an options menu. Consider select when you have 4 or more options, to avoid cluttering the interface.', + requires: '', + thumbnail: 'select-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'SelectProps', + description: '', + type: 'SelectProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'select-default.png', + codeblock: { + title: 'Basic Select', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Select/examples/basic-select.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-select.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use this component when customers need to choose between four or more predefined options.\n\n- Have a default option selected whenever possible. Use Select as placeholder text if there’s no logical default option.', + }, + ], + examples: { + description: '', + examples: [ + { + image: 'select-time-picking.png', + description: + 'The Select component is a great choice for displaying a long list of time choices, as it helps conserve valuable space. If the number of options is less than or equal to 5, we recommend using the [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) component. This allows buyers to see all options immediately without the need for clicking into the select.', + codeblock: { + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/time-picking-select.example.ts', + language: 'js', + }, + ], + title: + 'Using the Select component to display a long list of time choices', + }, + }, + ], + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/basic-select.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/basic-select.example.ts new file mode 100644 index 0000000000..8efc62a811 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/basic-select.example.ts @@ -0,0 +1,36 @@ +import {extension, Select} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const select = root.createComponent(Select, { + label: 'Country', + value: '2', + options: [ + { + value: '1', + label: 'Australia', + }, + { + value: '2', + label: 'Canada', + }, + { + value: '3', + label: 'France', + }, + { + value: '4', + label: 'Japan', + }, + { + value: '5', + label: 'Nigeria', + }, + { + value: '6', + label: 'United States', + }, + ], + }); + + root.appendChild(select); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.ts new file mode 100644 index 0000000000..9dffa4107a --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Select/examples/time-picking-select.example.ts @@ -0,0 +1,36 @@ +import {extension, Select} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const select = root.createComponent(Select, { + label: 'Pickup time', + value: '1', + options: [ + { + value: '1', + label: '9:00 AM', + }, + { + value: '2', + label: '9:30 AM', + }, + { + value: '3', + label: '10:00 AM', + }, + { + value: '4', + label: '10:30 AM', + }, + { + value: '5', + label: '11:00 AM', + }, + { + value: '6', + label: '11:30 AM', + }, + ], + }); + + root.appendChild(select); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/Sheet.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/Sheet.doc.ts new file mode 100644 index 0000000000..a5e4c5338f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/Sheet.doc.ts @@ -0,0 +1,76 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Sheet', + description: + 'The Sheet component displays essential information for customers at the bottom of the screen, appearing above other elements. Use it sparingly to avoid distracting customers during checkout. This component requires access to [Customer Privacy API](/docs/api/checkout-ui-extensions/unstable/configuration#collect-buyer-consent) to be rendered. \n\nThe library automatically applies the [WAI-ARIA Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/) to both the activator and the sheet content.', + requires: + 'configuration of the [Customer Privacy](/docs/api/checkout-ui-extensions/unstable/configuration#collect-buyer-consent) capability to be rendered.', + thumbnail: 'sheet-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'SheetProps', + description: '', + type: 'SheetProps', + }, + ], + category: 'UI components', + subCategory: 'Overlays', + defaultExample: { + image: 'sheet-default.png', + codeblock: { + title: 'Basic Sheet', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-sheet.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'shopify-controlled-surfaces', + title: 'Shopify-controlled surfaces', + sectionContent: + 'To prevent disruptions during checkout, we maintain strict design control over key areas of the Sheet component. These Shopify-controlled elements include: \n\n

    Locations of elements

    \n\nThe Sheet elements (header, content, action buttons, and dismiss button) are strategically positioned and sized to present vital information upfront.\n\n\n\n\n\n
    \n\n

    Padding and spacing

    \n\n\n\n
    \n\n

    Maximum height

    \n\nTo balance customer attention and task completion, a maximum height is set for the Sheet component.\n\n\n\n\n\nWhen content pushes the sheet to exceed this limit, the following UI behaviors are triggered:\n\n
    \n\n

    Heading and content are scrollable

    \n\n\n\n
    \n\n

    Expand pill appears to allow customers to view the entire content

    \n\n\n\n
    \n\n

    Actions slot and dismiss button remain fixed

    \n\n', + }, + { + type: 'Generic', + anchorLink: 'privacy-consent-requirements', + title: 'Privacy consent requirements', + sectionContent: + '

    Content

    \n\nFor the best customer experience, ensure content is brief and to the point.\n\n\n\nVarious strategies can be employed to avoid content scrolling.\n\n
    \n\n

    Use short content

    \n\n\n\n
    \n\n

    Use small text size

    \n\n \n\n
    \n\n

    Remove the header

    \n\n \n\n
    \n\n

    Actions slot

    \n\nThe actions slots allows customers to make decisions and is split into primary and secondary sections.\n\n\n\n
    \n\n

    Primary section

    \n\n Contains primary actions for customer decisions on the sheet’s prompt. Up to two buttons are allowed. Keep the button’s content brief so that it doesn’t wrap to more than one line.\n\n\n\n
    \n\n

    Secondary section

    \n\nContains action that is unrelated to the sheet’s prompt. Only one button is allowed. A modal can be activated when engaging with the secondary action. Keep the button’s content brief so that it doesn’t wrap to more than one line.\n\n\n\n
    \n\n

    Consent, denial of consent, and sheet dismissal

    \n\n

    Consent

    \n\nWhen a customer expresses consent by pressing the acceptance button, cookies will load and the sheet should not re-appear on refresh.\n\n
    \n\n

    Denial of consent

    \n\nWhen a customer expresses denial of consent by pressing the rejection button, cookies will not load and the sheet will not re-appear on refresh.\n\n
    \n\n

    Sheet dismissal

    \n\nWhen a customer neither grants nor denies consent by pressing the dismiss button, cookies will not load and the sheet will re-appear on refresh.\n\n', + }, + ], + examples: { + description: '', + examples: [ + getExample('ui-components/sheet-consent', ['jsx', 'js']), + getExample('ui-components/sheet-description-preferences', ['jsx', 'js']), + getExample('ui-components/sheet-icon-button-preferences', ['jsx', 'js']), + getExample('ui-components/sheet-layout-content', ['jsx', 'js']), + ], + }, + related: [ + { + name: 'Ui', + subtitle: 'API', + url: 'ui', + type: 'API', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.ts new file mode 100644 index 0000000000..be863e0d13 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Sheet/examples/basic-sheet.example.ts @@ -0,0 +1,29 @@ +import { + extension, + Link, + Sheet, + TextBlock, +} from '@shopify/ui-extensions/customer-account'; + +// This component requires access to Customer Privacy API to be rendered. + +export default extension('customer-account.page.render', (root) => { + const sheetFragment = root.createFragment(); + const sheet = root.createComponent( + Sheet, + { + id: 'basic-sheet', + heading: 'Basic Sheet', + accessibilityLabel: 'A sheet with text content', + }, + [root.createComponent(TextBlock, undefined, 'Basic Sheet Content')], + ); + sheetFragment.appendChild(sheet); + const link = root.createComponent( + Link, + {overlay: sheetFragment}, + 'Open sheet', + ); + + root.appendChild(link); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/SkeletonImage.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/SkeletonImage.doc.ts new file mode 100644 index 0000000000..720e684789 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/SkeletonImage.doc.ts @@ -0,0 +1,52 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const loadingSkeletons = getExample('ui-components/loading-skeletons', [ + 'jsx', + 'js', +]); + +const data: ReferenceEntityTemplateSchema = { + name: 'SkeletonImage', + description: + 'SkeletonImage is used to provide a low fidelity representation of an image before it appears on the page.', + requires: '', + thumbnail: 'skeletonimage-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'SkeletonImageProps', + description: '', + type: 'SkeletonImageProps', + }, + ], + category: 'UI components', + subCategory: 'Media and visuals', + defaultExample: { + image: 'skeletonimage-default.png', + codeblock: { + title: 'Basic SkeletonImage', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-skeletonimage.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [loadingSkeletons], + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.ts new file mode 100644 index 0000000000..f5536f764b --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonImage/examples/basic-skeletonimage.example.ts @@ -0,0 +1,10 @@ +import {extension, SkeletonImage} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const skeletonImage = root.createComponent(SkeletonImage, { + inlineSize: 300, + blockSize: 300, + }); + + root.appendChild(skeletonImage); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/SkeletonText.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/SkeletonText.doc.ts new file mode 100644 index 0000000000..4e66ec7738 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/SkeletonText.doc.ts @@ -0,0 +1,52 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const loadingSkeletons = getExample('ui-components/loading-skeletons', [ + 'jsx', + 'js', +]); + +const data: ReferenceEntityTemplateSchema = { + name: 'SkeletonText', + description: + 'SkeletonText is used to provide a low fidelity representation of text content before it appears on the page. \n\nOptionally you can use any text content inside `SkeletonText` to be used as a base for the rendered skeleton', + requires: '', + isVisualComponent: true, + thumbnail: 'skeletontext-thumbnail.png', + type: '', + definitions: [ + { + title: 'SkeletonTextProps', + description: '', + type: 'SkeletonTextProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'skeletontext-default.png', + codeblock: { + title: 'Basic SkeletonText', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-skeletontext.example.ts', + language: 'js', + }, + ], + }, + }, + examples: { + description: '', + examples: [loadingSkeletons], + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.ts new file mode 100644 index 0000000000..e43cddcad6 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonText/examples/basic-skeletontext.example.ts @@ -0,0 +1,7 @@ +import {extension, SkeletonText} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const skeletonText = root.createComponent(SkeletonText); + + root.appendChild(skeletonText); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/SkeletonTextBlock.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/SkeletonTextBlock.doc.ts new file mode 100644 index 0000000000..506885a27f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/SkeletonTextBlock.doc.ts @@ -0,0 +1,41 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'SkeletonTextBlock', + description: + 'SkeletonTextBlock is used to provide a low fidelity representation of a block of text before it appears on the page. \n\nOptionally you can use any text content inside `SkeletonTextBlock` to be used as a base for the rendered skeleton', + requires: '', + isVisualComponent: true, + thumbnail: 'skeletontextblock-thumbnail.png', + type: '', + definitions: [ + { + title: 'SkeletonTextBlockProps', + description: '', + type: 'SkeletonTextBlockProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'skeletontextblock-default.png', + codeblock: { + title: 'Basic SkeletonTextBlock', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-skeletontextblock.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.ts new file mode 100644 index 0000000000..ec1563a888 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/SkeletonTextBlock/examples/basic-skeletontextblock.example.ts @@ -0,0 +1,7 @@ +import {extension, SkeletonTextBlock} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const skeletonTextBlock = root.createComponent(SkeletonTextBlock); + + root.appendChild(skeletonTextBlock); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/Spinner.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/Spinner.doc.ts new file mode 100644 index 0000000000..3502132375 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/Spinner.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Spinner', + description: + 'Spinner is used to notify buyers that their action is being processed. The Spinner is usually used when sending or receiving data from a server.', + requires: '', + thumbnail: 'spinner-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'SpinnerProps', + description: '', + type: 'SpinnerProps', + }, + ], + category: 'UI components', + subCategory: 'Feedback and status indicators', + defaultExample: { + image: 'spinner-default.png', + codeblock: { + title: 'Basic Spinner', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-spinner.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "accent" | Conveys emphasis and draws attention to the element. |\n| "monochrome" | Takes the color of its parent.|', + }, + ], + related: [ + { + name: 'Progress', + subtitle: 'Component', + url: 'progress', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.ts new file mode 100644 index 0000000000..6c28a6168f --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Spinner/examples/basic-spinner.example.ts @@ -0,0 +1,7 @@ +import {extension, Spinner} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const spinner = root.createComponent(Spinner); + + root.appendChild(spinner); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/Stepper.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/Stepper.doc.ts new file mode 100644 index 0000000000..1bdfa74dcd --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/Stepper.doc.ts @@ -0,0 +1,50 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Stepper', + description: + 'Use a stepper to increase or decrease a value, like changing the quantity from 1 to 2.', + requires: '', + thumbnail: 'stepper-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'StepperProps', + description: '', + type: 'StepperProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'stepper-default.png', + codeblock: { + title: 'Basic Stepper', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-stepper.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use this component when customers are likely to choose a number within a small range, such as when changing a quantity from one to three.\n\n- If there’s no default number, then consider choosing another component such as a TextField or Select.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.ts new file mode 100644 index 0000000000..e38824e127 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Stepper/examples/basic-stepper.example.ts @@ -0,0 +1,10 @@ +import {extension, Stepper} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const stepper = root.createComponent(Stepper, { + label: 'Quantity', + value: 1, + }); + + root.appendChild(stepper); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Switch/Switch.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Switch/Switch.doc.ts new file mode 100644 index 0000000000..ea89f2c1d0 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Switch/Switch.doc.ts @@ -0,0 +1,80 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Switch', + description: + 'Use a switch to represent an on or off state that takes effect immediately when tapped.', + requires: '', + isVisualComponent: true, + thumbnail: 'switch-thumbnail.png', + type: '', + definitions: [ + { + title: 'SwitchProps', + description: '', + type: 'SwitchProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'switch-default.png', + codeblock: { + title: 'Basic Switch', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-switch.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: ` +- The outcome of a switch should take effect immediately when tapped. +- Use for independent settings, like turning on a stand-alone feature. +- Most of the time no call-to-action should be needed as the switch should take effect immediately, but if the experience needs one, use “done” instead of “submit” or “apply”. + +### Content +The label should be a noun. Try explaining the setting out loud to test the name. The name should make sense when you insert it into these statements: + +- You can turn [setting_label] on or off in settings. +- [setting_label] is on. +- [setting_label] is off. + +### Switch vs checkbox +- If the experience requires multiple connected inputs, like a survey, use a checkbox instead of a switch. +- If the experience requires an error state, like agreeing to terms and conditions, use a checkbox instead of a switch. Both on and off options for a switch should always be valid. +- If you’re unsure, default to a checkbox as it’s the more familiar web pattern. + + + `, + }, + ], + examples: { + description: '', + examples: [getExample('ui-components/switch-custom-label', ['jsx', 'js'])], + }, + related: [ + { + name: 'Checkbox', + subtitle: 'Component', + url: 'checkbox', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.ts new file mode 100644 index 0000000000..79f1e23b09 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Switch/examples/basic-switch.example.ts @@ -0,0 +1,9 @@ +import {extension, Switch} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const baseSwitch = root.createComponent(Switch, { + accessibilityLabel: 'my-switch', + }); + + root.appendChild(baseSwitch); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Tag/Tag.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Tag/Tag.doc.ts new file mode 100644 index 0000000000..88e7b51547 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Tag/Tag.doc.ts @@ -0,0 +1,41 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Tag', + description: + 'A Tag is used to help label, organize or categorize objects. It is commonly used in Checkout to display the discounts applied to a cart.', + requires: '', + thumbnail: 'tag-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'TagProps', + description: '', + type: 'TagProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'tag-default.png', + codeblock: { + title: 'Basic Tag', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-tag.example.ts', + language: 'js', + }, + ], + }, + }, + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.ts new file mode 100644 index 0000000000..4f2dbd21dc --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Tag/examples/basic-tag.example.ts @@ -0,0 +1,7 @@ +import {extension, Tag} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const tag = root.createComponent(Tag, {icon: 'discount'}, 'SPRING'); + + root.appendChild(tag); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Text/Text.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Text/Text.doc.ts new file mode 100644 index 0000000000..1b1b41f099 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Text/Text.doc.ts @@ -0,0 +1,76 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Text', + description: + 'Text is used to visually style and provide semantic value for a small piece of text content.', + requires: '', + thumbnail: 'text-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'TextProps', + description: '', + type: 'TextProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'text-default.png', + codeblock: { + title: 'Basic Text', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Text/examples/basic-text.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-text.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "accent" | Conveys emphasis and draws attention to the element. |\n| "subdued" | Conveys a subdued or disabled state for the element. |\n| "info" | Conveys that the element is informative or has information. |\n| "success" | Convey a successful interaction. |\n| "warning" | Convey something needs attention or an action needs to be taken. |\n| "critical" | Conveys a problem has arisen. |', + }, + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Use larger text to emphasize content that’s not a heading, such as a price total.\n\n- Create contrast between more and less important text with properties such as `size` and `subdued`.', + }, + ], + related: [ + { + name: 'Heading', + subtitle: 'Component', + url: 'heading', + type: 'Component', + }, + { + name: 'HeadingGroup', + subtitle: 'Component', + url: 'headinggroup', + type: 'Component', + }, + { + name: 'TextBlock', + subtitle: 'Component', + url: 'textblock', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Text/examples/basic-text.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Text/examples/basic-text.example.ts new file mode 100644 index 0000000000..63a0a65717 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Text/examples/basic-text.example.ts @@ -0,0 +1,14 @@ +import {extension, Text, BlockStack} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const text = root.createComponent(BlockStack, undefined, [ + root.createComponent(Text, {size: 'extraSmall'}, 'Total'), + root.createComponent(Text, {size: 'small'}, 'Total'), + root.createComponent(Text, {size: 'base'}, 'Total'), + root.createComponent(Text, {size: 'medium'}, 'Total'), + root.createComponent(Text, {size: 'large'}, 'Total'), + root.createComponent(Text, {size: 'extraLarge'}, 'Total'), + ]); + + root.appendChild(text); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/TextBlock.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/TextBlock.doc.ts new file mode 100644 index 0000000000..ec33c46a27 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/TextBlock.doc.ts @@ -0,0 +1,76 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'TextBlock', + description: + 'Text block is used to render a block of text that occupies the full width available, like a paragraph.', + requires: '', + thumbnail: 'textblock-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'TextBlockProps', + description: '', + type: 'TextBlockProps', + }, + ], + category: 'UI components', + subCategory: 'Typography and content', + defaultExample: { + image: 'textblock-default.png', + codeblock: { + title: 'Basic TextBlock', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-textblock.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'appearance', + title: 'Appearance', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "accent" | Conveys emphasis and draws attention to the element. |\n| "subdued" | Conveys a subdued or disabled state for the element. |\n| "info" | Conveys that the element is informative or has information. |\n| "success" | Convey a successful interaction. |\n| "warning" | Convey something needs attention or an action needs to be taken. |\n| "critical" | Conveys a problem has arisen. |', + }, + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Create contrast between more and less important text with properties such as `size`, `emphasis`, and `appearance`.', + }, + ], + related: [ + { + name: 'Heading', + subtitle: 'Component', + url: 'heading', + type: 'Component', + }, + { + name: 'HeadingGroup', + subtitle: 'Component', + url: 'headinggroup', + type: 'Component', + }, + { + name: 'Text', + subtitle: 'Component', + url: 'text', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.ts new file mode 100644 index 0000000000..ce9438bd24 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/TextBlock/examples/basic-textblock.example.ts @@ -0,0 +1,22 @@ +import { + extension, + TextBlock, + BlockStack, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const textBlock = root.createComponent(BlockStack, undefined, [ + root.createComponent( + TextBlock, + undefined, + 'We have a 30-day return policy, which means you have 30 days after receiving your item to request a return.', + ), + root.createComponent( + TextBlock, + undefined, + 'To be eligible for a return, your item must be in the same condition that you received it, unworn or unused, with tags, and in its original packaging. You’ll also need the receipt or proof of purchase.', + ), + ]); + + root.appendChild(textBlock); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/TextField/TextField.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/TextField/TextField.doc.ts new file mode 100644 index 0000000000..02cd6ce70c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/TextField/TextField.doc.ts @@ -0,0 +1,49 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'TextField', + description: 'Use a text field to get text input from a customer.', + requires: '', + thumbnail: 'textfield-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'TextFieldProps', + description: '', + type: 'TextFieldProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'textfield-default.png', + codeblock: { + title: 'Basic TextField', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-textfield.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + '- Clearly label text fields so that it’s obvious what customers should enter.\n\n- Label text fields as Optional when input isn’t required. For example, use the label First name (optional).\n\n- Don’t have optional fields pass true to the required property.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.ts new file mode 100644 index 0000000000..2b09e28ed1 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/TextField/examples/basic-textfield.example.ts @@ -0,0 +1,9 @@ +import {extension, TextField} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const textfield = root.createComponent(TextField, { + label: 'Last name', + }); + + root.appendChild(textfield); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/ToggleButton.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/ToggleButton.doc.ts new file mode 100644 index 0000000000..f021ec6cb3 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/ToggleButton.doc.ts @@ -0,0 +1,48 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'ToggleButton', + description: + 'Options inside a [ToggleButtonGroup](/docs/api/checkout-ui-extensions/components/forms/togglebuttongroup).', + thumbnail: 'togglebutton-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ToggleButtonProps', + description: '', + type: 'ToggleButtonProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'togglebutton-default.png', + codeblock: { + title: 'Basic ToggleButton', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-togglebutton.example.ts', + language: 'js', + }, + ], + }, + }, + related: [ + { + name: 'ToggleButtonGroup', + subtitle: 'Component', + url: 'togglebuttongroup', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.ts new file mode 100644 index 0000000000..7e9a950734 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButton/examples/basic-togglebutton.example.ts @@ -0,0 +1,20 @@ +import { + extension, + ToggleButtonGroup, + ToggleButton, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const toggleButtonGroup = root.createComponent( + ToggleButtonGroup, + { + value: 'none', + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [root.createComponent(ToggleButton, {id: 'none'}, 'None')], + ); + + root.appendChild(toggleButtonGroup); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/ToggleButtonGroup.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/ToggleButtonGroup.doc.ts new file mode 100644 index 0000000000..693e28a72c --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/ToggleButtonGroup.doc.ts @@ -0,0 +1,80 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +import {getExample} from '../../helper.docs'; + +const togglebuttongroupTimePicking = getExample( + 'ui-components/togglebuttongroup-time-picking', + ['jsx', 'js'], +); + +const data: ReferenceEntityTemplateSchema = { + name: 'ToggleButtonGroup', + description: + '`ToggleButtonGroup` allows you to make a single choice out of the number of options provided. This is similar to the [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) component, but without controls such as checkbox or radio button.\n\nYou can utilize our layout components to arrange `ToggleButtonGroup`.', + thumbnail: 'togglebuttongroup-thumbnail.png', + requires: '', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ToggleButtonGroupProps', + description: '', + type: 'ToggleButtonGroupProps', + }, + ], + category: 'UI components', + subCategory: 'Forms', + defaultExample: { + image: 'togglebuttongroup-default.png', + codeblock: { + title: 'Basic ToggleButtonGroup', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-togglebuttongroup.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + 'ToggleButtonGroup is a component designed for streamlined single-choice selection, without any additional details associated with the selection. If you need to allow multiple selections or present associated details, it is recommended to use [ChoiceList](/docs/api/checkout-ui-extensions/components/forms/choicelist) instead.', + sectionSubContent: [ + { + title: 'Label and order', + sectionContent: + 'Use descriptive and concise labels for each Toggle button, and maintain consistency in the terminology used across options. Arrange the Toggle buttons in a logical order that makes sense to users. Consider factors such as alphabetical order, chronological order, or order of importance, depending on the context.', + }, + { + title: 'Number of Toggle buttons', + sectionContent: + 'Avoid overwhelming users with too many Toggle buttons. Ideally, limit the number of choices to a manageable amount, typically between 2 and 7, to prevent decision fatigue and maintain clarity.', + }, + ], + }, + ], + examples: { + description: '', + examples: [togglebuttongroupTimePicking], + }, + related: [ + { + name: 'ToggleButton', + subtitle: 'Component', + url: 'togglebutton', + type: 'Component', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.ts new file mode 100644 index 0000000000..94470c5625 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/ToggleButtonGroup/examples/basic-togglebuttongroup.example.ts @@ -0,0 +1,76 @@ +import { + extension, + ToggleButtonGroup, + ToggleButton, + InlineLayout, + View, + BlockStack, + Text, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const toggleButtonGroup = root.createComponent( + ToggleButtonGroup, + { + value: 'none', + onChange: (value) => { + console.log(`onChange event with value: ${value}`); + }, + }, + [ + root.createComponent(InlineLayout, {spacing: 'base'}, [ + root.createComponent( + ToggleButton, + {id: 'none'}, + root.createComponent( + View, + { + blockAlignment: 'center', + inlineAlignment: 'center', + minBlockSize: 'fill', + }, + 'None', + ), + ), + root.createComponent( + ToggleButton, + {id: 'points-100'}, + root.createComponent( + BlockStack, + {inlineAlignment: 'center', spacing: 'none'}, + [ + root.createComponent(Text, undefined, '100'), + root.createComponent(Text, {appearance: 'subdued'}, 'points'), + ], + ), + ), + root.createComponent( + ToggleButton, + {id: 'points-200'}, + root.createComponent( + BlockStack, + {inlineAlignment: 'center', spacing: 'none'}, + [ + root.createComponent(Text, undefined, '200'), + root.createComponent(Text, {appearance: 'subdued'}, 'points'), + ], + ), + ), + root.createComponent( + ToggleButton, + {id: 'points-300'}, + root.createComponent( + BlockStack, + {inlineAlignment: 'center', spacing: 'none'}, + [ + root.createComponent(Text, undefined, '300'), + root.createComponent(Text, {appearance: 'subdued'}, 'points'), + ], + ), + ), + ]), + ], + ); + + root.appendChild(toggleButtonGroup); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/Tooltip.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/Tooltip.doc.ts new file mode 100644 index 0000000000..666c006cfb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/Tooltip.doc.ts @@ -0,0 +1,50 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'Tooltip', + description: + 'Tooltips are floating labels that briefly explain the function of a user interface element. They must be specified inside the `overlay` prop of an activator component. Currently, activator components are `Button`, `Link`, and `Pressable`.\n\nThe library automatically applies the [WAI-ARIA Tooltip Widget pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/) to both the activator and the tooltip content. Expect screen readers to read the tooltip content when the user focuses the activator.', + requires: '', + thumbnail: 'tooltip-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'TooltipProps', + description: '', + type: 'TooltipProps', + }, + ], + category: 'UI components', + subCategory: 'Overlays', + defaultExample: { + image: 'tooltip-default.png', + codeblock: { + title: 'Basic Tooltip', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-tooltip.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'best-practices', + title: 'Best Practices', + sectionContent: + 'Use tooltips if:\n\n- It’s used for showing information only.\n\n- The information contained in it is not needed by someone to complete their checkout.\n\n- The information can be written in a sentence.', + }, + ], + related: [], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.ts new file mode 100644 index 0000000000..2d0591ad84 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/Tooltip/examples/basic-tooltip.example.ts @@ -0,0 +1,23 @@ +import { + extension, + Icon, + Pressable, + Tooltip, +} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const tooltipFragment = root.createFragment(); + const tooltip = root.createComponent( + Tooltip, + {}, + 'In case we need to contact you about your order', + ); + tooltipFragment.appendChild(tooltip); + const pressable = root.createComponent( + Pressable, + {overlay: tooltipFragment}, + [root.createComponent(Icon, {source: 'questionFill'})], + ); + + root.appendChild(pressable); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/View/View.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/components/View/View.doc.ts new file mode 100644 index 0000000000..a89b014045 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/View/View.doc.ts @@ -0,0 +1,57 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'View', + description: + 'View is a generic container component. Its contents will always be their “natural” size, so this component can be useful in layout components (like `Grid`, `BlockStack`, `InlineStack`) that would otherwise stretch their children to fit.', + requires: '', + thumbnail: 'view-thumbnail.png', + isVisualComponent: true, + type: '', + definitions: [ + { + title: 'ViewProps', + description: '', + type: 'ViewProps', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + image: 'view-default.png', + codeblock: { + title: 'Basic View', + tabs: [ + { + title: 'React', + code: '../../../../../../ui-extensions-react/src/surfaces/customer-account/components/View/examples/basic-view.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/basic-view.example.ts', + language: 'js', + }, + ], + }, + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'accessibility-roles', + title: 'Accessibility roles', + sectionContent: + '| Value | Description |\n| --- | --- |\n| "main" | Used to indicate the primary content. |\n| "header" | Used to indicate the component is a header. |\n| "footer" | Used to display information such as copyright information, navigation links, and privacy statements. |\n| "section" | Used to indicate a generic section. |\n| "complementary" | Used to designate a supporting section that relates to the main content. |\n| "navigation" | Used to identify major groups of links used for navigating. |\n| "orderedList" | Used to identify a list of ordered items. |\n| "listItem" | Used to identify an item inside a list of items. |\n| "unorderedList" | Used to identify a list of unordered items. |\n| "separator" | Used to indicates the component acts as a divider that separates and distinguishes sections of content. |\n| "status" | Used to define a live region containing advisory information for the user that is not important enough to be an alert. |\n| "alert" | Used for important, and usually time-sensitive, information. |', + }, + ], + related: [ + { + subtitle: 'Utility', + name: 'StyleHelper', + url: '/docs/api/checkout-ui-extensions/unstable/components/utilities/stylehelper', + type: 'utility', + }, + ], +}; + +export default data; diff --git a/packages/ui-extensions/src/surfaces/customer-account/components/View/examples/basic-view.example.ts b/packages/ui-extensions/src/surfaces/customer-account/components/View/examples/basic-view.example.ts new file mode 100644 index 0000000000..9ed27629ff --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/components/View/examples/basic-view.example.ts @@ -0,0 +1,11 @@ +import {extension, View} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const view = root.createComponent( + View, + {border: 'base', padding: 'base'}, + 'View', + ); + + root.appendChild(view); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/helper.docs.ts b/packages/ui-extensions/src/surfaces/customer-account/helper.docs.ts new file mode 100644 index 0000000000..c17a7e7594 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/helper.docs.ts @@ -0,0 +1,232 @@ +import type {CodeTabType, ExampleType} from '@shopify/generate-docs'; + +const examplePath = '../../../../../docs/surfaces/checkout/reference/examples'; + +type NonEmptyArray = [T, ...T[]]; +type ExtensionExampleLanguage = 'js' | 'jsx'; +type ExtensionCodeTabConfig = Record< + ExtensionExampleLanguage, + { + title: string; + fileExtension: 'ts' | 'tsx'; + } +>; +const codeExampleTabConfig: ExtensionCodeTabConfig = { + js: { + title: 'JavaScript', + fileExtension: 'ts', + }, + jsx: { + title: 'React', + fileExtension: 'tsx', + }, +}; + +/** + * Returns all examples available, specified with a key for reference. + */ +export function getExamples( + languages: NonEmptyArray, +): Record { + if (!languages || languages.length === 0) { + throw new HelperDocsError( + 'You must define at least one extension code language context you wish to retrieve the example(s) for.', + ); + } + /** + * Provides the code tab for the requested languages in "JavaScript" and "React". + */ + function getExtensionCodeTabs(name: string): CodeTabType[] { + return languages.map((language) => { + return { + code: `${examplePath}/${name}.example.${codeExampleTabConfig[language].fileExtension}`, + language, + title: codeExampleTabConfig[language].title, + }; + }); + } + + // Add new examples here that can be shared across multiples pages. + return { + 'ui-components/checkbox-links': { + description: + 'To provide buyers with additional information or references, couple it with link components seamlessly within checkbox components. This can be done by including links as part of the checkbox label in the checkbox. This will provide an easy way to access relevant content that buyers may need.', + image: 'checkbox-links.png', + codeblock: { + title: 'Embedding links in checkbox components', + tabs: getExtensionCodeTabs('ui-components/checkbox-links'), + }, + }, + 'ui-components/clipboarditem-qrcode': { + description: + 'When displaying a QR code, include an alternative way for the user to get the content', + image: 'clipboard-qrcode.png', + codeblock: { + title: "Copying content of a QR code to the user's clipboard", + tabs: getExtensionCodeTabs('ui-components/clipboarditem-qrcode'), + }, + }, + 'ui-components/clipboarditem-oncopy': { + description: + 'Use the onCopy property to display an icon that swaps to a checkmark when the text is copied.', + image: 'clipboard-oncopy.png', + codeblock: { + title: 'Swapping an icon when the text is copied', + tabs: getExtensionCodeTabs('ui-components/clipboarditem-oncopy'), + }, + }, + 'ui-components/disclosure-and-alignment': { + description: + 'Use the Disclosure component to simplify the user experience and reveal interfaces only when the customer requests it. It also demonstrates how a combination of inline and block layout components can improve the readability of information. By employing these strategies, users can easily scan and comprehend the content, making for a better user experience overall.', + image: 'disclosure-and-alignment.gif', + codeblock: { + title: + 'Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.', + tabs: getExtensionCodeTabs('ui-components/disclosure-and-alignment'), + }, + }, + 'ui-components/loading-skeletons': { + description: + 'When adding content to a layout, incorporate a skeleton loader that renders the approximate size and position of the content during loading. This will provide a seamless transition from skeleton loaders to the content, and prevent any layout shift when the resulting content loads.', + image: 'loading-skeletons.gif', + codeblock: { + title: + 'Using skeleton loaders to prevent layout shifts on content load.', + tabs: getExtensionCodeTabs('ui-components/loading-skeletons'), + }, + }, + 'ui-components/togglebuttongroup-time-picking': { + image: 'togglebuttongroup-time-picking.png', + description: `The ToggleButtonGroup component is ideal for a small set of options. It allows for easy scanning of available choices. Also the component’s big tap target makes it a good choice for enhanced mobile experience. However, in a grid layout, having more than 6 ToggleButtons can get overwhelming and take up too much vertical space. When there are more than 6 choices, consider using the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component instead. `, + codeblock: { + title: 'Displaying a small set of time choices', + tabs: getExtensionCodeTabs( + 'ui-components/togglebuttongroup-time-picking', + ), + }, + }, + 'ui-components/choicelist-survey': { + description: `The base variant’s flexibility allows for the creation of Likert scales using the ChoiceList component. By utilizing layout components, you can easily structure rows and columns for this purpose.`, + image: 'choicelist-survey.png', + codeblock: { + title: 'Custom survey using the base variant', + tabs: getExtensionCodeTabs('ui-components/choicelist-survey'), + }, + }, + 'ui-components/choicelist-details': { + description: `The ChoiceList’s group variant, combined with the details property, allows for the conditional display of information when needed.`, + image: 'choicelist-details.png', + codeblock: { + title: 'Collecting additional information', + tabs: getExtensionCodeTabs('ui-components/choicelist-details'), + }, + }, + 'ui-components/choicelist-time-picking': { + description: `The ChoiceList component is great for presenting a concise list of options, particularly when showcasing time ranges due to its ample horizontal space. However, if there’s more than 5 choices, use the [Select](/docs/api/checkout-ui-extensions/components/forms/select) component instead.`, + image: 'choicelist-time-picking.png', + codeblock: { + title: 'Displaying a short list of time choices', + tabs: getExtensionCodeTabs('ui-components/choicelist-time-picking'), + }, + }, + 'ui-components/sheet-consent': { + description: + 'The Sheet component can be used to display privacy consent preferences in the Checkout interface. Sheet can be defaulted to open for this use case.\n\n This component requires access to [Customer Privacy API](/docs/api/checkout-ui-extensions/unstable/apis/customer-privacy) to be rendered.', + codeblock: { + title: 'Using Sheet to display consent preferences', + tabs: getExtensionCodeTabs('ui-components/sheet-consent'), + }, + }, + 'ui-components/sheet-description-preferences': { + description: + 'In order to save space in the action slot, secondary actions can be placed in the content area.', + image: 'sheet-description-preferences.png', + codeblock: { + title: 'Preferences button is in the description as a link', + tabs: getExtensionCodeTabs( + 'ui-components/sheet-description-preferences', + ), + }, + }, + 'ui-components/sheet-layout-content': { + description: + 'The description can take in layout components to allow for different types of content to be structured in specific ways.', + image: 'sheet-layout-content.png', + codeblock: { + title: 'Using layout component in the description ', + tabs: getExtensionCodeTabs('ui-components/sheet-layout-content'), + }, + }, + 'ui-components/sheet-icon-button-preferences': { + description: + 'An icon button can be used in the secondary actions area to allow for more space for the primary actions.', + image: 'sheet-icon-button-preferences.png', + codeblock: { + title: 'Icon button used for preferences', + tabs: getExtensionCodeTabs( + 'ui-components/sheet-icon-button-preferences', + ), + }, + }, + 'ui-components/switch-custom-label': { + description: + 'This example demonstrates pairing the switch with a custom label and layout while keeping it accessible to screen readers.', + image: 'switch-custom-label.png', + codeblock: { + title: 'Custom label', + tabs: getExtensionCodeTabs('ui-components/switch-custom-label'), + }, + }, + 'ui-components/progress-determinate-state': { + description: + 'In a determinate state, [TextBlock](../titles-and-text/textblock) or [Text](../titles-and-text/text) components can be used to communicate what the progress bar is tracking, and to set clear expectations about the current progress.', + image: 'progress-determinate.png', + codeblock: { + title: 'Determinate state', + tabs: getExtensionCodeTabs('ui-components/progress-determinate-state'), + }, + }, + 'ui-components/qrcode-image': { + description: + 'The QRCode component can display an image in the center. Adding a logo can increase brand trust and set expectations for the action when scanning.', + image: 'qrcode-image.png', + codeblock: { + title: 'With logo', + tabs: getExtensionCodeTabs('ui-components/qrcode-image'), + }, + }, + 'ui-components/qrcode-fill-size': { + description: + 'In most cases the default size should work well. If you need a different size, use `fill` to make it grow to the size of its parent container.', + image: 'qrcode-fill-size.png', + codeblock: { + title: 'Fill size', + tabs: getExtensionCodeTabs('ui-components/qrcode-fill-size'), + }, + }, + }; +} + +/** + * Returns a specific `Example` by name, as specified in `getExamples()`. + * Specify whether you want to include both `js` and `jsx`examples or just one. + */ +export function getExample( + name: string, + languages: NonEmptyArray = ['js'], +): ExampleType { + const example = getExamples(languages)[name]; + if (!example) { + throw new HelperDocsError( + `Could not find a matching example with the name "${name}". Does it exist within the file "docs/reference/helper.docs.ts" in getExamples()?`, + ); + } + return example; +} + +class HelperDocsError extends Error { + name = 'HelperDocsError'; +} + +export const REQUIRES_PROTECTED_CUSTOMER_DATA = + 'access to [protected customer data](/docs/apps/store/data-protection/protected-customer-data) for some properties.'; diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/examples/defaultstyle.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/style/examples/defaultstyle.example.tsx new file mode 100644 index 0000000000..3f462557cb --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/examples/defaultstyle.example.tsx @@ -0,0 +1,9 @@ + + Content + Content + diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/examples/hiding.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/style/examples/hiding.example.tsx new file mode 100644 index 0000000000..78e0af35c7 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/examples/hiding.example.tsx @@ -0,0 +1,8 @@ + + Content + diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/examples/simplecondition.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/style/examples/simplecondition.example.tsx new file mode 100644 index 0000000000..f20d3439ef --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/examples/simplecondition.example.tsx @@ -0,0 +1,9 @@ + alert('press')} + border={Style.default(['base', 'dotted']).when( + {viewportInlineSize: {min: 'small'}}, + ['base', 'dotted', 'none', 'base'], + )} +> + Content + diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.ts b/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.ts new file mode 100644 index 0000000000..71b3639511 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.ts @@ -0,0 +1,18 @@ +import {Style, View, extension} from '@shopify/ui-extensions/customer-account'; + +export default extension('customer-account.page.render', (root) => { + const view = root.createComponent( + View, + { + border: 'base', + padding: 'base', + maxInlineSize: Style.default(200) + .when({viewportInlineSize: {min: 'small'}}, 300) + .when({viewportInlineSize: {min: 'medium'}}, 400) + .when({viewportInlineSize: {min: 'large'}}, 800), + }, + 'Responsive Content', + ); + + root.appendChild(view); +}); diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.tsx b/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.tsx new file mode 100644 index 0000000000..949ef11586 --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/examples/style.example.tsx @@ -0,0 +1,22 @@ +import { + reactExtension, + Style, + View, +} from '@shopify/ui-extensions-react/customer-account'; + +export default reactExtension('customer-account.page.render', () => ( + +)); + +function Extension() { + return ( + + Responsive Content + + ); +} diff --git a/packages/ui-extensions/src/surfaces/customer-account/style/style.doc.ts b/packages/ui-extensions/src/surfaces/customer-account/style/style.doc.ts new file mode 100644 index 0000000000..71fdd1b91e --- /dev/null +++ b/packages/ui-extensions/src/surfaces/customer-account/style/style.doc.ts @@ -0,0 +1,180 @@ +import type {ReferenceEntityTemplateSchema} from '@shopify/generate-docs'; + +const data: ReferenceEntityTemplateSchema = { + name: 'StyleHelper', + description: + 'This is a helper for authoring conditional values for property styles.\n\nWrite complex conditional styles based on one or more conditions, such as viewport sizes and interactive states, in a concise and expressive way.', + requires: '', + isVisualComponent: false, + type: '', + definitions: [ + { + title: 'StyleHelper', + description: '', + type: 'DocsStyle', + }, + ], + category: 'UI components', + subCategory: 'Layout and structure', + defaultExample: { + codeblock: { + tabs: [ + { + title: 'React', + code: './examples/style.example.tsx', + language: 'tsx', + }, + { + title: 'JS', + code: './examples/style.example.ts', + language: 'js', + }, + ], + title: 'Import the Style helper', + }, + }, + examples: { + description: 'This section provides examples of conditions.', + examples: [ + { + description: + "Default styling can be combined with specific conditions. In this example, the Grid's children will be stacked by default and side by side on viewports above the small breakpoint.", + codeblock: { + title: 'Default Style With Conditions', + tabs: [ + { + title: 'React', + code: './examples/defaultstyle.example.tsx', + language: 'tsx', + }, + ], + }, + }, + { + description: + "Using simple conditional styling enables you to specify a styling change when a condition is met. In this example, the View's padding will be loose on hover.", + codeblock: { + title: 'Simple Condition', + tabs: [ + { + title: 'React', + code: './examples/simplecondition.example.tsx', + language: 'tsx', + }, + ], + }, + }, + { + description: + 'Using the `display` property with conditional styles enables you to hide content for certain viewport sizes. In this example, the View will be hidden on small and above screen sizes.', + codeblock: { + title: 'Conditionally hiding content', + tabs: [ + { + title: 'React', + code: './examples/hiding.example.tsx', + language: 'tsx', + }, + ], + }, + }, + ], + }, + subSections: [ + { + type: 'Generic', + anchorLink: 'conditions', + title: 'Conditions', + sectionContent: + 'The following conditions are supported for conditional styles.\n\nMultiple conditions can be set on the same `when` method.\n\n \n\n| Name | Type | Description |\n| --- | --- | --- |\n| "hover" | true | This condition is met when an element is hovered on with the cursor (mouse pointer). |\n| "focus" | true | This condition is met when an element is clicked, tapped on or selected using the Tab key.|\n| viewportInlineSize | {min: "small" | "medium" | "large"} | This condition is met when the device matches the minimum width.|', + }, + ], + related: [ + { + name: 'BlockLayout', + subtitle: 'Component', + url: 'blocklayout', + type: 'Component', + }, + { + name: 'BlockSpacer', + subtitle: 'Component', + url: 'blockspacer', + type: 'Component', + }, + { + name: 'BlockStack', + subtitle: 'Component', + url: 'blockstack', + type: 'Component', + }, + { + name: 'Grid', + subtitle: 'Component', + url: 'grid', + type: 'Component', + }, + { + name: 'GridItem', + subtitle: 'Component', + url: 'griditem', + type: 'Component', + }, + { + name: 'Image', + subtitle: 'Component', + url: 'image', + type: 'Component', + }, + { + name: 'InlineLayout', + subtitle: 'Component', + url: 'inlinelayout', + type: 'Component', + }, + { + name: 'InlineSpacer', + subtitle: 'Component', + url: 'inlinespacer', + type: 'Component', + }, + { + name: 'InlineStack', + subtitle: 'Component', + url: 'inlinestack', + type: 'Component', + }, + { + name: 'List', + subtitle: 'Component', + url: 'list', + type: 'Component', + }, + { + name: 'Pressable', + subtitle: 'Component', + url: 'pressable', + type: 'Component', + }, + { + name: 'ScrollView', + subtitle: 'Component', + url: 'scrollview', + type: 'Component', + }, + { + name: 'SkeletonImage', + subtitle: 'Component', + url: 'skeletonimage', + type: 'Component', + }, + { + name: 'View', + subtitle: 'Component', + url: 'view', + type: 'Component', + }, + ], +}; + +export default data;