diff --git a/AdaptiveCards/authoring-cards/getting-started.md b/AdaptiveCards/authoring-cards/getting-started.md index 5a9dcea3a..6b27902e4 100644 --- a/AdaptiveCards/authoring-cards/getting-started.md +++ b/AdaptiveCards/authoring-cards/getting-started.md @@ -84,7 +84,7 @@ Actions add buttons to the card. These can perform a variety of actions, like op ## Learn More -* [Browse Sample cards](http://adaptivecards.io/samples/) for inspiration -* Use the [Schema Explorer](http://adaptivecards.io/explorer) to browse the available elements -* Build a card using the [Interactive Visualizer](http://adaptivecards.io/visualizer/) -* [Get in touch](http://adaptivecards.io/connect) with any feedback you have +* [Browse Sample cards](https://adaptivecards.io/samples/) for inspiration +* Use the [Schema Explorer](https://adaptivecards.io/explorer) to browse the available elements +* Build a card using the [Interactive Visualizer](https://adaptivecards.io/visualizer/) +* [Get in touch](https://adaptivecards.io/connect) with any feedback you have diff --git a/AdaptiveCards/authoring-cards/text-features.md b/AdaptiveCards/authoring-cards/text-features.md index 34b1177d1..46df794ac 100644 --- a/AdaptiveCards/authoring-cards/text-features.md +++ b/AdaptiveCards/authoring-cards/text-features.md @@ -2,16 +2,21 @@ title: Text Features author: matthidinger ms.author: mahiding -ms.date: 11/09/2017 +ms.date: 06/18/2020 ms.topic: article --- # Text features -`TextBlock` offers some advanced features for formatting and localizing the text. +[TextBlock](https://adaptivecards.io/explorer/TextBlock.html) offers advanced features for formatting and localizing the text. -## Markdown -To support inline markup, Adaptive Cards support a **subset** of Markdown syntax. +## Markdown (Commonmark subset) + +To support inline markup, Adaptive Cards support a **subset** of the [Commonmark](https://commonmark.org/help/) Markdown syntax. + +> [!NOTE] +> +> [RichTextBlock](https://adaptivecards.io/explorer/RichTextBlock.html) does not support markdown, but offers a wide array of text configuration options directly within the the [TextRun](https://adaptivecards.io/explorer/TextRun.html) _Supported_ @@ -62,7 +67,7 @@ The below payload would render something like this: }, { "type": "TextBlock", - "text": "Check out [Adaptive Cards](http://adaptivecards.io)" + "text": "Check out [Adaptive Cards](https://adaptivecards.io)" } ] } diff --git a/AdaptiveCards/getting-started/bots.md b/AdaptiveCards/getting-started/bots.md index 9f65e7d01..a0d1ee5a4 100644 --- a/AdaptiveCards/getting-started/bots.md +++ b/AdaptiveCards/getting-started/bots.md @@ -102,7 +102,7 @@ You can: * Add multiple types of `Actions` * Collect `Input` from your users * Have one card `show another card` -* [Check out the full schema explorer](http://adaptivecards.io/explorer/)! +* [Check out the full schema explorer](https://adaptivecards.io/explorer/)! ## Platform SDKs @@ -123,7 +123,7 @@ The Bot Framework lets you publish your bot to multiple channels. We're working We've just scratched the surface in this tutorial, so please take a look at the links below to explore more ways that Adaptive Cards can enhance your bot. -* [Browse Sample cards](http://adaptivecards.io/samples/) for inspiration -* Use the [Schema Explorer](http://adaptivecards.io/explorer) to learn the available elements -* Build a card using the [Interactive Visualizer](http://adaptivecards.io/visualizer/index.html?hostApp=Skype) -* [Get in touch](http://adaptivecards.io/connect) with any feedback you have +* [Browse Sample cards](https://adaptivecards.io/samples/) for inspiration +* Use the [Schema Explorer](https://adaptivecards.io/explorer) to learn the available elements +* Build a card using the [Interactive Visualizer](https://adaptivecards.io/visualizer/index.html?hostApp=Skype) +* [Get in touch](https://adaptivecards.io/connect) with any feedback you have diff --git a/AdaptiveCards/getting-started/outlook.md b/AdaptiveCards/getting-started/outlook.md index 985dd0f6d..97333cdca 100644 --- a/AdaptiveCards/getting-started/outlook.md +++ b/AdaptiveCards/getting-started/outlook.md @@ -23,4 +23,4 @@ You can now use Adaptive Cards to power your Outlook Actionable Messages, and cr - Head over to https://docs.microsoft.com/outlook/actionable-messages/ which will guide you through the steps of creating your first Actionable Message scenario. - Use the Actionable Message Card Playground tool to see card samples, create your own cards, send them to your own Office 365 account and see them in [Outlook for the Web](https://outlook.office.com). -- Would you rather not write JSON manually? The [Adaptive Card Designer (preview)](https://acdesignerbeta.azurewebsites.net) lets you create Adaptive Cards without writing a single line of JSON! \ No newline at end of file +- Would you rather not write JSON manually? The [Adaptive Card Designer](https://adaptivecards.io/designer/) lets you create Adaptive Cards without writing a single line of JSON! diff --git a/AdaptiveCards/getting-started/windows.md b/AdaptiveCards/getting-started/windows.md index d1d931206..89b481b3f 100644 --- a/AdaptiveCards/getting-started/windows.md +++ b/AdaptiveCards/getting-started/windows.md @@ -47,7 +47,7 @@ We don't have anything to share just yet, but we're working on incorporating Ada We've barely scratched the surface in this tutorial, so check back soon and browse the links below to explore more about Adaptive Cards. -* [Browse Sample cards](http://adaptivecards.io/samples/) for inspiration -* Use the [Schema Explorer](http://adaptivecards.io/explorer) to learn the available elements -* Build a card using the [Interactive Visualizer](http://adaptivecards.io/visualizer/index.html?hostApp=Skype) -* [Get in touch](http://adaptivecards.io/connect) with any feedback you have +* [Browse Sample cards](https://adaptivecards.io/samples/) for inspiration +* Use the [Schema Explorer](https://adaptivecards.io/explorer) to learn the available elements +* Build a card using the [Interactive Visualizer](https://adaptivecards.io/visualizer/index.html?hostApp=Skype) +* [Get in touch](https://adaptivecards.io/connect) with any feedback you have diff --git a/AdaptiveCards/resources/partners.md b/AdaptiveCards/resources/partners.md index 5ce2e41af..dfa4207ea 100644 --- a/AdaptiveCards/resources/partners.md +++ b/AdaptiveCards/resources/partners.md @@ -16,7 +16,7 @@ If you are interested in joining the Adaptive Cards ecosystem, please [reach out Platform | Description | Documentation | Version ---------|-------------|---------------|--------- -[Bot Framework Web Chat](https://github.com/Microsoft/BotFramework-WebChat) | Embeddable web chat control for the Microsoft Bot Framework | [Get Started](https://docs.microsoft.com/adaptive-cards/get-started/bots) | 1.2.5 (Web Chat 4.9.0) +[Bot Framework Web Chat](https://github.com/Microsoft/BotFramework-WebChat) | Embeddable web chat control for the Microsoft Bot Framework | [Get Started](https://docs.microsoft.com/adaptive-cards/get-started/bots) | 1.2.6 (Web Chat 4.9.2) [Outlook Actionable Messages](https://docs.microsoft.com/outlook/actionable-messages/) | Attach an actionable message to email | [Get Started](https://docs.microsoft.com/outlook/actionable-messages/) | 1.0 [Microsoft Teams](https://products.office.com/microsoft-teams/group-chat-software) | Platform that combines workplace chat, meetings, and notes | [Get Started](https://docs.microsoft.com/microsoftteams/platform/concepts/cards/cards-reference#adaptive-card) | 1.2 [Cortana Skills](https://docs.microsoft.com/cortana/skills/adaptive-cards) | A virtual assistant for Windows 10 | [Get Started](https://docs.microsoft.com/adaptive-cards/get-started/bots) | 1.0 diff --git a/AdaptiveCards/resources/tools.md b/AdaptiveCards/resources/tools.md index eb9af3e6b..050129724 100644 --- a/AdaptiveCards/resources/tools.md +++ b/AdaptiveCards/resources/tools.md @@ -24,7 +24,7 @@ Check out the [adaptivecards-designer](https://npmjs.com/adaptivecards-designer) Schema validation is a powerful way of making authoring easier and enabling tooling. -We have provided a complete [JSON Schema file](http://adaptivecards.io/schemas/1.2.0/adaptive-card.json) for editing and validating adaptive cards in json. Note that the schema URL is versioned, newer versions of Adaptive Cards will have a corresponding URL. +We have provided a complete [JSON Schema file](https://adaptivecards.io/schemas/1.2.0/adaptive-card.json) for editing and validating adaptive cards in json. Note that the schema URL is versioned, newer versions of Adaptive Cards will have a corresponding URL. In Visual Studio and Visual Studio Code you can get automatic Intellisense by including a `$schema` reference. diff --git a/AdaptiveCards/sdk/rendering-cards/android/native-styling.md b/AdaptiveCards/sdk/rendering-cards/android/native-styling.md index ee521f852..9edfd898b 100644 --- a/AdaptiveCards/sdk/rendering-cards/android/native-styling.md +++ b/AdaptiveCards/sdk/rendering-cards/android/native-styling.md @@ -30,3 +30,11 @@ Text inputs with an inline action allows styling for the action being rendered. > [!IMPORTANT] > All item names must be kept as shown here as the renderer looks for those exact names + +## Action.ShowCard + +Action.ShowCard can be styled by adding styles to your theme in styles.xml. + +```styles.xml + @style/adaptiveShowCardAction +``` \ No newline at end of file diff --git a/AdaptiveCards/sdk/rendering-cards/javascript/extensibility.md b/AdaptiveCards/sdk/rendering-cards/javascript/extensibility.md index 1ffa8e58a..66e01b43a 100644 --- a/AdaptiveCards/sdk/rendering-cards/javascript/extensibility.md +++ b/AdaptiveCards/sdk/rendering-cards/javascript/extensibility.md @@ -2,16 +2,251 @@ title: Extensibility - JavaScript SDK author: matthidinger ms.author: mahiding -ms.date: 11/28/2017 +ms.date: 07/16/2020 ms.topic: article --- # Extensibility - JavaScript -## Implement and register a custom element +## Extensibility with the JS SDK version 2.0 and greater +### Before you start + +> **IMPORTANT**: Version 2.0 and greater of the JS SDK makes use of [TypeScript decorators](https://www.typescriptlang.org/docs/handbook/decorators.html). Decorators are still an experimental feature and must be explicitly enabled in your `tsconfig.js` file: + +```json +{ + "compilerOptions": { + "experimentalDecorators": true + } +} +``` +Version 2.0 of the JS SDK introduces breaking changes in the way custom elements and actions are implemented and registered. For an example on how to implement and register an element or action using previous versions of the SDK, see [Extensibility with the JS SDK prior to version 2.0](#extensibility-with-the-js-sdk-prior-to-version-20). + + +### Custom elements The steps for creating a custom Adaptive Card element type are: -- Create a new class driving from `CardElement` +- Create a new class deriving from `CardElement` +- Create its schema by declaring static property definitions +- Implement its `getJsonTypeName`, and `internalRender` methods +- Register it in the global element registry, or use a custom registry on a per-card basis + + +Let's take an example and implement a simple Progress Bar element: +```typescript +export class ProgressBar extends AC.CardElement { + static readonly JsonTypeName = "ProgressBar"; + + //#region Schema + + static readonly titleProperty = new AC.StringProperty(AC.Versions.v1_0, "title", true); + static readonly valueProperty = new AC.NumProperty(AC.Versions.v1_0, "value"); + + @AC.property(ProgressBar.titleProperty) + get title(): string | undefined { + return this.getValue(ProgressBar.titleProperty); + } + + set title(value: string) { + if (this.title !== value) { + this.setValue(ProgressBar.titleProperty, value); + + this.updateLayout(); + } + } + + @AC.property(ProgressBar.valueProperty) + get value(): number { + return this.getValue(ProgressBar.valueProperty); + } + + set value(value: number) { + let adjustedValue = value; + + if (adjustedValue < 0) { + adjustedValue = 0; + } + else if (adjustedValue > 100) { + adjustedValue = 100; + } + + if (this.value !== adjustedValue) { + this.setValue(ProgressBar.valueProperty, adjustedValue); + + this.updateLayout(); + } + } + + //#endregion + + private _titleElement: HTMLElement; + private _leftBarElement: HTMLElement; + private _rightBarElement: HTMLElement; + + protected internalRender(): HTMLElement { + let element = document.createElement("div"); + + let textBlock = new AC.TextBlock(); + textBlock.setParent(this); + textBlock.text = this.title; + textBlock.wrap = true; + + this._titleElement = textBlock.render(); + this._titleElement.style.marginBottom = "6px"; + + let progressBarElement = document.createElement("div"); + progressBarElement.style.display = "flex"; + + this._leftBarElement = document.createElement("div"); + this._leftBarElement.style.height = "6px"; + this._leftBarElement.style.backgroundColor = AC.stringToCssColor(this.hostConfig.containerStyles.emphasis.foregroundColors.accent.default); + + this._rightBarElement = document.createElement("div"); + this._rightBarElement.style.height = "6px"; + this._rightBarElement.style.backgroundColor = AC.stringToCssColor(this.hostConfig.containerStyles.emphasis.backgroundColor); + + progressBarElement.append(this._leftBarElement, this._rightBarElement); + + element.append(this._titleElement, progressBarElement); + + return element; + } + + getJsonTypeName(): string { + return ProgressBar.JsonTypeName; + } + + updateLayout(processChildren: boolean = true) { + super.updateLayout(processChildren); + + if (this.renderedElement) { + if (this.title) { + this._titleElement.style.display = "none"; + } + else { + this._titleElement.style.removeProperty("display"); + } + + this._leftBarElement.style.flex = "1 1 " + this.value + "%"; + this._rightBarElement.style.flex = "1 1 " + (100 - this.value) + "%"; + } + } +} +``` +That's it. The ProgressBar element now needs to be registered in order to be recognized by the SDK. You can register it globally: + +```typescript +AC.GlobalRegistry.elements.register(ProgressBar.JsonTypeName, ProgressBar); +``` + +Or you can use a per-card registry, which allows the use of different registries for different cards in your application: + +```typescript +// Create a custom registry for elements +let elementRegistry = new AC.CardObjectRegistry(); + +// Populate it with the default set of elements +AC.GlobalRegistry.populateWithDefaultElements(elementRegistry); + +// Register the custom ProgressBar element +elementRegistry.register(ProgressBar.JsonTypeName, ProgressBar); + +// Parse a card payload using the custom registry +let serializationContext = new AC.SerializationContext(); +serializationContext.setElementRegistry(elementRegistry); + +let card = new AC.AdaptiveCard(); +card.parse( + { + type: "AdaptiveCard", + version: "1.0", + body: [ + { + type: "ProgressBar", + title: "This is a progress bar", + value: 45 + } + ] + }, + serializationContext +); +``` + +### Custom actions +The steps to implementing a custom action are the same as those for elements. The only difference is that actions are registered in action registries, and not in element registries. + +```typescript +export class AlertAction extends AC.Action { + static readonly JsonTypeName = "Action.Alert"; + + //#region Schema + + static readonly textProperty = new AC.StringProperty(AC.Versions.v1_0, "text", true); + + @AC.property(AlertAction.textProperty) + text?: string; + + //#endregion + + getJsonTypeName(): string { + return AlertAction.JsonTypeName; + } + + execute() { + alert(this.text); + } +} +``` + +Register the new action globally: +```typescript +AC.GlobalRegistry.actions.register(AlertAction.JsonTypeName, AlertAction); +``` + +Or use a per-card registry: +```typescript +// Create a custom registry for actions +let actionRegistry = new AC.CardObjectRegistry(); + +// Populate it with the default set of actions +AC.GlobalRegistry.populateWithDefaultActions(actionRegistry); + +// Register the custom AlertAction type +actionRegistry.register(AlertAction.JsonTypeName, AlertAction); + +// Parse a card payload using the custom registry +let serializationContext = new AC.SerializationContext(); +serializationContext.setActionRegistry(actionRegistry); + +let card = new AC.AdaptiveCard(); +card.parse( + { + type: "AdaptiveCard", + version: "1.0", + body: [ + { + type: "TextBlock", + text: "This demonstrates the AlertAction action." + } + ], + actions: [ + { + type: "Action.Alert", + title: "Click me!", + text: "Hello World" + } + ] + }, + serializationContext +); +``` + +## Extensibility with the JS SDK prior to version 2.0 + +### Custom elements + +The steps for creating a custom Adaptive Card element type are: +- Create a new class deriving from `CardElement` - Implement its `getJsonTypeName`, `parse`, `toJSON`, `internalRender` and `renderSpeech` methods - Register it by adding it to the renderer's element registry @@ -137,7 +372,7 @@ That's it. Now just register the Progress Bar class with the renderer: Adaptive.AdaptiveCard.elementTypeRegistry.registerType("ProgressBar", () => { return new ProgressBar(); }); ``` -## Implement and register a custom action +## Custom actions The steps for creating a custom Adaptive Card action are essentially the same as those for custom elements. Here is a simple example of an Alert Action that simply displays a message box with configurable text: @@ -173,14 +408,14 @@ export class AlertAction extends Adaptive.Action { Now register the new action: -``` +```typescript Adaptive.AdaptiveCard.actionTypeRegistry.registerType("Action.Alert", () => { return new AlertAction(); }); ``` ## Example Here is a sample card that uses both the ProgressBar element and AlertAction action: -``` +```json { "type": "AdaptiveCard", "version": "1.0", diff --git a/AdaptiveCards/sdk/rendering-cards/net-wpf/native-styling.md b/AdaptiveCards/sdk/rendering-cards/net-wpf/native-styling.md index abe978c64..b6e607e1d 100644 --- a/AdaptiveCards/sdk/rendering-cards/net-wpf/native-styling.md +++ b/AdaptiveCards/sdk/rendering-cards/net-wpf/native-styling.md @@ -36,8 +36,8 @@ This sample XAML Resource dictionary that sets the background of all TextBlocks ```xml + xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> diff --git a/AdaptiveCards/sdk/rendering-cards/uwp/native-styling.md b/AdaptiveCards/sdk/rendering-cards/uwp/native-styling.md index 88cc8cd91..c69f8ba72 100644 --- a/AdaptiveCards/sdk/rendering-cards/uwp/native-styling.md +++ b/AdaptiveCards/sdk/rendering-cards/uwp/native-styling.md @@ -36,8 +36,8 @@ This sample XAML Resource dictionary that sets the background of all TextBlocks ```xml + xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> diff --git a/AdaptiveCards/templating/index.md b/AdaptiveCards/templating/index.md index a659fda2e..46f513177 100644 --- a/AdaptiveCards/templating/index.md +++ b/AdaptiveCards/templating/index.md @@ -193,14 +193,27 @@ The JavaScript below shows the general pattern that will be used to populate a t ```js var template = new ACData.Template({ - // EmployeeCardTemplate goes here + // Card Template JSON }); var card = template.expand({ $root: { - // Your data goes here + // Data Fields } }); + +// Now you have an AdaptiveCard ready to render! +``` + +### C# Example + +The C# below shows the general pattern that will be used to populate a template with data. + +```csharp +var template = new AdaptiveCards.Templating.AdaptiveCardTemplate(cardJson); + +var card = template.Expand(new {Key="Value"}); + // Now you have an AdaptiveCard ready to render! ``` diff --git a/AdaptiveCards/templating/sdk.md b/AdaptiveCards/templating/sdk.md index 34af75a65..dda0bba14 100644 --- a/AdaptiveCards/templating/sdk.md +++ b/AdaptiveCards/templating/sdk.md @@ -187,8 +187,11 @@ string cardJson = template.Expand(context); ## Troubleshooting Q. Why am I running into an AdaptiveTemplateException calling ```expand()```? A. If your error message looks like '\' at line, '\' is **malformed for '$data : ' pair**". -Please ensure that value provided for "$data" is valid json such as number, boolean, object, and array, or follows correct syntax for Adaptive Template language, and the entry exists in the data context at the line number. Please note that ${LineItem} and '8' can change. +Please ensure that value provided for "$data" is valid json such as number, boolean, object, and array, or follows correct syntax for Adaptive Template language, and the entry exists in the data context at the line number. Q. Why am I running into an ArgumentNullException calling ```expand()```? A. If your error message looks like" **Check if parent data context is set, or please enter a non-null value for** '\' at line, '\'". It indicates that there doesn't exist data context for the requested data binding. Please ensure that root data context is set, if exists, ensure that any data context is available for current binding as indicated by the line number. + +Q. Why date/time in RFC 3389 format e.g "2017-02-14T06:08:00Z" when used with template doesn't works with TIME/DATE functions? +A. .NET sdk nuget version 1.0.0-rc.0 exhibits this behavior. this behavior is corrected in the subsequent releases. json.Net deserilizer's default behavior changes date/time format string, and it's disabled for the subsequent releases. Please use formatDateTime() function to format the date/time string to RFC 3389 as seen in [this example](https://github.com/microsoft/AdaptiveCards/blob/db99ee07dadf317fe45e114a508e3de6e4325d0f/samples/Templates/Elements/Template.Functions.DateFunctions.json#L28), or you can bypass TIME/DATE functions, and just use formatDateTime(). For more information on formatDateTime(), please go [here](https://docs.microsoft.com/azure/bot-service/adaptive-expressions/adaptive-expressions-prebuilt-functions?view=azure-bot-service-4.0#date-and-time-functions). diff --git a/ThirdPartyNotices b/ThirdPartyNotices index a0bd09d68..faceb5a52 100644 --- a/ThirdPartyNotices +++ b/ThirdPartyNotices @@ -7,7 +7,7 @@ see the [LICENSE](LICENSE) file, and grant you a license to any code in the repo Microsoft, Windows, Microsoft Azure and/or other Microsoft products and services referenced in the documentation may be either trademarks or registered trademarks of Microsoft in the United States and/or other countries. The licenses for this project do not grant you rights to use any Microsoft names, logos, or trademarks. -Microsoft's general trademark guidelines can be found at http://go.microsoft.com/fwlink/?LinkID=254653. +Microsoft's general trademark guidelines can be found at https://go.microsoft.com/fwlink/?LinkID=254653. Privacy information can be found at https://privacy.microsoft.com/en-us/