Giter Site home page Giter Site logo

ui-extensions's Issues

Incorrect behaviour in webpack build when index source file not found

Please list the package(s) involved in the issue, and include the version you are using

checkout-ui-extensions-run V0.7.0

Describe the bug

When an index.{ts,tsx,js} file is not found, instead of throwing an exception as appears intended, an empty array is returned instead, this causes issues in the generated webpack config which will subsequently fail.

The issue is caused by this section of code in webpack-config.ts, it's clear from the preceding check that it's not meant to return the result (an empty array) if no index source file was found.

https://github.com/Shopify/ui-extensions/blob/main/packages/checkout-ui-extensions-run/src/webpack-config.ts#L228

Steps to reproduce the behavior:

  1. Run checkout-ui-extensions-run serve in a directory with no index.{ts,tsx,js} or src/index.{ts,tsx,js}.

Expected behavior

Exception stating index source file was not found is expected to have been thrown.

Additional context

The fix for this as in the previous check is to change if (srcIndexFiles) { to if (srcIndexFiles.length > 0) {

Unexpected Behavior from `<Layout />`

Considering the following, which has two <Layout /> instances in a <BlockStack /> You can apply this code to argo-checkout-template.

    <BlockStack>
      <CalloutBanner
        title={`The body of this page was rendered by ${extensionPoint}`}
      >
        subtext
      </CalloutBanner>
      {/* <Layout />
       * `500` represents `500px`
       * `0.5` represents `50%`
       * `1` represents `100%` */}
      <Layout
        media={[
          {viewportSize: 'small', sizes: [1, 1], maxInlineSize: 0.95},
          {viewportSize: 'medium', sizes: [300, 0.5], maxInlineSize: 0.95},
          {viewportSize: 'large', sizes: [300, 0.3], maxInlineSize: 0.95},
        ]}
      >
        <BlockStack>
          <Heading>Left Column</Heading>
          <Image source="https://cdn.shopify.com/assets/images/logos/shopify-bag.png" />
        </BlockStack>
        <BlockStack alignment="leading">
          <TextContainer>
            <Heading>Right Column</Heading>
            <HeadingGroup>
              <Heading>My Post-Purchase Extension</Heading>
              <TextBlock>
                It could be a cross-sell extension, product review for past
                purchases, request for more information from the buyer, or
                anything else
              </TextBlock>
              <HeadingGroup>
                <Heading>Description</Heading>
                <TextBlock>
                  This is a non-exhaustive example, demonstrating provided UI
                  components
                </TextBlock>
                <Heading>initialState</Heading>
                <TextBlock>{JSON.stringify(initialState)}</TextBlock>
              </HeadingGroup>
            </HeadingGroup>
          </TextContainer>
          <Button
            onPress={() => {
              console.log(`Extension point ${extensionPoint}`);
            }}
          >
            Log extension point to console
          </Button>
        </BlockStack>
      </Layout>
      <Layout sizes={[0.1]}>
        <Separator />
        <TextContainer spacing="loose" alignment="center">
          <TextBlock>
            Bottom Text <Text emphasized>Stretches </Text>
            across both columns. Bottom Text Stretches across both columns.
            Bottom Text Stretches across both columns. Bottom Text Stretches
            across both columns. Bottom Text Stretches across both columns.
            Bottom Text Stretches across both columns.
          </TextBlock>
          <TextBlock>
            In the <Text role="deletion">First</Text> Second Paragraph, Bottom
            Text Stretches across both columns. Bottom Text Stretches across
            both columns. Bottom Text Stretches across both columns. Bottom Text
            Stretches across both columns. Bottom Text Stretches across both
            columns. Bottom Text Stretches across both columns.
          </TextBlock>
        </TextContainer>
      </Layout>
    </BlockStack>

This code does produce expected results, with the bottom section spanning across the whole screen. However, the bottom section is pushed off to the right. I expected it to be centered.

image

What's really surprising, is if I change the 2nd layout to <Layout sizes={[0.9]}> It renders like this:

image

A numeric TextField's value and onChange should be Number

When using a TextField with type = "number" like this:

<TextField
    label={'Delivery frequency'}
    type="number"
    value={`${denormalizedSellingPlan.fulfillmentIntervalCount.value}`}
    onChange={(value: string) =>
        denormalizedSellingPlan.fulfillmentIntervalCount.onChange(
        // temporary workaround, TextField.onChange should return value as Number
        // and follow the standard https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number
        Number(value),
        )
    }
    />

should we follow input and return a Number instead?

Add changelog to checkout and post-purchase packages

Please list the related package(s)

  • checkout-ui-extensions
  • checkout-ui-extensions-react
  • post-purchase-ui-extensions
  • post-purchase-ui-extensions-react

Describe the changes you are looking for

Currently, we maintain a CHANGELOG for admin-ui-extensions, but not for any of the other packages in this repo.

We should probably maintain a CHANGELOG for every component library in this repo.

Expose the Dynamic Extension Point Location

Please list the related package(s)

checkout-ui-extensions
checkout-ui-extensions-react

If this related to specific APIs or components, please list them here

useExtensionApi()

Is your feature request related to a problem? Please describe.

Please surface the location for dynamic extensions so that we know where in checkout it's rendering. I have multiple use cases that are much more complicated/blocked without this information. Trying to reuse a more generic extension for use in multiple locations but it doesn't know where it is so the content remains the same.

CleanShot 2022-06-24 at 12 11 45

Describe the changes you are looking for

Maybe expose on the same hook where you show the extensions version? I think it's useExtensionApi()?

Describe alternatives you’ve considered

Not aware of an alternative.

Additional context

First run experience: add links to docs + which file to edit for scaffolding project

Please list the related package(s)

If this related to specific APIs or components, please list them here

Is your feature request related to a problem? Please describe.

Currently the scaffolded app renders the string Welcome to the Checkout::Dynamic::Render extension! below the cart. It's easy to miss as it's not visually distinct from the rest of the page. On smaller screens it's completely hidden behind a Rollup. I was initially confused as to why the string wasn't showing up as I usually have devtools open on the side and the page is forced into the smaller layout.

Desktop:

Screenshot 2022-05-25 at 16 09 50

Mobile:

Screenshot 2022-05-25 at 16 10 16

Describe the changes you are looking for

  • Use an extension point which is always visible on all screen sizes
  • Add a link to our documentation
  • Add the file name that needs to be edited to change the extension. Something like Edit file /path/to/file to be able to change this text

Describe alternatives you’ve considered

Additional context

Many scaffolding apps for various frontend frameworks include these. A good example is CRA:

Screenshot 2022-05-25 at 16 20 28

JWT Token In Post-Purchase Extension Invalid Payload

Please list the package(s) involved in the issue, and include the version you are using

"@shopify/post-purchase-ui-extensions": "0.13.2",
"@shopify/post-purchase-ui-extensions-react": "0.13.2",
"react": "^17.0.0"

Describe the bug

I am building a Post-Purchase Extension which makes POST requests to a GraphQL Rails server, which I am trying to authenticate using the JWT token. In the ShouldRender function I am accessing the JWT token from inputData. Then I construct the headers based on this:

extend('Checkout::PostPurchase::ShouldRender', async ({inputData, storage}) => {

  const jwt_token = inputData.token;

  let response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: 'Bearer ' + jwt_token,
    },
    body: ...
  });
});

