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
+ + + + + +
+
+
, +