diff --git a/samples/excel/10-chart/chart-data-labels.yaml b/samples/excel/10-chart/chart-data-labels.yaml new file mode 100644 index 00000000..8f8df0e8 --- /dev/null +++ b/samples/excel/10-chart/chart-data-labels.yaml @@ -0,0 +1,241 @@ +order: 16 +id: chart-data-labels +name: Data labels +description: Add and style data labels for your charts. +host: EXCEL +api_set: + ExcelApi: '1.19' +script: + content: > + $("#setup").click(() => tryCatch(setup)); + $("#show-data-callout").click(() => tryCatch(addDatalabelToDataPoints)); + $("#style-the-datalabel").click(() => tryCatch(changeTheStyleOfSubstrings)); + $("#change-label-to-roundRect").click(() => tryCatch(changeLabelShapesToRoundRect)); + $("#change-label-to-any").click(() => tryCatch(changeLabelShapesToAny)); + + const sheetName = "Data Label APIs Sample"; + + const labels = [ + { + index: 11, + date: "7/12/2023", + news: "The city hold a Sport event." + }, + { + index: 20, + date: "7/21/2023", + news: "The movie 'Titanic' come back to the cinema." + } + ]; + + async function changeLabelShapesToAny() { + await Excel.run(async (context) => { + let sheet = context.workbook.worksheets.getItem(sheetName); + let chart = sheet.charts.getItemAt(0); + + await context.sync(); + + let series = chart.series.getItemAt(0); + let label = series.points.getItemAt(labels[0].index).dataLabel; + label.geometricShapeType = Excel.GeometricShapeType.snip1Rectangle; + + label = series.points.getItemAt(labels[1].index).dataLabel; + label.geometricShapeType = Excel.GeometricShapeType.snip2DiagonalRectangle; + label.format.fill.setSolidColor("90EE90"); + + await context.sync(); + }); + } + + async function changeLabelShapesToRoundRect() { + await Excel.run(async (context) => { + let sheet = context.workbook.worksheets.getItem(sheetName); + let chart = sheet.charts.getItemAt(0); + + await context.sync(); + + let series = chart.series.getItemAt(0); + series.load("*"); + await context.sync(); + + series.points.load("*"); + await context.sync(); + + let label = series.points.getItemAt(labels[0].index).dataLabel; + label.geometricShapeType = Excel.GeometricShapeType.roundRectangle; + + label = series.points.getItemAt(labels[1].index).dataLabel; + label.geometricShapeType = Excel.GeometricShapeType.roundRectangle; + + await context.sync(); + }); + } + + async function addDatalabelToDataPoints() { + await Excel.run(async (context) => { + let sheet = context.workbook.worksheets.getItem(sheetName); + let chart = sheet.charts.getItemAt(0); + + await context.sync(); + + let series = chart.series.getItemAt(0); + series.points.load("*"); + await context.sync(); + let propSet = [ + { + top: 70, + geometricShapeType: Excel.GeometricShapeType.rectangle + }, + { + top: 200, + geometricShapeType: Excel.GeometricShapeType.rectangle + } + ]; + + for (let i = 0; i < labels.length; i++) { + series.points.getItemAt(labels[i].index).hasDataLabel = true; + await context.sync(); + let label = series.points.getItemAt(labels[i].index).dataLabel; + label.text = labels[i].news; + label.set(propSet[i]); + await context.sync(); + } + + await context.sync(); + }); + } + + async function changeTheStyleOfSubstrings() { + await Excel.run(async (context) => { + let sheet = context.workbook.worksheets.getItem(sheetName); + let chart = sheet.charts.getItemAt(0); + + await context.sync(); + + let series = chart.series.getItemAt(0); + series.load("points"); + await context.sync(); + + series.points.load("items"); + await context.sync(); + + // Label 1 + let searchStr = "Sport"; + let label = series.points.getItemAt(labels[0].index).dataLabel.load("text"); + await context.sync(); + let substrStart = label.text.indexOf(searchStr); + let subLabel = label.getSubstring(substrStart, searchStr.length); + subLabel.font.size = 13; + subLabel.font.bold = true; + + // Label 2 + searchStr = "'Titanic'"; + label = series.points.getItemAt(labels[1].index).dataLabel.load("text"); + await context.sync(); + substrStart = label.text.indexOf(searchStr); + subLabel = label.getSubstring(substrStart, searchStr.length); + subLabel.font.name = "Calibri"; + subLabel.font.size = 13; + subLabel.font.italic = true; + subLabel.font.color = "blue"; + await context.sync(); + }); + } + + async function setup() { + await Excel.run(async (context) => { + context.workbook.worksheets.getItemOrNullObject(sheetName).delete(); + const sheet = context.workbook.worksheets.add(sheetName); + + let dataRange = sheet.getRange("A1:B32"); + dataRange.values = SampleData; + + sheet.activate(); + await context.sync(); + + let chart = sheet.charts.add(Excel.ChartType.lineMarkers, dataRange); + + chart.setPosition("C4", "P25"); + chart.legend.visible = false; + chart.title.text = "Price Tag"; + chart.title.format.font.size = 20; + chart.axes.valueAxis.minimum = 80; + + await context.sync(); + }); + } + + /** Default helper for invoking an action and handling errors. */ + async function tryCatch(callback) { + try { + await callback(); + } catch (error) { + // Note: In a production add-in, you'd want to notify the user through your add-in's UI. + console.error(error); + } + } + + let SampleData = [ + ["Date", "Price"], + ["7/1/2023", 100], + ["7/2/2023", 96.71], + ["7/3/2023", 103.24], + ["7/4/2023", 109.09], + ["7/5/2023", 113.68], + ["7/6/2023", 118.68], + ["7/7/2023", 123.2], + ["7/8/2023", 135.05], + ["7/9/2023", 138.68], + ["7/10/2023", 129.63], + ["7/11/2023", 130.85], + ["7/12/2023", 135.71], + ["7/13/2023", 124.83], + ["7/14/2023", 118.94], + ["7/15/2023", 119.63], + ["7/16/2023", 127.2], + ["7/17/2023", 113.98], + ["7/18/2023", 110.32], + ["7/19/2023", 119.3], + ["7/20/2023", 120.36], + ["7/21/2023", 111.88], + ["7/22/2023", 118.88], + ["7/23/2023", 124.37], + ["7/24/2023", 119.53], + ["7/25/2023", 133.42], + ["7/26/2023", 125.67], + ["7/27/2023", 135.82], + ["7/28/2023", 137.87], + ["7/29/2023", 138.9], + ["7/30/2023", 139.36], + ["7/31/2023", 138.75] + ]; + language: typescript +template: + content: "
\n\t

This sample shows how to create callout for chart, and make it beautify by using styling API.

\n
\n\n
\n\t

Set up

\n\t\n\t

\n\t

Add Data Labels

\n\t\n\t

\n\t

Styling

\n\t\n\t

\n\t\n\t

\n\n\t\n\t

\n

" + language: html +style: + content: |- + section.samples { + margin-top: 20px; + } + + section.samples .ms-Button, section.setup .ms-Button { + display: block; + margin-bottom: 5px; + margin-left: 20px; + min-width: 80px; + } + language: css +libraries: | + https://unpkg.com/@microsoft/office-js@1.1.88-custom.18/dist/office.debug.js + https://unpkg.com/@microsoft/office-js@1.1.88-custom.18/dist/office.d.ts + //@types/office-js + + office-ui-fabric-js@1.4.0/dist/css/fabric.min.css + office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css + + core-js@2.4.1/client/core.min.js + @types/core-js + + jquery@3.1.1 + @types/jquery@3.3.1 \ No newline at end of file diff --git a/samples/excel/10-chart/chart-leader-lines.yaml b/samples/excel/10-chart/chart-leader-lines.yaml new file mode 100644 index 00000000..c46a8bf7 --- /dev/null +++ b/samples/excel/10-chart/chart-leader-lines.yaml @@ -0,0 +1,139 @@ +order: 17 +id: chart-leaderlines +name: Leaderlines +description: Enable and disable leaderlines for chart labels. +host: EXCEL +api_set: + ExcelApi: '1.19' +script: + content: | + $("#setup").click(() => tryCatch(setup)); + $("#addlabels").click(() => tryCatch(addLabels)); + $("#turnonldl").click(() => tryCatch(turnOnLeaderlines)); + $("#turnoffldl").click(() => tryCatch(turnOffLeaderlines)); + $("#changeFormat").click(() => tryCatch(changeFormat)); + + async function setup() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + + const count = sheet.charts.getCount(); + await context.sync(); + + if (count.value > 0) { + const chart = sheet.charts.getItemAt(0); + chart.delete(); + } + + let range = sheet.getRange("A1:C4"); + range.values = [ + ["Type", "Product A", "Product B"], + ["Q1", 15, 20], + ["Q2", 22, 15], + ["Q3", 33, 47] + ]; + let chart = sheet.charts.add(Excel.ChartType.line, range); + chart.title.text = "Sales Quantity"; + await context.sync(); + }); + } + + async function changeFormat() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let chart = sheet.charts.getItemAt(0); + let series = chart.series.getItemAt(0); + let seriesDataLabels = series.dataLabels; + let lineformat = seriesDataLabels.leaderLines.format; + + lineformat.line.color = "blue"; + lineformat.line.weight = 2; + lineformat.line.lineStyle = Excel.ChartLineStyle.dot; + + console.log("changes leaderlines format"); + }); + } + + async function addLabels() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let chart = sheet.charts.getItemAt(0); + let series = chart.series.getItemAt(0); + series.hasDataLabels = true; + series.points.load("items"); + await context.sync(); + series.points.items.forEach((point) => point.dataLabel.load("top")); + await context.sync(); + + series.points.items[1].dataLabel.top = series.points.items[1].dataLabel.top - 50; + series.points.items[2].dataLabel.top = series.points.items[2].dataLabel.top + 50; + series.dataLabels.geometricShapeType = Excel.GeometricShapeType.rectangle; + series.dataLabels.showCategoryName = true; + series.dataLabels.format.border.weight = 1; + await context.sync(); + }); + } + + async function turnOnLeaderlines() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let chart = sheet.charts.getItemAt(0); + let series = chart.series.getItemAt(0); + let seriesDataLabels = series.dataLabels; + + seriesDataLabels.load("showLeaderLines"); + await context.sync(); + seriesDataLabels.showLeaderLines = true; + console.log("turned on leaderlines"); + }); + } + + async function turnOffLeaderlines() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let chart = sheet.charts.getItemAt(0); + let series = chart.series.getItemAt(0); + let seriesDataLabels = series.dataLabels; + seriesDataLabels.showLeaderLines = false; + console.log("turned off leaderlines"); + }); + } + + /** Default helper for invoking an action and handling errors. */ + async function tryCatch(callback) { + try { + await callback(); + } catch (error) { + // Note: In a production add-in, you'd want to notify the user through your add-in's UI. + console.error(error); + } + } + language: typescript +template: + content: "
\n\t

This sample shows how to use the data label leader lines API.

\n
\n
\n\t

Setup

\n\t\n
\n
\n\t

Try it out

\n\t\n\t\n\t\n\t\n
" + language: html +style: + content: |- + section.samples { + margin-top: 20px; + } + + section.samples .ms-Button, section.setup .ms-Button { + display: block; + margin-bottom: 5px; + margin-left: 20px; + min-width: 80px; + } + language: css +libraries: | + https://appsforoffice.microsoft.com/lib/beta/hosted/office.js + https://appsforoffice.microsoft.com/lib/beta/hosted/office-experiment52.d.ts + + office-ui-fabric-js@1.4.0/dist/css/fabric.min.css + office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css + + core-js@2.4.1/client/core.min.js + @types/core-js + + jquery@3.1.1 + @types/jquery@3.3.1 \ No newline at end of file diff --git a/samples/excel/20-data-types/data-types-basic-types.yaml b/samples/excel/20-data-types/data-types-basic-types.yaml new file mode 100644 index 00000000..8534e2f7 --- /dev/null +++ b/samples/excel/20-data-types/data-types-basic-types.yaml @@ -0,0 +1,311 @@ +order: 8 +id: chart-data-labels +name: Basic types with metadata +description: This sample shows how to set and get data types using primitives. +host: EXCEL +api_set: + ExcelApi: '1.19' +script: + content: > + $("#setup").on("click", () => tryCatch(setup)); + $("#set-values-with-metadata").on("click", () => tryCatch(setValuesWithMetadata)); + $("#set-vwm-referenced-values").on("click", () => tryCatch(setReferencedValuesVwM)); + $("#set-vwm-circular-ref-values").on("click", () => tryCatch(setCircularReferencesPwM)); + $("#get-formatted-number").on("click", () => tryCatch(getFormattedNumber)); + + let primitiveStringValue: Excel.StringCellValue = { + type: Excel.CellValueType.string, + basicType: Excel.CellValueType.string, + basicValue: "This is a primitive string value" + }; + + let primitiveDoubleValue: Excel.DoubleCellValue = { + type: Excel.CellValueType.double, + basicType: Excel.CellValueType.double, + basicValue: 10 + }; + + let primitiveBooleanValue: Excel.BooleanCellValue = { + type: Excel.CellValueType.boolean, + basicType: Excel.CellValueType.boolean, + basicValue: true + }; + + let imageCellValue: Excel.WebImageCellValue = { + type: "WebImage", + basicType: "Error", + basicValue: "#VALUE!", + address: "https://1000logos.net/wp-content/uploads/2021/11/Bing-logo-500x281.png" + }; + + let basicViewLayoutWithIcon: Excel.BasicViewLayouts = { + card: { + title: "This is the title", + sections: [ + { + layout: "List", + properties: ["stringProperty", "booleanProperty", "doubleProperty"], + collapsed: false, + collapsible: true + } + ], + subTitle: { + property: "stringProperty" + }, + mainImage: { + property: "imageProperty" + } + }, + compact: { + icon: Excel.EntityCompactLayoutIcons.animalDog + } + }; + + let basicViewLayoutSimpleWithoutIcon: Excel.BasicViewLayouts = { + card: { + title: "This is the title", + subTitle: { + property: "stringProperty" + } + } + }; + + let cellValueProvider: Excel.CellValueProviderAttributes = { + description: "Microsoft Bing", + logoSourceAddress: "https://logos-world.net/wp-content/uploads/2021/02/Bing-Logo.png", + logoTargetAddress: "https://www.bing.com" + }; + + let doubleWithFormatAndMetadata: Excel.DoubleCellValue = { + type: Excel.CellValueType.double, + basicType: Excel.CellValueType.double, + basicValue: 300, + numberFormat: "$0.00", + properties: { + stringProperty: primitiveStringValue, + booleanProperty: primitiveBooleanValue, + doubleProperty: primitiveDoubleValue, + imageProperty: imageCellValue + }, + layouts: basicViewLayoutWithIcon, + provider: cellValueProvider + }; + + let doubleWithMetadata: Excel.DoubleCellValue = { + type: Excel.CellValueType.double, + basicType: Excel.CellValueType.double, + basicValue: 123.45, + properties: { + stringProperty: primitiveStringValue, + booleanProperty: primitiveBooleanValue, + doubleProperty: primitiveDoubleValue, + imageProperty: imageCellValue + }, + layouts: basicViewLayoutSimpleWithoutIcon, + provider: cellValueProvider + }; + + let stringWithMetadata: Excel.StringCellValue = { + type: Excel.CellValueType.string, + basicType: Excel.CellValueType.string, + basicValue: "SwM", + properties: { + stringProperty: primitiveStringValue, + booleanProperty: primitiveBooleanValue, + doubleProperty: primitiveDoubleValue, + imageProperty: imageCellValue + }, + layouts: basicViewLayoutWithIcon, + provider: cellValueProvider + }; + + let booleanWithMetadata: Excel.BooleanCellValue = { + type: Excel.CellValueType.boolean, + basicType: Excel.CellValueType.boolean, + basicValue: true, + properties: { + stringProperty: primitiveStringValue, + booleanProperty: primitiveBooleanValue, + doubleProperty: primitiveDoubleValue, + imageProperty: imageCellValue + }, + layouts: basicViewLayoutSimpleWithoutIcon, + provider: cellValueProvider + }; + + async function setValuesWithMetadata() { + await Excel.run(async (context) => { + // Get the Sample worksheet and a range on that sheet. + const sheet = context.workbook.worksheets.getItemOrNullObject("PwMSample"); + const dateRange = sheet.getRange("A1:A4"); + + // Write all different primitive with metadata to range A1:A4. + dateRange.valuesAsJson = [ + [doubleWithFormatAndMetadata], + [doubleWithMetadata], + [stringWithMetadata], + [booleanWithMetadata] + ]; + await context.sync(); + }); + } + + async function setReferencedValuesVwM() { + await Excel.run(async (context) => { + // Get the Sample worksheet and a range on that sheet. + const sheet = context.workbook.worksheets.getItemOrNullObject("PwMSample"); + const currencyRange = sheet.getRange("A5"); + + // Write a string with metadata with referenced values. + currencyRange.valuesAsJson = [ + [ + { + type: Excel.CellValueType.string, + basicType: Excel.CellValueType.string, + basicValue: "SwM Referenced Values", + properties: { + stringProperty: { + type: Excel.CellValueType.reference, + reference: 0 + }, + booleanProperty: { + type: Excel.CellValueType.reference, + reference: 1 + }, + doubleWithFormatProperty: { + type: Excel.CellValueType.reference, + reference: 2 + }, + doubleProperty: { + type: Excel.CellValueType.reference, + reference: 3 + } + }, + referencedValues: [stringWithMetadata, booleanWithMetadata, doubleWithFormatAndMetadata, doubleWithMetadata], + layouts: { + compact: { + icon: Excel.EntityCompactLayoutIcons.apple + } + } + } + ] + ]; + + await context.sync(); + }); + } + + async function setCircularReferencesPwM() { + await Excel.run(async (context) => { + // Get the Sample worksheet and a range on that sheet. + const sheet = context.workbook.worksheets.getItemOrNullObject("PwMSample"); + const currencyRange = sheet.getRange("A6"); + + // Write a string with metadata with a circular reference. + currencyRange.valuesAsJson = [ + [ + { + type: Excel.CellValueType.string, + basicType: Excel.CellValueType.string, + basicValue: "SwM Circular References", + properties: { + doubleProperty: { + type: Excel.CellValueType.double, + basicType: Excel.CellValueType.double, + basicValue: 10, + properties: { + stringProperty: primitiveStringValue, + doubleProperty: primitiveDoubleValue, + booleanProperty: primitiveBooleanValue, + rootProperty: { + type: Excel.CellValueType.reference, + reference: 0 + } + }, + referencedValues: [ + { + type: Excel.ReferenceValueType.root + } + ] + } + }, + layouts: { + compact: { + icon: Excel.EntityCompactLayoutIcons.animalTurtle + } + } + } + ] + ]; + + await context.sync(); + }); + } + + async function getFormattedNumber() { + // This function prints information about data types + // in cells A1 and A6 to the console. + await Excel.run(async (context) => { + // Get the Sample worksheet and two ranges on that sheet. + const sheet = context.workbook.worksheets.getItemOrNullObject("PwMSample"); + const VwMrange = sheet.getRange("A1:A6"); + + // Load the data type property of the ranges. + VwMrange.load("valuesAsJson"); + await context.sync(); + + const VwMValues = VwMrange.valuesAsJson; + + // Print information about the data types to the console. + console.log(VwMValues); + }); + } + + async function setup() { + await Excel.run(async (context) => { + // Create a new worksheet called "Sample" and activate it. + context.workbook.worksheets.getItemOrNullObject("PwMSample").delete(); + const sheet = context.workbook.worksheets.add("PwMSample"); + sheet.activate(); + await context.sync(); + }); + } + + /** Default helper for invoking an action and handling errors. */ async + function tryCatch(callback) { + try { + await callback(); + } catch (error) { + // Note: In a production add-in, you'd want to notify the user through your add-in's UI. + console.error(error); + } + } + language: typescript +template: + content: "
\n\t

This sample shows how to work with the primitive with metadata data type.

\n
\n
\n\t

Set up

\n\t\n\t

Try it out

\n\t\n\t\n\t\n\t\n
" + language: html +style: + content: |- + section.samples { + margin-top: 20px; + } + + section.samples .ms-Button, section.setup .ms-Button { + display: block; + margin-bottom: 5px; + margin-left: 20px; + min-width: 80px; + } + language: css +libraries: | + https://appsforoffice.microsoft.com/lib/beta/hosted/office.js + https://appsforoffice.microsoft.com/lib/beta/hosted/office-experiment52.d.ts + + office-ui-fabric-js@1.4.0/dist/css/fabric.min.css + office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css + + core-js@2.4.1/client/core.min.js + @types/core-js + + jquery@3.1.1 + @types/jquery@3.3.1 diff --git a/samples/excel/44-shape/shape-get-active.yaml b/samples/excel/44-shape/shape-get-active.yaml new file mode 100644 index 00000000..67a73122 --- /dev/null +++ b/samples/excel/44-shape/shape-get-active.yaml @@ -0,0 +1,129 @@ +order: 7 +id: excel-shape-get-active +name: Get active shape +description: Get the active shape in your workbook. +host: EXCEL +api_set: + ExcelApi: '1.19' +script: + content: | + $("#setup").on("click", () => tryCatch(setup)); + $("#addShapeAsTitle").on("click", () => tryCatch(addShapeAsTitle)); + $("#group").on("click", () => tryCatch(groupChartShape)); + $("#getActiveShape").on("click", () => tryCatch(getActiveShape)); + + async function setup() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + const count = sheet.shapes.getCount(); + await context.sync(); + if (count.value > 0) { + const shape = sheet.shapes.getItemAt(0); + shape.delete(); + } + let range = sheet.getRange("A1:C4"); + range.values = [ + ["Type", "Product A", "Product B"], + ["Q1", 15, 20], + ["Q2", 22, 15], + ["Q3", 33, 47] + ]; + let chart = sheet.charts.add(Excel.ChartType.lineMarkers, range); + chart.name = "SalesChart"; + // chart.title.text = "Sales Quantity"; + await context.sync(); + }); + } + + async function addShapeAsTitle() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let shape = sheet.shapes.addGeometricShape(Excel.GeometricShapeType.rectangle); + shape.name = "ChartTitle"; + shape.height = 20; + shape.width = 90; + shape.textFrame.textRange.text = "Sales Quantity"; + shape.textFrame.textRange.font.size = 13; + + let chart = sheet.charts.getItemAt(0); + chart.load("left, top"); + chart.plotArea.load("width"); + await context.sync(); + + shape.left = chart.left + chart.plotArea.width / 2 - 30; + shape.top = chart.top + 10; + + await context.sync(); + }); + } + + async function groupChartShape() { + await Excel.run(async (context) => { + const sheet = context.workbook.worksheets.getActiveWorksheet(); + let shape = sheet.shapes.getItem("ChartTitle"); + let chartShape = sheet.shapes.getItem("SalesChart"); + let group = sheet.shapes.addGroup([shape, chartShape]); + group.name = "GroupChart"; + await context.sync(); + }); + } + + async function getActiveShape() { + await Excel.run(async (context) => { + let group = context.workbook.getActiveShapeOrNullObject(); + if (group == null) { + console.log("No active shape"); + } else { + let image = group.getAsImage(Excel.PictureFormat.png); + await context.sync(); + let div = document.getElementById("image"); + let img = document.createElement("img"); + img.src = "data: image / jpeg; base64," + image.value; + div.appendChild(img); + } + }); + } + + /** Default helper for invoking an action and handling errors. */ + async function tryCatch(callback) { + try { + await callback(); + } catch (error) { + // Note: In a production add-in, you'd want to notify the user through your add-in's UI. + console.error(error); + } + } + language: typescript +template: + content: "
\n\t

This sample shows how to use API to get active shape.

\n
\n
\n\t

Setup

\n\t\n
\n
\n\t

Try it out

\n\t\n\t\n\t

Note: Make sure the group shape is selected.

\n\t\n
\n

Here shows the image from avtive shape:

\n
" + language: html +style: + content: |- + section.samples { + margin-top: 20px; + } + + section.samples .ms-Button, section.setup .ms-Button { + display: block; + margin-bottom: 5px; + margin-left: 20px; + min-width: 80px; + } + + p.tips { + margin-left: 20px; + font-size: 13px; + } + language: css +libraries: | + https://appsforoffice.microsoft.com/lib/beta/hosted/office.js + https://appsforoffice.microsoft.com/lib/beta/hosted/office-experiment52.d.ts + + office-ui-fabric-js@1.4.0/dist/css/fabric.min.css + office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css + + core-js@2.4.1/client/core.min.js + @types/core-js + + jquery@3.1.1 + @types/jquery@3.3.1