In my Rails server logs, I can see the request error-ing, due to the missing aud claim, which should be set as the API KEY as per the JWT Shopify specification.

[ShopifyApp::JWT] Failed to validate JWT: [ShopifyApp::JWT::InvalidAudienceError] 'aud' claim does not match api_key

Digging through the Ruby JWT module I can see this error comes from this line here, which leads me to believe something is wrong with the token. Now, inspecting the JS console I log the token and then use the https://jwt.io/ tool to decode the token, which in turn looks like the following & proves it's missing some object keys from the JWT spec:

The token header is missing a "typ": "JWT":

{
  "alg": "HS256"
}

The token payload is missing a few of the Claims from the specification

{
  "iss": "shopify",
  "sub": "a3c59a6b3c451c33b90e68871cd944de",
  "input_data": {
    "extensionPoint": "Checkout::PostPurchase::ShouldRender",
    "initialPurchase": {
      "referenceId": "a3c59a6b3c451c33b90e68871cd944de",
      "customerId": 5788644180212,
      "destinationCountryCode": "GB",
      "totalPriceSet": {
        "shopMoney": {
          "amount": "25.98",
          "currencyCode": "GBP"
        },
        "presentmentMoney": {
          "amount": "25.98",
          "currencyCode": "GBP"
        }
      },
      "lineItems": [
        {
          "product": {
            "id": 6636284346612,
            "metafields": [],
            "title": "Fertilizer",
            "variant": {
              "id": 39467655692532,
              "metafields": [],
              "title": ""
            }
          },
          "quantity": 1,
          "totalPriceSet": {
            "shopMoney": {
              "amount": "19.99",
              "currencyCode": "GBP"
            },
            "presentmentMoney": {
              "amount": "19.99",
              "currencyCode": "GBP"
            }
          }
        }
      ]
    },
    "locale": "en",
    "shop": {
      "id": 1234,
      "domain": "mydomain.myshopify.com",
      "metafields": []
    },
    "version": "unstable"
  },
  "iat": 1642930977
}

Steps to reproduce the behavior:

  • Follow the tutorial here
  • Pass the inputData.token variable to the ShouldRender Extension point (as per my example above)
  • Log it & decode it at https://jwt.io/

Expected behavior

By comparison, the structure of a JWT token described here looks different:

Header

{
  "alg": "HS256",  -- The algorithm used to encode the JWT
  "typ": "JWT",    -- https://tools.ietf.org/html/rfc7519#section-5.1
}

Payload

{
  "iss": "<shop-name.myshopify.com/admin>", -- The shop’s admin domain
  "dest": "<shop-name.myshopify.com>",      -- The shop’s domain
  "aud": "<api key>",         -- The Api key of the receiving app
  "sub": "<user id>",         -- The user the JWT is intended for
  "exp": "<time in seconds>",   -- when the JWT expires
  "nbf": "<time in seconds>",   -- when the JWT activates
  "iat": "<time in seconds>",   -- when the JWT was issued
  "jti": "<random UUID>",   -- A secure random UUID
}

Am I missing something or am I looking at the wrong thing?

Circular dependencies in checkout-ui-extensions docs generation

There are circular dependencies being detected when running yarn docs:checkout to generate documentation for checkout-ui-extensions. If left unchecked, these cause fatal Maximum call stack size exceeded errors.

