Open22

AdaptiveCardsを試してみる

kurehajimekurehajime

Adaptive Cardsとは

https://adaptivecards.io/

Microsoftが開発した、JSONでカード型UIが作成できるやつ。
ひとつのJSON定義でJavaScript、Windows、Android、iOS等々のカード型UIが作れる。

これだけを使ってアプリを作るというよりは、アプリ内に埋め込むウィジットを作るためのフレームワークっぽい感じがする。

kurehajimekurehajime

JavaScript版を試す

Vite + TypeScriptでやってみる

kurehajimekurehajime

main.tsをサンプルコードで差し替える

import * as AdaptiveCards from "adaptivecards";
const card = {
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
      {
          "type": "Image",
          "url": "https://adaptivecards.io/content/adaptive-card-50.png"
      },
      {
          "type": "TextBlock",
          "text": "Hello **Adaptive Cards!**"
      }
  ],
  "actions": [
      {
          "type": "Action.OpenUrl",
          "title": "Learn more",
          "url": "https://adaptivecards.io"
      },
      {
          "type": "Action.OpenUrl",
          "title": "GitHub",
          "url": "https://github.com/Microsoft/AdaptiveCards"
      }
  ]
};
const adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
  fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
});
adaptiveCard.onExecuteAction = function(action) { alert("Ow!"); }
adaptiveCard.parse(card);
const renderedCard = adaptiveCard.render();
document.body.appendChild(renderedCard);
kurehajimekurehajime

サンプルコードのここはTypeScriptでエラーになる
renderedCardの型はHTMLElement | undefinedなので

var renderedCard = adaptiveCard.render();
document.body.appendChild(renderedCard);

なのでこう書き換える

const renderedCard = adaptiveCard.render();
if(renderedCard){
  document.body.appendChild(renderedCard);
}
kurehajimekurehajime

見た目をリッチにする

kurehajimekurehajime

fluentuiを適用するパッケージを入れる

npm install adaptivecards-fluentui
kurehajimekurehajime

エラーでた

> npm install adaptivecards-fluentui
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: adaptivecardssandbox@0.0.0
npm error Found: adaptivecards@3.0.4
npm error node_modules/adaptivecards
npm error   adaptivecards@"^3.0.4" from the root project
npm error
npm error Could not resolve dependency:
npm error peer adaptivecards@">=2.0.0 <3.0.0" from adaptivecards-fluentui@0.5.3
npm error node_modules/adaptivecards-fluentui
npm error   adaptivecards-fluentui@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error D:\.cache_all\npm\_logs\2024-06-30T02_17_37_622Z-eresolve-report.txt
npm error A complete log of this run can be found in: D:\.cache_all\npm\_logs\2024-06-30T02_17_37_622Z-debug-0.log

公式が提供してるパッケージなのに最新版に追従してないのは残念

kurehajimekurehajime

React必須と言いながらサンプルコードは
document.body.appendChild
してるReactを一切使わないコードだしよくわからない

kurehajimekurehajime

はいエラー

> npm i npm install adaptivecards-fluentui
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: adaptivecardssandbox@0.0.0
npm error Found: @types/react@18.3.3
npm error node_modules/@types/react
npm error   dev @types/react@"^18.3.3" from the root project
npm error   peer @types/react@">=16.8.0 <19.0.0" from @fluentui/react@8.119.0
npm error   node_modules/@fluentui/react
npm error     @fluentui/react@"^8.119.0" from the root project
npm error     peer @fluentui/react@">= 8.2.0 <9.0.0" from adaptivecards-fluentui@0.5.3
npm error     node_modules/adaptivecards-fluentui
npm error       adaptivecards-fluentui@"*" from the root project
npm error   1 more (@types/react-dom)
npm error
npm error Could not resolve dependency:
npm error peer @types/react@">=16.8.0 <18.0.0" from adaptivecards-fluentui@0.5.3
npm error node_modules/adaptivecards-fluentui
npm error   adaptivecards-fluentui@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error D:\.cache_all\npm\_logs\2024-06-30T02_41_32_756Z-eresolve-report.txt
npm error A complete log of this run can be found in: D:\.cache_all\npm\_logs\2024-06-30T02_41_32_756Z-debug-0.log

もう疲れたのでforceで入れる

npm i npm install adaptivecards-fluentui  --force
kurehajimekurehajime

main.tsをサンプルコードに差し替える
React要素ゼロ

import * as AdaptiveCards from "adaptivecards";
import * as ACFluentUI from "adaptivecards-fluentui";

// Author a card
// In practice you'll probably get this from a service
// see http://adaptivecards.io/samples/ for inspiration
let card = {
	"type": "AdaptiveCard",
	"version": "1.3",
	"body": [
		{
			"type": "Image",
			"url": "https://adaptivecards.io/content/adaptive-card-50.png"
		},
		{
			"type": "TextBlock",
			"text": "Hello **Adaptive Cards!**"
		},
		{
			"type": "Input.Text",
			"placeholder": "Enter your name",
			"label": "Name",
			"isRequired": false,
			"style": "text",
			"id": "Name"
		}
	],
	"actions": [
		{
			"type": "Action.OpenUrl",
			"title": "Learn more",
			"url": "https://adaptivecards.io"
		},
		{
			"type": "Action.Submit",
			"title": "Submit"
		}
	]
};

// Create an AdaptiveCard instance
let adaptiveCard = new AdaptiveCards.AdaptiveCard();

// Use Fluent UI controls when rendering Adaptive Cards
ACFluentUI.useFluentUI();

// Set its hostConfig property unless you want to use the default Host Config
// Host Config defines the style and behavior of a card
adaptiveCard.hostConfig = new AdaptiveCards.HostConfig({
	fontFamily: "Segoe UI, Helvetica Neue, sans-serif"
	// More host config options
});

// Set the adaptive card's event handlers. onExecuteAction is invoked
// whenever an action is clicked in the card
adaptiveCard.onExecuteAction = function (action) {
	var message = "Action executed\n";
	message += "    Title: " + action.title + "\n";

	if (action instanceof AdaptiveCards.OpenUrlAction) {
		message += "    Type: OpenUrl\n";
		message += "    Url: " + action.url + "\n";
	}
	else if (action instanceof AdaptiveCards.SubmitAction) {
		message += "    Type: Submit\n";
		message += "    Data: " + JSON.stringify(action.data);
	}
	else {
		message += "    Type: <unknown>";
	}

	alert(message);
}

// Parse the card payload
adaptiveCard.parse(card);

// Render the card to an HTML element:
let renderedCard = adaptiveCard.render();

// And finally insert it somewhere in your page:
document.body.appendChild(renderedCard);

kurehajimekurehajime

誕生日入力欄を加える

,
		{
			"type": "Input.Date",
			"placeholder": "Enter your birthday",
			"label": "Date",
			"isRequired": false,
			"style": "text",
			"id": "Name"
		}

まぁちょっとリッチかな

kurehajimekurehajime

感想

クロスプラットフォームでカードUIを動的に作るというコンセプトは面白い
頻繁に要素が付け足される管理画面には向いてるかもしれない

ただ周辺エコシステムのサポートは手が回ってないように見える
自分でCSS書いて使う分にはありかもしれない