diff --git a/src/components/adaptive-cards/ActionOpenURL/ActionOpenUrl.jsx b/src/components/adaptive-cards/ActionOpenURL/ActionOpenUrl.jsx
index f7deeb7c6..e7ff0cfdc 100644
--- a/src/components/adaptive-cards/ActionOpenURL/ActionOpenUrl.jsx
+++ b/src/components/adaptive-cards/ActionOpenURL/ActionOpenUrl.jsx
@@ -35,7 +35,7 @@ ActionOpenUrl.defaultProps = {
style: undefined,
};
-Action.acPropTypes = {
+ActionOpenUrl.acPropTypes = {
fallback: acPropTypes.fallback,
iconUrl: acPropTypes.iconUrl,
id: acPropTypes.id,
@@ -48,7 +48,7 @@ Action.acPropTypes = {
url: acPropTypes.url,
};
-Action.acDefaultProps = {
+ActionOpenUrl.acDefaultProps = {
style: 'default',
};
diff --git a/src/components/adaptive-cards/ActionSet/ActionSet.jsx b/src/components/adaptive-cards/ActionSet/ActionSet.jsx
index e92977ec7..7ef883d50 100644
--- a/src/components/adaptive-cards/ActionSet/ActionSet.jsx
+++ b/src/components/adaptive-cards/ActionSet/ActionSet.jsx
@@ -60,4 +60,8 @@ ActionSet.acPropTypes = {
type: acPropTypes.type,
};
+ActionSet.acDefaultProps = {
+ isVisible: true,
+};
+
registerComponent('ActionSet', ActionSet, 'horizontal');
diff --git a/src/components/adaptive-cards/ActionToggleVisibility/ActionToggleVisibility.jsx b/src/components/adaptive-cards/ActionToggleVisibility/ActionToggleVisibility.jsx
new file mode 100644
index 000000000..7e6ce2384
--- /dev/null
+++ b/src/components/adaptive-cards/ActionToggleVisibility/ActionToggleVisibility.jsx
@@ -0,0 +1,62 @@
+import React, {useContext} from 'react';
+import PropTypes from 'prop-types';
+import {acPropTypes, registerComponent} from '../Component/Component';
+import webexComponentClasses from '../../helpers';
+import Action from '../Action/Action';
+import AdaptiveCardContext from '../context/adaptive-card-context';
+
+/**
+ * Adaptive Cards Action.ToggleVisibility component
+ * https://adaptivecards.io/explorer/Action.ToggleVisibility.html
+ *
+ * @param {object} props React props passed to the component
+ * @param {string} [props.className] Custom CSS class to apply
+ * @param {object} props.data Active cards definition
+ * @param {object} [props.style] Custom style to apply
+ * @returns {object} JSX of the component
+ */
+export default function ActionToggleVisibility({className, data, style}) {
+ const [cssClasses] = webexComponentClasses('ac-action-toggle-visibility', className);
+ const {getIsVisible, setIsVisible} = useContext(AdaptiveCardContext);
+
+ const handleClick = () => {
+ (data.targetElements || []).map((elem) => (
+ typeof elem === 'string'
+ ? setIsVisible(elem, !getIsVisible(elem))
+ : setIsVisible(elem.elementId, elem.isVisible)));
+ };
+
+ return (
+
+ );
+}
+
+ActionToggleVisibility.propTypes = {
+ className: PropTypes.string,
+ data: PropTypes.shape().isRequired,
+ style: PropTypes.shape(),
+};
+
+ActionToggleVisibility.defaultProps = {
+ className: undefined,
+ style: undefined,
+};
+
+ActionToggleVisibility.acPropTypes = {
+ iconUrl: acPropTypes.iconUrl,
+ id: acPropTypes.id,
+ isEnabled: acPropTypes.isEnabled,
+ mode: acPropTypes.mode,
+ style: acPropTypes.actionStyle,
+ title: acPropTypes.title,
+ tooltip: acPropTypes.tooltip,
+ targetElements: acPropTypes.targetElements,
+ type: acPropTypes.type,
+ url: acPropTypes.url,
+};
+
+ActionToggleVisibility.acDefaultProps = {
+ style: 'default',
+};
+
+registerComponent('Action.ToggleVisibility', ActionToggleVisibility);
diff --git a/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.jsx b/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.jsx
index 6921e6981..2b36ab007 100644
--- a/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.jsx
+++ b/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.jsx
@@ -8,6 +8,7 @@ import Component, {acPropTypes, registerComponent} from '../Component/Component'
import '../ActionOpenURL/ActionOpenUrl';
import '../ActionSet/ActionSet';
import '../ActionShowCard/ActionShowCard';
+import '../ActionToggleVisibility/ActionToggleVisibility';
import '../Column/Column';
import '../ColumnSet/ColumnSet';
import '../Container/Container';
@@ -85,6 +86,28 @@ export default function AdaptiveCard({
const data = templateInstance.expand({
$root: context,
});
+
+ const [elements, setElements] = useState({});
+
+ const setElement = useCallback((element) => {
+ setElements((prevElements) => (
+ {...prevElements, [element.id]: element}
+ ));
+ }, [setElements]);
+
+ const setIsVisible = (id, isVisible) => {
+ setElements((prevElements) => {
+ const targetElem = prevElements[id];
+
+ return {
+ ...prevElements,
+ [id]: {...targetElem, isVisible},
+ };
+ });
+ };
+
+ const getIsVisible = (id) => (elements[id]?.isVisible !== false);
+
const [inputs, setInputs] = useState({});
const setValue = (id, value) => {
setInputs((prevInputs) => {
@@ -111,6 +134,9 @@ export default function AdaptiveCard({
getValue,
setInput,
getAllValues,
+ setElement,
+ setIsVisible,
+ getIsVisible,
}}
>
diff --git a/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.stories.js b/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.stories.js
index 9bb231480..86bc28943 100644
--- a/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.stories.js
+++ b/src/components/adaptive-cards/AdaptiveCard/AdaptiveCard.stories.js
@@ -1912,6 +1912,103 @@ const exampleActionShowCard = {
],
};
+const exampleActionToggleVisibility = {
+ type: 'AdaptiveCard',
+ version: '1.2',
+ body: [
+ {
+ type: 'TextBlock',
+ text: 'Press the buttons to toggle the images!',
+ wrap: true,
+ },
+ {
+ type: 'TextBlock',
+ text: 'Here are some images:',
+ isVisible: false,
+ id: 'textToToggle',
+ },
+ {
+ type: 'ColumnSet',
+ columns: [
+ {
+ type: 'Column',
+ items: [
+ {
+ style: 'person',
+ type: 'Image',
+ url: 'https://picsum.photos/100/100?image=112',
+ isVisible: false,
+ id: 'imageToToggle',
+ altText: 'sample image 1',
+ size: 'medium',
+ },
+ ],
+ },
+ {
+ type: 'Column',
+ items: [
+ {
+ type: 'Image',
+ url: 'https://picsum.photos/100/100?image=123',
+ isVisible: false,
+ id: 'imageToToggle2',
+ altText: 'sample image 2',
+ size: 'medium',
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ actions: [
+ {
+ type: 'Action.ToggleVisibility',
+ title: 'Toggle!',
+ targetElements: [
+ 'textToToggle',
+ 'imageToToggle',
+ 'imageToToggle2',
+ ],
+ },
+ {
+ type: 'Action.ToggleVisibility',
+ title: 'Show!',
+ targetElements: [
+ {
+ elementId: 'textToToggle',
+ isVisible: true,
+ },
+ {
+ elementId: 'imageToToggle',
+ isVisible: true,
+ },
+ {
+ elementId: 'imageToToggle2',
+ isVisible: true,
+ },
+ ],
+ },
+ {
+ type: 'Action.ToggleVisibility',
+ title: 'Hide!',
+ targetElements: [
+ {
+ elementId: 'textToToggle',
+ isVisible: false,
+ },
+ {
+ elementId: 'imageToToggle',
+ isVisible: false,
+ },
+ {
+ elementId: 'imageToToggle2',
+ isVisible: false,
+ },
+ ],
+ },
+ ],
+};
+
const exampleInputChoiceSet = {
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
type: 'AdaptiveCard',
@@ -2116,6 +2213,11 @@ ActionShowCard.args = {
template: exampleActionShowCard,
};
+export const ActionToggleVisibility = Template.bind({});
+ActionToggleVisibility.args = {
+ template: exampleActionToggleVisibility,
+};
+
export const InputChoiceSet = Template.bind({});
InputChoiceSet.args = {
template: exampleInputChoiceSet,
diff --git a/src/components/adaptive-cards/AdaptiveCard/__snapshots__/AdaptiveCard.stories.storyshot b/src/components/adaptive-cards/AdaptiveCard/__snapshots__/AdaptiveCard.stories.storyshot
index e7fdecc3d..a8a1f6670 100644
--- a/src/components/adaptive-cards/AdaptiveCard/__snapshots__/AdaptiveCard.stories.storyshot
+++ b/src/components/adaptive-cards/AdaptiveCard/__snapshots__/AdaptiveCard.stories.storyshot
@@ -7,17 +7,17 @@ Array [
style={Object {}}
>
The action of these cards will open a URL