The culprit of this issue are infinite recursive propType() function calls from scripts/typedoc/shopify-dev-renderer/shared/index.ts. There appears to be some component props that have a nested props object that references itself, thus being a circular dependency and the cause of a stack overflow through infinite recursion. A comment has been left in the file via #265 to outline where the problem occurs and the hacky workaround left in place to work around this unfortunate issue (note that I implemented this workaround while pairing with @lemonmade).

Our hunch is that there is a bug in the internal @shopify/docs-tools package. We will follow up with the team maintaining this package as needed.

Docs: render UI components props in alphabetical order

Please list the package(s) involved in the issue, and include the version you are using

checkout-ui-extensions

Describe the bug

Properties listed in tables don't appear to be sorted in any logical ways making it hard to find props and their descriptions. Sorting them in alphabetical order would be a great improvements (it works really well in Polaris)

Steps to reproduce the behavior:

Visit the PhoneField page on shopify-dev.

Extension API to notify when discount codes are added/removed

Please list the related package(s)

If this related to specific APIs or components, please list them here

  • checkout-ui-extensions-react

Is your feature request related to a problem? Please describe.

  • No

Describe the changes you are looking for

  • Add useApplyDiscountCodeChange to React hooks.

No error message when unregistered extension point is used

Please list the package(s) involved in the issue, and include the version you are using

  • "@shopify/checkout-ui-extensions-react": "^0.15.0",

Describe the bug

When you pick an extension point which is NOT registered in extension.config.yml you're not notified in any way that you're doing something wrong. We should throw some sort of permission error when we detect that.

Steps to reproduce the behavior:

  1. Scaffold new extension.
  2. Keep config as is, but use another extension point in your JS like Checkout::Actions::RenderBefore

Expected behavior

I expected to see some sort of permission error to be thrown.

Screenshots

Additional context

[Docs script] Not matched supported props on shopify.dev for View component

Please list the package(s) involved in the issue, and include the version you are using

"@shopify/post-purchase-ui-extensions": "0.10.1",
"@shopify/post-purchase-ui-extensions-react": "0.10.1",

"@shopify/checkout-ui-extensions-run": "0.7.0",

Describe the bug

I found out that the supported props listed in https://shopify.dev/api/checkout-extensions/components/view are not matched with the implementation. It seems like the API reference is not up to date. I can see there are only two props supported below.
image

But in the implementation, there is no props that shown in the API references above, but more other supported props.

export interface ViewProps {
  /**
   * Adjust the maximum inline size.
   *
   * Numbers less than or equal to 1 are treated as percentages and numbers greater than 1 are treated as pixels.
   *
   * Examples:
   * - `500` represents `500px`
   * - `0.5` represents `50%`
   * - `1` represents `100%`
   */
  maxInlineSize?: number | Responsive<number>;

  /**
   * Adjust the padding.
   *
   * To shorten the code, it is possible to specify all the padding properties in one property.
   *
   * Examples:
   * - `base` means blockStart, inlineEnd, blockEnd and inlineStart paddings are `base`
   * - [`base`, `none`] means blockStart and blockEnd paddings are `base`, inlineStart and inlineEnd paddings are `none`
   * - [`base`, `none`, `loose`, `tight`] means blockStart padding is `base`, inlineEnd padding is `none`, blockEnd padding is `loose` and  blockStart padding is `tight`
   */
  padding?: CSSShorthand<Spacing> | Responsive<CSSShorthand<Spacing>>;

  /**
   * Adjust the background.
   */
  background?: Background | Responsive<Background>;

  /**
   * Sets one or multiple responsive background images.
   */
  backgroundImage?: string | Responsive<string>;

  /**
   * Indicates if the background image should scale its container without cropping
   * and stretching, or scale as large as possible to fill the container and stretching if necessary.
   */
  backgroundFit?: BackgroundFit;

  /**
   * Sets the initial position of the background image.
   * @defaultValue 'center'
   */
  backgroundPosition?: BackgroundPosition;

  /**
   * Sets how background image are repeated.
   * @defaultValue false
   */
  backgroundRepeat?: boolean;

  /**
   * Adjust the border style.
   *
   * To shorten the code, it is possible to specify all the border style properties in one property.
   *
   * Examples:
   * - `base` means blockStart, inlineEnd, blockEnd and inlineStart border styles are `base`
   * - [`base`, `none`] means blockStart and blockEnd border styles are `base`, inlineStart and inlineEnd border styles are `none`
   * - [`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`
   */
  border?: CSSShorthand<BorderStyle> | Responsive<CSSShorthand<BorderStyle>>;

  /**
   * Adjust the border width.
   *
   * To shorten the code, it is possible to specify all the border width properties in one property.
   *
   * Examples:
   * - `base` means blockStart, inlineEnd, blockEnd and inlineStart border widths are `base`
   * - [`base`, `thick`] means blockStart and blockEnd border widths are `base`, inlineStart and inlineEnd border widths are `thick`
   * - [`base`, `thick`, `thick`, `base`] means blockStart border width is `base`, inlineEnd border width is `thick`, blockEnd border width is `thick` and  blockStart border width is `base`
   */
  borderWidth?:
    | CSSShorthand<BorderWidth>
    | Responsive<CSSShorthand<BorderWidth>>;

  /**
   * Adjust the border color.
   */
  borderColor?: BorderColor | Responsive<BorderColor>;

