Skip to content
This repository has been archived by the owner on May 10, 2023. It is now read-only.

Advanced Topics

yusufsipahi edited this page Jul 21, 2020 · 23 revisions

1. APL Commands

Jsx For Apl provides contracts for APL Commands. Therefore it leverages command declarations within typescript usage. The set of usable commands interfaces can be found under Which APL Components does Jsx for Apl provide section.

The following sample demonstrates the usage of AnimateItem command inside onMount property.

// FruitApl.tsx

import * as React from "react";
import { Frame, Container, Text, Image, APL, MainTemplate, Command } from "ask-sdk-jsx-for-apl";

export class FruitApl extends React.Component<{ fruit: object }> {
  
  public render() {
    return (
      <APL>
        <MainTemplate>
          <Frame width="100vw" height="100vh" backgroundColor="rgb(22,147,165)">
            <Container
              width="100vw"
              height="100vh"
              alignItems="center"
              justifyContent="spaceAround"
            >
              <Text text="${this.props.fruit.title}" fontSize="50px" color="rgb(251,184,41)" />
              <Image
                source="${this.props.fruit.image}"
                height="60vh"
                width="30vh"
                scale="best-fit"
                onMount={[this.buildAnimateCommand()]}
              />
            </Container>
          </Frame>
        </MainTemplate>
      </APL>
    );
  }

  private buildAnimateCommand(): Command {
    const command: Command = {
      type: "AnimateItem",
      duration: 600,
      easing: "ease-in-out",
      value: [
        {
          property: "opacity",
          from: 0,
          to: 1,
        },
        {
          property: "transform",
          from: [
            {
              translateX: 200,
            },
            {
              rotate: 90,
            },
          ],
          to: [
            {
              translateX: "0",
            },
            {
              rotate: 0,
            },
          ],
        },
      ],
    };
    return command;
  }
}

In case of using Execute Command Directive with Jsx For Apl, token property must be provided to APL component: <APL token="token_name">.

In case of using User-defined Commands with Jsx For Apl, commands property must be provided to APL component: <APL commands={commands_map}>

2. Responsive Templates

Currently parent-child component relationship for Responsive Templates(AlexaImageList, AlexaLists, AlexaPaginatedList, AlexaTextList) is not supported by Jsx for APL yet.

The solution of providing items to these Responsive Templates can be implemented via populating their listItems property.

// MyImageList.jsx

import { APL, MainTemplate } from "ask-sdk-jsx-for-apl";
import { AlexaImageList } from "ask-sdk-jsx-for-apl/alexa-layouts";

const imageList = [
  {
    primaryText: "First list item",
    secondaryText: "Secondary text",
    imageSource: "https://d2o906d8ln7ui1.cloudfront.net/images/md_gruyere.png"
  }
];

export class MyImageList extends React.Component {
  render() {
    return (
      <APL>
        <MainTemplate>
          <AlexaImageList listItems={imageList} imageBlurredBackground={true} />
        </MainTemplate>
      </APL>
    );
  }
}

3. APL Document Properties

Jsx For Apl has one to one property mapping with APL Document Properties inside APL component. You can check some of the example use cases below.

3.1. APL Resources & Styles

Skill developers may need to use Resources and/or Styles rather than binding data to a component on runtime utilizing React Props or React Context.

In that case resources and/or styles must be provided to APL component.

// MyStylesAndResourcesApl.jsx
...
const resources = [
  {
    colors: {
      "MyBlue": "#0022f3"
    }
  }
];

const styles = {
  textJsxStyle: {
    values: [
      {
        fontSize: 24,
        color: "@MyBlue"
      }
    ]
  }
}

export class MyStylesAndResourcesApl extends React.Component {
  render() {
    return (
      <APL resources={resources} styles={styles}>
        <MainTemplate>
          <Text style="textJsxStyle" text="Testing Jsx Styles" />
        </MainTemplate>
      </APL>
    );
  }
}

3.2. APL Data Sources

