diff --git a/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css b/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css index 6f6afc5613..25273a9bfb 100644 --- a/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css +++ b/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css @@ -420,6 +420,10 @@ content: "\E8C8"; } +.acd-icon-help::before { + content: "\E897"; +} + .acd-icon-header-expanded::before { content: "\F166"; } diff --git a/source/nodejs/adaptivecards-designer/src/card-designer.ts b/source/nodejs/adaptivecards-designer/src/card-designer.ts index e7a27a9a87..bea3338d49 100644 --- a/source/nodejs/adaptivecards-designer/src/card-designer.ts +++ b/source/nodejs/adaptivecards-designer/src/card-designer.ts @@ -22,6 +22,7 @@ import { Strings } from "./strings"; import * as Shared from "./shared"; import { TreeView } from "./tree-view"; import { SampleCatalogue } from "./catalogue"; +import { HelpDialog } from "./help-dialog"; export class CardDesigner extends Designer.DesignContext { private static internalProcessMarkdown(text: string, result: Adaptive.IMarkdownProcessingResult) { @@ -582,6 +583,7 @@ export class CardDesigner extends Designer.DesignContext { private _newCardButton: ToolbarButton; private _copyJSONButton: ToolbarButton; private _togglePreviewButton: ToolbarButton; + private _helpButton: ToolbarButton; private _preventRecursiveSetTargetVersion = false; private prepareToolbar() { @@ -715,6 +717,16 @@ export class CardDesigner extends Designer.DesignContext { this.toolbar.addElement(this._togglePreviewButton); + this._helpButton = new ToolbarButton( + CardDesigner.ToolbarCommands.Help, + "Help", + "acd-icon-help", + (sender: ToolbarButton) => { this.showHelp(); }); + this._helpButton.toolTip = "Display help."; + this._helpButton.separator = true; + this._helpButton.alignment = ToolbarElementAlignment.Right; + this.toolbar.addElement(this._helpButton); + this._fullScreenHandler = new FullScreenHandler(); this._fullScreenHandler.onFullScreenChanged = (isFullScreen: boolean) => { this._fullScreenButton.toolTip = isFullScreen ? "Exit full screen" : "Enter full screen"; @@ -1127,6 +1139,12 @@ export class CardDesigner extends Designer.DesignContext { } } + showHelp() { + let helpDialog = new HelpDialog(); + helpDialog.title = "Help"; + helpDialog.open(); + } + newCard() { let card = { type: "AdaptiveCard", @@ -1279,5 +1297,6 @@ export module CardDesigner { static readonly NewCard = "__newCardButton"; static readonly CopyJSON = "__copyJsonButton"; static readonly TogglePreview = "__togglePreviewButton"; + static readonly Help = "__helpButton"; } } diff --git a/source/nodejs/adaptivecards-designer/src/dialog.ts b/source/nodejs/adaptivecards-designer/src/dialog.ts index bd0ac6f722..b0f06ebd1d 100644 --- a/source/nodejs/adaptivecards-designer/src/dialog.ts +++ b/source/nodejs/adaptivecards-designer/src/dialog.ts @@ -1,3 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. import * as Controls from "adaptivecards-controls"; export class DialogButton { diff --git a/source/nodejs/adaptivecards-designer/src/help-dialog.ts b/source/nodejs/adaptivecards-designer/src/help-dialog.ts new file mode 100644 index 0000000000..a3d0912512 --- /dev/null +++ b/source/nodejs/adaptivecards-designer/src/help-dialog.ts @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import * as Adaptive from "adaptivecards"; +import { Dialog } from "./dialog"; + +export class HelpDialog extends Dialog { + private _renderedElement: HTMLElement; + + private _getShortcutRow(shortcut: string, description: string, isHeader: boolean=false) : HTMLElement { + let shortcutText = document.createElement("b"); + shortcutText.innerText = shortcut; + let shortcutCell = document.createElement(isHeader ? "th" : "td"); + shortcutCell.style.textAlign = "left"; + shortcutCell.appendChild(shortcutText); + + let descriptionCell = document.createElement(isHeader ? "th" : "td"); + descriptionCell.style.textAlign = "left"; + descriptionCell.innerText = description; + + let row = document.createElement("tr"); + row.appendChild(shortcutCell); + row.appendChild(descriptionCell); + return row; + } + + protected renderContent(): HTMLElement { + this._renderedElement = document.createElement("div"); + + let cardHeading = document.createElement("h1"); + cardHeading.innerText = "Card Payload and Sample Data Editors"; + this._renderedElement.appendChild(cardHeading); + + let keyboardHeading = document.createElement("h2"); + keyboardHeading.innerText = "Keyboard Shortcuts"; + this._renderedElement.appendChild(keyboardHeading); + + let keyboardText = document.createElement("div"); + keyboardText.innerText = "These keyboard shortcuts only work when the keyboard focus is within either the card payload or sample data editors"; + this._renderedElement.appendChild(keyboardText); + this._renderedElement.appendChild(document.createElement("br")); + + let shortcutTable = document.createElement("table"); + shortcutTable.appendChild(this._getShortcutRow("Shortcut", "Description", true)); + shortcutTable.appendChild(this._getShortcutRow("Alt-F1", "Show help dialog for editor")); + shortcutTable.appendChild(this._getShortcutRow("Ctrl-M", "Toggle behavior of TAB key. By default, pressing TAB will insert a TAB character. When toggled, pressing TAB will navigate to the next focusable item.")); + + this._renderedElement.appendChild(shortcutTable); + return this._renderedElement; + } +} diff --git a/source/nodejs/adaptivecards-designer/src/open-sample-dialog.ts b/source/nodejs/adaptivecards-designer/src/open-sample-dialog.ts index 85f09f143e..9ef64ed81d 100644 --- a/source/nodejs/adaptivecards-designer/src/open-sample-dialog.ts +++ b/source/nodejs/adaptivecards-designer/src/open-sample-dialog.ts @@ -1,8 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. import { SampleCatalogue, CatalogueEntry } from "./catalogue"; import * as ACData from "adaptivecards-templating"; import * as Adaptive from "adaptivecards"; import { Dialog } from "./dialog"; -import { Downloader } from "./downloader"; class CatalogueItem { onClick: (sender: CatalogueItem) => void;