  /**
   * Adjust the border radius.
   *
   * To shorten the code, it is possible to specify all the border width properties in one property.
   *
   * Examples:
   * - `base` means blockStart, inlineEnd, blockEnd and inlineStart border radii are `base`
   * - [`base`, `none`] means blockStart and blockEnd border radii are `base`, inlineStart and inlineEnd border radii are `none`
   * - [`base`, `none`, `tight`, `base`] means blockStart border radius is `base`, inlineEnd border radius is `none`, blockEnd border radius is `tight` and  blockStart border radius is `base`
   */
  borderRadius?:
    | CSSShorthand<BorderRadius>
    | Responsive<CSSShorthand<BorderRadius>>;

  /**
   * Changes the visibility of the element.
   *
   * 'hidden' visually hides the component while keeping it accessible to assistive technology (for example,
   * a screen reader). Hidden elements do not take any visual space contrary to CSS visibility: hidden;
   */
  visibility?: Visibility;

  /**
   * Changes the visibility of the element to assistive technologies.
   *
   * 'hidden' hides the component from assistive technology (for example,
   * a screen reader) but remains visually visible.
   */
  accessibilityVisibility?: AccessibilityVisibility;

  /**
   * Changes the display of the View.
   *
   * 'inline' follows the direction of words in a sentence based on the document’s writing mode.
   * 'block' follows the direction of paragraphs based on the document’s writing mode.
   *
   * @defaultValue 'block'
   */
  display?: Display;

  /**
   * A unique identifier for the View.
   */
  id?: string;
}

Expected behavior

The doc should up to date and align with implementation

[Button]: component add props for supporting change button's background colour and text colour

Please list the related package(s)

"@shopify/post-purchase-ui-extensions": "0.13.0",
"@shopify/post-purchase-ui-extensions-react": "0.13.0",

If this related to specific APIs or components, please list them here

Related API reference: https://shopify.dev/api/checkout-extensions/components/button
Can we add new props to allow customising the background colour and text/font colour for Button component? So that the button style can be aligned with the checkout page in case the store owner changes the theme or customising the checkout page.

Is your feature request related to a problem? Please describe.

N/A

Describe the changes you are looking for

Support new props: e.g. textColour, backgroundColour?

Describe alternatives you’ve considered

N/A

Additional context

To make sure the post purchase page has the same styling as the checkout/payment page.

Post purchase <View/> component border not working anymore

Please list the package(s) involved in the issue, and include the version you are using

Describe the bug

<View border="base" padding="base"> as per your example at https://github.com/Shopify/ui-extensions/blob/main/packages/post-purchase-ui-extensions-react/src/components/View/examples/basic-view.example.tsx#L7 padding and a border should be added around the <View/> element.

The <View/> component displayed a border and padding when the border and padding attributes were present.

Steps to reproduce the behavior:

  1. Add the following component to a post-purchase checkout extension: <View border="base" padding="base"></View>

Expected behavior

A border and padding around the element.

Screenshots

Additional context

Missing error message when throwing any error from an extension

Please list the package(s) involved in the issue, and include the version you are using

  • @shopify/checkout-ui-extensions-react 0.15.0
  • @shopify/shopify-cli-extensions 0.2.1

Describe the bug

When a developer tries to render a string-based node like <div /> the error message isn't really descriptive as to why that's not allowed. The current error message just says:

main.js:10638 The above error occurred in the <div> component:

Problem is that there is no error above this one.

Steps to reproduce the behavior:

  1. Create extension and render a <div /> somewhere

Expected behavior

An error message in the console which mentions that these kind of components cannot be used.

Screenshots

Screenshot 2022-05-25 at 15 13 55

Additional context

DX when running yarn server too soon

Devs can run yarn server before running yarn generate, which results in an unfriendly webpack error message.

We can improve this scenario by removing server.scripts from package.json and/or augmenting argo-run.

Current output

(node:62170) UnhandledPromiseRejectionWarning: WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.entry[1] should be a string.
   -> A non-empty string
    at webpack (/Users/jared.dykstra/src/github.com/Shopify/argo-checkout-template/node_modules/webpack/lib/webpack.js:31:9)
    at dev (/Users/jared.dykstra/src/github.com/Shopify/argo-checkout-template/node_modules/@shopify/argo-run/build/node/dev.js:36:41)
    at run (/Users/jared.dykstra/src/github.com/Shopify/argo-checkout-template/node_modules/@shopify/argo-run/build/node/index.js:59:15)
(node:62170) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:62170) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
✨  Done in 1.40s.

Sentry crashes a post-purchase extension

Packages:
"@sentry/browser": "^6.13.2", "@sentry/tracing": "^6.13.2", "@shopify/post-purchase-ui-extensions": "0.10.1"

I'm trying to debug the post-purchase extension code using Sentry. But right after importing Sentry packages - the extension stops working. Everything works like a charm when I don't import Sentry.

The code:

import {
  extend,
  render,
  useExtensionInput,
  BlockStack,
  Button,
  CalloutBanner,
  Heading,
  Image,
  Layout,
  TextBlock,
  TextContainer,
  View,
} from '@shopify/post-purchase-ui-extensions-react';

import * as Sentry from '@sentry/browser';
import {Integrations} from '@sentry/tracing';