Skill developers may need to use APL Data Sources and use them via APL Data-Binding rather than binding data to a component on runtime utilizing React Props or React Context.

When there is a need of using APL Data Source, data source object must be provided to dataSources property of APL component.

// FruitApl.jsx
...
export class FruitApl extends React.Component {
    render() {
        const fruitData = {
            apple: {
                title: "apple",
                image: "https://m.media-amazon.com/images/G/01/voicehub/vesper_fruit_skill/licensed_images/Apple.jpg"
            }
        };
        return (
            <APL dataSources={fruitData}>
            <MainTemplate parameters={["payload"]}>
              <Frame width="100vw" height="100vh" backgroundColor="rgb(22,147,165)">
                <Container width="100vw" height="100vh" alignItems="center" justifyContent="spaceAround">
                  <Text text="${payload.apple.title}" fontSize="50px" color="rgb(251,184,41)" />
                  <Image source="${payload.apple.image}" height="60vh" width="30vh" scale="best-fit" />
                </Container>
              </Frame>
            </MainTemplate>
          </APL>
        );
    }
}

3.3. APL Layout

The defined React components inside a skill can be used multiple times to serve different content. They basically serve like APL Layout.

There can be times when skill developers want to reduce directive payload size and using APL Layout can be a solution for this situation.

// MySkillApl.jsx

import * as React from "react";
import omit from 'lodash/omit';
import { APL, MainTemplate, APLComponent } from "ask-sdk-jsx-for-apl";

//Define layouts json to push into APL.
const layouts = {
  MyLayout: {
    parameters: [
      "parameterText"
    ],
    item: [
      {
        type: "Text",
        text: "${parameterText}",
        width: "100%"
      }
    ]
  }
}

//Create React Components for the defined layouts.
const MyLayout = (props) => {
  return (
    <>
      <APLComponent definition={{ ...omit(props, ['children']), type: 'MyLayout' }}>
       {props.children}
      </APLComponent>
    </>
  );
}

//Use Defined Layout React Component inside APL.
export class MySkillApl extends React.Component {
  render() {
    return (
      <APL layouts={layouts}>
        <MainTemplate>
          <MyLayout parameterText="Testing Jsx Layouts" />
        </MainTemplate>
      </APL>
    );
  }
}

If you are coding with typescript, you can even leverage IDE auto-completion ability by defining props for your Layout component.

// MyLayout.tsx
...
export interface MyLayoutProps {
  parameterText?: string;
}

//Create React Components for the defined layouts.
export MyLayout = (props: React.PropsWithChildren<MyLayoutProps>) => {
  return (
    <>
      <APLComponent definition={{ ...omit(props, ['children']), type: 'MyLayout' }}>
       {props.children}
      </APLComponent>
    </>
  );
}

3.4. VectorGraphic

To use VectorGraphic component with Jsx For Apl, graphics property must be provided inside APL component following Vector Graphic Format guideline.

// MyGraphicsApl.jsx

import * as React from "react";
import { APL, MainTemplate, VectorGraphic } from "ask-sdk-jsx-for-apl";

const graphics = {
  parameterizedCircle: {
    type: "AVG",
    version: "1.0",
    height: 100,
    width: 100,
    parameters: [
      {
        name: "circleColor",
        type: "color",
        default: "black"
      },
      {
        name: "circleBorderWidth",
        type: "number",
        default: 2
      }
    ],
    items: [
      {
        type: "path",
        pathData: "M25,50 a25,25 0 1 1 50,0 a25,25 0 1 1 -50,0",
        stroke: "${circleColor}",
        strokeWidth: "${circleBorderWidth}",
        fill: "none"
      }
    ]
  }
}

export class MyGraphicsApl extends React.Component {
  render() {
    return (
      <APL graphics={graphics}>
        <MainTemplate>
          <VectorGraphic source="parameterizedCircle" width={100} height={100}
            circleColor="red" circleBorderWidth={15} />
        </MainTemplate>
      </APL>
    );
  }
}
Clone this wiki locally