extend('Checkout::PostPurchase::ShouldRender', async ({inputData, storage}) => {
  const initialState = await getRenderData();
  const render = true;

  if (render) {
    // Saves initial state, provided to `Render` via `storage.initialData`
    await storage.update(initialState);
  }
  return {
    render,
  };
});
// Simulate results of network call, etc.
async function getRenderData() {
  return {
    couldBe: 'anythinge',
  };
}
/**
 * Entry point for the `Render` Extension Point
 *
 * Returns markup composed of remote UI components.  The Render extension can
 * optionally make use of data stored during `ShouldRender` extension point to
 * expedite time-to-first-meaningful-paint.
 */
render('Checkout::PostPurchase::Render', () => <App />);
// Top-level React component
export function App() {
  const {extensionPoint, storage} = useExtensionInput();
  const helloWorld = useExtensionInput();
  console.log('hey1', helloWorld);
  const initialState = storage.initialData;
  return (
    <BlockStack spacing="loose">
      <CalloutBanner title="Post-purchase extension template">
        Use this template as a starting point to build a great post-purchase
        extension.
      </CalloutBanner>
      <Layout
        maxInlineSize={0.95}
        media={[
          {viewportSize: 'small', sizes: [1, 30, 1]},
          {viewportSize: 'medium', sizes: [300, 30, 0.5]},
          {viewportSize: 'large', sizes: [400, 30, 0.33]},
        ]}
      >
        <View>
          <Image source="https://cdn.shopify.com/static/images/examples/img-placeholder-1120x1120.png" />
        </View>
        <View />
        <BlockStack spacing="xloose">
          <TextContainer>
            <Heading>Post-purchase extension</Heading>
            <TextBlock>
              Here you can cross-sell other products, request a product review
              based on a previous purchase, and much more.
            </TextBlock>
          </TextContainer>
          <Button
            submit
            onPress={() => {
              // eslint-disable-next-line no-console
              console.log(`Extension point ${extensionPoint}`, initialState);
            }}
          >
            Primary button
          </Button>
        </BlockStack>
      </Layout>
    </BlockStack>
  );
}

Form input components unresponsive after submission

Please list the package(s) involved in the issue, and include the version you are using

shopify/admin-ui-extensions v1.0.1
shopify/admin-ui-extensions-react v1.0.1
shopify/admin-ui-extensions v0.12.1
shopify/admin-ui-extensions-react v0.12.1

Describe the bug

If the create form has a Radio button, Checkbox or Select component and the user cancels out of the form and immediately returns to it, the components appear to be unresponsive.

Steps to reproduce the behavior:

  1. Build a create form that contains at least two radio buttons.
  2. In the subscription section of the product edit page, click on Add new option.
  3. Fill out the form. Confirm that you can change the radio button selection several times.
  4. Click on the cancel button.
  5. Return to the same form and attempt to select different values for the radio button.
  6. The radio buttons should appear unresponsive at this point.

Expected behavior

  1. Build a create form that contains at least two radio buttons.
  2. In the subscription section of the product edit page, click on Add new option.
  3. Fill out the form. Confirm that you can change the radio button selection several times.
  4. Click on the cancel button.
  5. Return to the same form and attempt to select different values for the radio button.
  6. The radio buttons should appear responsive, and the component's state should be updated accordingly.

Screenshots

2021-12-21.13-05-10.mov

Additional context

Source code for the create form:

import React from 'react';
import {
  BlockStack,
  Button,
  Card,
  CardSection,
  Radio,
  StackItem,
  useContainer,
} from '@shopify/admin-ui-extensions-react';

function Create() {
  const { close, done } = useContainer();
  const [discountType, setDiscountType] = React.useState();

  React.useEffect(() => {console.log('mounted');setDiscountType()}, []);

  React.useEffect(() => console.log(discountType), [discountType]);

  return (
    <>
      <BlockStack vertical={true}>
        <Card title="Create Selling Plan" sectioned={true}>
          <CardSection>
            <BlockStack vertical={true} spacing="tight">
              <StackItem>
                <Radio
                  label="Discount (%)"
                  value="1"
                  name="discountGroup"
                  checked={discountType === '1'}
                  onChange={setDiscountType}
                />
              </StackItem>
              <StackItem>
                <Radio
                  label="Flat amount ($)"
                  value="2"
                  name="discountGroup"
                  checked={discountType === '2'}
                  onChange={setDiscountType}
                />
              </StackItem>
            </BlockStack>
          </CardSection>
        </Card>
        <Button title="Close" onPress={close} />
        <Button title="Done" onPress={done} />
      </BlockStack>
    </>
  );
}

export default Create;

Export all interfaces and types of post-purchase extensions

Please list the related package(s)

"@shopify/post-purchase-ui-extensions": "0.13.0",
"@shopify/post-purchase-ui-extensions-react": "0.13.0",

If this related to specific APIs or components, please list them here

N/A

Is your feature request related to a problem? Please describe.

It is not kind of a problem, but more like a request. Can we export all defined interfaces/models/types from the package: @shopify/post-purchase-ui-extensions? Currently only the top level interfaces are export which is good:

export type {
  PostPurchaseRenderApi,
  PostPurchaseShouldRenderApi,
  PostPurchaseShouldRenderResult,
  ChangeType,
  ExplicitDiscountType,
} from './post-purchase';

But that will be more easier and helpful for people who are also using the Typescript to develop the post-purchase extension points if we can export all other types/interfaces, especially the following types/interfaces:

type CalculateChangesetResult =
  | CalculateChangesetUnprocessedResult
  | CalculateChangesetProcessedResult;

interface CalculatedPurchase

type Changes = (
  | AddVariantChange
  | AddShippingLineChange
  | SetMetafieldChange
  | AddSubscriptionChange
)[];

Is there any special reason or consideration that those interfaces/types are not export out?

  • make developer's life more easier
  • make sure the lint tool not complain the typing/linting issue

Describe the changes you are looking for

Describe alternatives you’ve considered

N/A

N/A

Additional context

N/A

JSX type errors caused by multiple versions of `@types/react`

Please list the package(s) involved in the issue, and include the version you are using

  • @shopify/checkout-ui-extensions-react 0.15.0
  • @shopify/shopify-cli-extensions 0.2.1

Describe the bug

A new projected created by our CLI with the typescript-react template has type errors.

Steps to reproduce the behavior:

  1. Run shopify extension create and follow instructions (pick the ´typescript-react` template
  2. Navigate to the generated extension folder
  3. Open src/index.tsx in your editor -> Type ERROR

Expected behavior

There should be no type errors when creating a brand new extension. This doesn't make for a good first time impression.

Screenshots

Screenshot 2022-05-25 at 12 10 05

Additional context

Did some digging and the issue is caused by multiple versions of @types/react being present at the same time. One version v17.0.45 is installed by being a direct dependency of @remote-ui/react and the other one is coming from @types/react-reconciler which just has "@types/react": "*" listed in its dependencies. This leads to that package installing @types/react v18.0.9 on top of the already existing 17.0.45. Because both packages define the same types globally, there is a conflict and we'll end up with type errors in our editor as pictured above.

APIs for read/write SMS marketing consent

SMS marketing partners have made a strong request to allow for customized SMS marketing consent capture in checkout, and to not be forced to only use the 1P feature we offer for this.

Since this feature can be optionally turned off in checkout using /settings, there is no real way (except on app review) to prevent partners from asking a merchant to turn off the 1P capture feature, and creating an extension which captures SMS compliance at checkout through an extension.

To avoid this being read/written to using the external call capability, we should add an extension API for it. This API should allow:

  • An extension to know if the first party SMS compliance collection setting is enabled in the admin for the shop
  • An extension to read the state of the field for this customer
  • An extension to write to this field

This has also been committed to by us (including Tobi/Glen) to Yotpo. Context from Egan Cheung below:

Hey Mani! Sorry we didn’t get to chat this through more deliberately, but a couple of things happened in rapid succession:

  1. Tomer spoke to Glen about his concerns around SMS consent collection as a whole and he scheduled a time to review with them.
  2. In the intervening time, Tomer spoke to Tobi about his concerns, specifically around customizing the UI and Tobi told him to use C1 checkout extensions to customize SMS consent collection.
  3. Also in the intervening time, I caught Glen up about the list of concerns Yotpo had and that the one we had not committed to yet was customizing the box. I let Glen know that one solution being considered was checkout extensions, though I did relay that due to the additive principle, we did not have alignment yet with the checkout team on this. That being said, in full transparency, I argued that I was in favour of it because:
    the addition of a checkout extension is additive, and that would be the only thing we would allow
    removal of the native sms collection would need to be manual (or simply not turned on), so the extension itself is not substituting or subtracting we would not be able to technically stop it from happening, anyway

Considering the arguments in 3a,b and c and with the subsequent knowledge that Tobi had already encouraged them to do so, Glen and I went in confirming that option to Tomer.

[Discussion] Allow to change the text font on post purchase page

Please list the related package(s)

"@shopify/post-purchase-ui-extensions": "0.13.0",
"@shopify/post-purchase-ui-extensions-react": "0.13.0",

If this related to specific APIs or components, please list them here

N/A

Is your feature request related to a problem? Please describe.

N/A

Describe the changes you are looking for

Is it feasible to allow to change font/add new font on post purchase extension page? Or does the post purchase page use the same font as the font used in checkout/payment page ALWAYS?

N/A

Describe alternatives you’ve considered

N/A

Additional context

Surface React Hook to fetch Product & Collection Data

Please list the related package(s)

@shopify/checkout-ui-extensions-react

If this related to specific APIs or components, please list them here

To help facilitate with realtime product data fetching as well as contextual product data based on the customer:

  • currency
  • b2b price rules
  • language

Please consider surfacing a way to communicate with the storefront api from our extension. Most apps are not eligible for the storefront api and so surfacing this in checkout would greatly improve both developer and customer experience (less chance for stale data).

Is your feature request related to a problem? Please describe.

It's becoming really difficult to store all the required product data for a checkout extension when there's so many variations a customer say see (pricing, language). Leveraging the storefront API to fetch data is performant and already support contextual api calls.

Describe the changes you are looking for

Please surface a React hook to fetch product data by gid or collection gid. It would be great if the following were support:

Describe alternatives you’ve considered

Storing all the data in a metafield or server-side and fetch via api call. If we're doing an external api call to fetch the data, it seems more performant to leverage the Storefront api at that point.

Additional context

[Docs script] Preserve unique locals

For example type Size in BlockSpacing, Text, and Layout are all different but not treated that way. Currently docs for Layout are incorrect and listing the string literal values for BlockSpacing.

Automatically generate docs for Conditional Prop Style Helpers from code

Problem

This is a follow-up issue from Document Conditional Props using a Static file.

The conditional prop style helper docs are managed in a static markdown file. This will be hard to maintain long-term.

Solution

The exact solution will vary depending on how the conditional props have been implemented (at this time it's not clear).

  • In the ui-extensions components() script generator, you'll need to call the createDependencyGraph() function from docs-tools for a file that exports the style helpers
  • You may need to support certain new TS types from within the docs-tools package
  • You may also need to adjust the propTypes() in ui-extensions to handle them

EDIT: Fixed typo in createDependencyGraph function name - @marvinhagemeister

Add a Date picker form field component

Please list the related package(s)

checkout-ui-extensions-react

If this related to specific APIs or components, please list them here

Textfield

Describe the changes you are looking for

Can we consider adding a date picker as a ui component? Even just using TextField + browser date field.https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date

The use case is delivery date form field for products that require specifying a date such as flower delivery or food where the customer has to be home to receive.

Describe alternatives you’ve considered

Textfield with custom formatting to enter a date (prone to error from customers) and a custom Polaris-like calendar component using buttons.

Post-Purchase API Requests

Please list the related package(s)

argo-post-purchase

If this related to specific APIs or components, please list them here

Post purchase initialPurchase API data

Is your feature request related to a problem? Please describe.

I'm having to call the Shopify checkout API to get all the information I need for eligibility which is causing a major problem:

  • The response is sometimes taking too long on Shop Pay which causes the post purchase extension to not fire when it actually should have.

I can't really cache this information since it's different for every checkout instance.

Describe the changes you are looking for

I am hoping the team might be able to reconsider surfacing additional data points to prevent the need of an API call:

Customer first & last name

Right now I call the customer API to grab the first & last name since I use that to personalize the offer. There's no other way get this information. I wonder if it could be solved by passing in the primary billing address like the checkout extension does: https://github.com/Shopify/argo/blob/main/packages/argo-checkout/src/extension-points/api/standard/index.ts#L262 & https://github.com/Shopify/argo/blob/main/packages/argo-checkout/src/extension-points/api/standard/index.ts#L394

Product Tags & (Vendor/SKU)

Merchants sometimes want to limit post purchase eligibility by the products ordered based on tags and vendor/sku and this isn't surfaced on the Product interface: https://github.com/Shopify/argo/blob/main/packages/argo-post-purchase/src/extension-points/api/post-purchase/post-purchase.ts#L89

Honestly, vendor/sku is less important. Is there no efficient way to pass through the tags? It's such a key component to merchant merchandising efforts.

Subtotal

You're surfacing totalPriceSet (https://github.com/Shopify/argo/blob/main/packages/argo-post-purchase/src/extension-points/api/post-purchase/post-purchase.ts#L67) which is great but can we get a subtotal value that excludes shipping and tax? Given tax and shipping are specific to the customer, some merchants like targeting dollar thresholds based on the subtotal since that's more consistent across customers.

Line Items ID

When successfully applying a changeset, can we get the line item ids returned? It's for internal tracking and to remove if somehow payment is due.

Describe alternatives you’ve considered

Currently calling 1-2 Shopify APIs during the eligibility determination which wasn't a huge issue but is starting to become one with Shop Pay.

Additional context

n/a?

Discount metafields are not available to read in a checkout ui extension.

Please list the package(s) involved in the issue, and include the version you are using

  • checkout-ui-extensions v0.17.1
  • checkout-ui-extensions-react v0.17.1
  • shopify product_discounts

Describe the bug

When creating a product_discount extension / shopify function, we are adding metafield data into a namespace/key that is attached to the new discount being created.

Our expectation was that we could then read this metafield data from the checkout-ui-extension by specifying the namespace/key in the shopify.ui.extension.toml file.

However, the data is not being shown in the extension appMetafields.

After some discussion in the Shopify discord, it was mentioned that this use case may not have been considered yet.
https://discord.com/channels/842813079926603828/993570246361362462/994316477442302093

Steps to reproduce the behavior:

  1. Create new product_discount extension as per tutorial
  2. On create, add metafields using specific namespace/key combination and include in the discount data.
  3. Create new checkout ui extension
  4. Update metafields section of shopify.ui.extension.toml to request access to the namespace/key from the discount extension.
  5. In checkout-ui extension react code, console log extensionApi.appMetafields and you'll find it empty

Expected behavior

Expectation is that metafield data for the specified namespace/key combo will be available for the checkout ui extension to view and use when rendering the checkout extension.

[Docs script] Missing types in post-purchase docs

Please list the package(s) involved in the issue, and include the version you are using

argo-post-purchase package

Describe the bug

The following types are not outputting / rendering in the API reference:

  • Changeset token
  • ChangesetResult
  • ChangesetProcessingStatus
  • Calculatedpurchase
  • Updatedlineitem
  • Addedtaxline
  • Added shipping line

Steps to reproduce the behavior:

  1. Run yarn docs:checkout
  2. In shopify.dev check the updated files by running a local server
  3. Browse the page at https://shopify-dev.myshopify.io/api/checkout/extension-points/api
  4. Notice that the listed types do not appear

Expected behavior

Types output to the page

Screenshots

Additional context

`initialPurchase` is missing `token` property

initialPurchase of PostPurchaseRenderApi takes the type of Purchase but it seems to be missing the newly-added token property.

Type:

interface Purchase {
  /** Initial purchase's unique identifier */
  referenceId: string;
  customerId?: string;
  destinationCountryCode?: string;
  totalPriceSet: MoneyBag;
  /** Items being purchased */
  lineItems: LineItem[];
}

Actual payload:

referenceId: "51df3707...",
customerId: 3914168172700,
destinationCountryCode: "CA",
totalPriceSet: {...},
lineItems: [{}],
token: "eyJhb..."

Thanks 👋

Banner onDismiss callback not firing (@shopify/checkout-ui-extensions-react)

Please list the package(s) involved in the issue, and include the version you are using

"@shopify/app": "^3.0.24",
"@shopify/checkout-ui-extensions-react": "^0.17.0",
"@shopify/cli": "^3.0.24",
"react": "^17.0.2"

Describe the bug

onDismiss does not seem to fire for the <Banner> component? I double checked everything so I don't think it's on my end?

Steps to reproduce the behavior:

  1. Added the following code:
<Banner 
                status="success" 
                onDismiss={() => console.log("onDismiss!")}
                title={`${product.title} was successfully added to your cart.`}
/>
  1. Clicked the X button on the banner:
    CleanShot 2022-06-23 at 09 31 58

  2. The console log never fires.
    4 .The following dev tools error message is shown:
    CleanShot 2022-06-23 at 09 32 52

Expected behavior

OnDismiss callback fires allowing me to set state and hide banner.

Docs: the `children` property of UI components is not listed

Please list the package(s) involved in the issue, and include the version you are using

This issue applies to checkout-ui-extensions

Describe the bug

The props table for UI components does not list the children as an option. In some case, like the Checkbox, it would be great to be able to define how the children is used (as <label> for the checkbox in this case). In other cases, like the Divider, its not obvious that it accepts a children and it opens a set of UI possibilities.

Steps to reproduce the behavior:

Visit the Divider page in shopify.dev.

Expected behavior

children is part of the props table, or specified in some way. This might not be as accurate for the vanilla JS context though. Something to consider.

Screenshots

image

Changes in Checkout::PostPurchase::ShouldRender not applied?

Please list the package(s) involved in the issue, and include the version you are using

"@shopify/post-purchase-ui-extensions": "0.10.1",
"@shopify/post-purchase-ui-extensions-react": "0.10.1",

Describe the bug

I'm following the guide at https://shopify.dev/apps/checkout/post-purchase/getting-started-post-purchase-extension. Only the sample code runs. No changes in the callback inside "Checkout::PostPurchase::ShouldRender" are applied.

The changes in Checkout::PostPurchase::Render are visible on manual reload. (saving the file triggers a hot-reload but the following error is shown in the console: ExtensionSandboxPostPurchase.latest.en.5bf54cf4d521fa29dde1.worker.js:1 Uncaught (in promise) Error: No 'reload' method is exposed on this endpoint)

Steps to reproduce the behavior:

Follow the guide at https://shopify.dev/apps/checkout/post-purchase/getting-started-post-purchase-extension
At step 3, the page should look like the screenshot in the guide. It should show this image: https://cdn.shopify.com/s/files/1/0551/4084/3576/products/[email protected]

Instead, the image is not loaded. Only the "Click me" button is shown.

Expected behavior

The results should be the same as the step by step guide.

Additional context

I have also tried restarting the devlopment server, a different browser in private mode, etc.

Add Modal component

Please list the related package(s)

checkout-ui-extensions-react

If this related to specific APIs or components, please list them here

components

Is your feature request related to a problem? Please describe.

We'd like to use it to pop a confirmation.

Describe the changes you are looking for

make Modal component available for Post Purchase extension

Describe alternatives you’ve considered

Nothing else

Additional context

Requesting this based on the description of https://github.com/Shopify/post-purchase-ui
If it's already planned or on the way to release, just close this ticket.

Publish Packages and Documentation easier with automation

Pain Points

  • Time in which documentation changes vs when its published can be a long time, devs need to tophat their doc changes when they make changes in checkout-web
  • Devs can easily add breaking changes to doc generation, this should break the build or at least warn so it can be fixed by the dev who introduced the issue
  • Developers can't easily preview what the documentation will look like on shopify-dev - requires a manual process of copying packages to ui-extensions and then running yarn docs:checkout, which generates files in the local shopify-dev repo, then a dev needs to run that using dev up or spin to preview the changes.

Error with `Post Purchase UI React Package`

There is a really useful package that I have been trying to get to work for the last 5 days.

Here is the link to the package:
https://github.com/Shopify/post-purchase-ui

There have also been 3 issues raised about this packaging all raising the same problem in the package.

There has only been 1 contributor on this package, I have tried to contact him with no luck.

I was wondering if someone in the Shopify team could take a look at this package and solve this tiny little issue that keeps coming up.

Here are a few discoveries/documentation about the issue:

  • The package Readme file wants us to use the addWebpackConfig function to the webpack config, but once that is added, the following error occurs:
error - ./node_modules/@shopify/polaris/dist/esnext/components/ExceptionList/ExceptionList.css 1:0 ┃ Module parse failed: Unexpected character '@' (1:0) ┃ You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders ┃ > @charset "UTF-8"; ┃ | .Polaris-ExceptionList_1wvyn{ margin:0; padding:0; list-style:none; } ┃ |

I have tried a lot of different things to make it work but no luck. Hope someone can help

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.