"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CalloutTest = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var react_native_1 = require("react-native");
var react_native_2 = require("@fluentui/react-native");
var CalloutE2ETest_1 = require("./CalloutE2ETest");
var consts_1 = require("../../../../E2E/src/Callout/consts");
var MenuPicker_1 = require("../Common/MenuPicker");
var styles_1 = require("../Common/styles");
var Test_1 = require("../Test");
var StandardCallout = function () {
    var _a = React.useState(false), showStandardCallout = _a[0], setShowStandardCallout = _a[1];
    var _b = React.useState(false), isStandardCalloutVisible = _b[0], setIsStandardCalloutVisible = _b[1];
    var _c = React.useState(true), openCalloutOnHoverAnchor = _c[0], setOpenCalloutOnHoverAnchor = _c[1];
    var _d = React.useState(false), calloutHovered = _d[0], setCalloutHovered = _d[1];
    var _e = React.useState(true), shouldSetInitialFocus = _e[0], setShouldSetInitialFocus = _e[1];
    var onInitialFocusChange = React.useCallback(function (value) { return setShouldSetInitialFocus(value); }, []);
    var _f = React.useState(false), customRestoreFocus = _f[0], setCustomRestoreFocus = _f[1];
    var onRestoreFocusChange = React.useCallback(function (value) { return setCustomRestoreFocus(value); }, []);
    var _g = React.useState(false), isBeakVisible = _g[0], setIsBeakVisible = _g[1];
    var onIsBeakVisibleChange = React.useCallback(function (value) { return setIsBeakVisible(value); }, []);
    var _h = React.useState(false), preventDismissOnKeyDown = _h[0], setPreventDismissOnKeyDown = _h[1];
    var _j = React.useState(false), preventDismissOnClickOutside = _j[0], setPreventDismissOnClickOutside = _j[1];
    var _k = React.useState([]), calloutDismissBehaviors = _k[0], setDismissBehaviors = _k[1];
    var onPreventDismissOnKeyDownChange = React.useCallback(function (value) {
        setPreventDismissOnKeyDown(value);
        if (value) {
            setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnKeyDown'));
        }
        else {
            var newDismissBehaviors = calloutDismissBehaviors.filter(function (value) {
                value != 'preventDismissOnKeyDown';
            });
            setDismissBehaviors(newDismissBehaviors);
        }
    }, [calloutDismissBehaviors]);
    var onPreventDismissOnClickOutsideChange = React.useCallback(function (value) {
        setPreventDismissOnClickOutside(value);
        if (value) {
            setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnClickOutside'));
        }
        else {
            var newDismissBehaviors = calloutDismissBehaviors.filter(function (value) {
                value != 'preventDismissOnClickOutside';
            });
            setDismissBehaviors(newDismissBehaviors);
        }
    }, [calloutDismissBehaviors]);
    var redTargetRef = React.useRef(null);
    var blueTargetRef = React.useRef(null);
    var greenTargetRef = React.useRef(null);
    var decoyBtn1Ref = React.useRef(null);
    var decoyBtn2Ref = React.useRef(null);
    var _l = React.useState(redTargetRef), anchorRef = _l[0], setAnchorRef = _l[1];
    var _m = React.useState(0), hoveredTargetsCount = _m[0], setHoveredTargetsCount = _m[1];
    var _o = React.useState(0), displayCountHoveredTargets = _o[0], setDisplayCountHoveredTargets = _o[1];
    var anchorRefsInfo = React.useMemo(function () {
        return {
            hoverCount: displayCountHoveredTargets,
            isCurrentAnchor: [
                openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == redTargetRef,
                openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == greenTargetRef,
                openCalloutOnHoverAnchor && isStandardCalloutVisible && anchorRef == blueTargetRef,
            ],
        };
    }, [anchorRef, displayCountHoveredTargets, isStandardCalloutVisible, openCalloutOnHoverAnchor]);
    // Use a timer to update the targets count and avoid jittery updates of counts on-screen
    React.useLayoutEffect(function () {
        var timer = setTimeout(function () {
            setDisplayCountHoveredTargets(hoveredTargetsCount);
        }, 50);
        return function () { return clearTimeout(timer); };
    }, [hoveredTargetsCount]);
    React.useLayoutEffect(function () {
        // The callout may be dismissed by multiple mechanisms, depending on its active invocation
        // mechanisms.  In each of those dismissal routes, we use this function to reset the callout's
        // state universally.
        if (!showStandardCallout) {
            setIsStandardCalloutVisible(false);
            setCalloutHovered(false);
        }
    }, [showStandardCallout]);
    var toggleShowStandardCallout = React.useCallback(function () {
        setShowStandardCallout(!showStandardCallout);
    }, [showStandardCallout]);
    // Set up a LayoutEffect for hover callout mechanics including:
    //   the toggle switch for hover callout behavior
    //   multiple hover targets (i.e. the callout and its anchor)
    //   a dismissal timer for closing the callout with no targets hovered
    React.useLayoutEffect(function () {
        if (!openCalloutOnHoverAnchor) {
            setShowStandardCallout(false);
        }
        else if (openCalloutOnHoverAnchor && hoveredTargetsCount > 0) {
            setShowStandardCallout(true);
        }
        else {
            var timer_1 = setTimeout(function () {
                setShowStandardCallout(false);
            }, 2000);
            return function () { return clearTimeout(timer_1); };
        }
        return undefined;
    }, [openCalloutOnHoverAnchor, hoveredTargetsCount]);
    var updateCalloutTargetsHoverState = React.useCallback(function (show, hoverAnchorRef) {
        if (hoverAnchorRef !== undefined && hoverAnchorRef !== anchorRef) {
            return;
        }
        setHoveredTargetsCount(hoveredTargetsCount + (show ? 1 : -1));
    }, [anchorRef, hoveredTargetsCount, setHoveredTargetsCount]);
    var calloutHoveredCallback = React.useCallback(function (isHovered) {
        updateCalloutTargetsHoverState(isHovered, undefined);
        setCalloutHovered(isHovered);
    }, [updateCalloutTargetsHoverState]);
    var toggleCalloutRef = React.useCallback(function () {
        // Cycle the target ref between the RGB target views
        setAnchorRef(anchorRef === redTargetRef ? greenTargetRef : anchorRef === greenTargetRef ? blueTargetRef : redTargetRef);
    }, [anchorRef]);
    var switchTargetRefOrRect = React.useCallback(function () {
        // Switch between RGB views or a fixed anchor
        setAnchorRef(anchorRef === redTargetRef || anchorRef === greenTargetRef || anchorRef == blueTargetRef ? undefined : redTargetRef);
    }, [anchorRef]);
    React.useEffect(function () {
        if (!showStandardCallout && anchorRef === undefined) {
            setAnchorRef(redTargetRef);
        }
    }, [anchorRef, setAnchorRef, showStandardCallout]);
    var onShowStandardCallout = React.useCallback(function () {
        setIsStandardCalloutVisible(true);
    }, []);
    var onDismissStandardCallout = React.useCallback(function () {
        // setting the internal state to false will instigate unmounting the
        // zombie Callout control.
        setShowStandardCallout(false);
    }, []);
    var onRestoreFocusStandardCallout = React.useCallback(function (restoreFocusEvent) {
        var _a, _b, _c, _d, _e;
        if ((_a = restoreFocusEvent === null || restoreFocusEvent === void 0 ? void 0 : restoreFocusEvent.nativeEvent) === null || _a === void 0 ? void 0 : _a.containsFocus) {
            (_c = (_b = decoyBtn1Ref === null || decoyBtn1Ref === void 0 ? void 0 : decoyBtn1Ref.current) === null || _b === void 0 ? void 0 : _b.focus) === null || _c === void 0 ? void 0 : _c.call(_b);
        }
        else {
            (_e = (_d = decoyBtn2Ref === null || decoyBtn2Ref === void 0 ? void 0 : decoyBtn2Ref.current) === null || _d === void 0 ? void 0 : _d.focus) === null || _e === void 0 ? void 0 : _e.call(_d);
        }
    }, [decoyBtn1Ref, decoyBtn2Ref]);
    var colorDefault = 'default';
    var colorSelections = [colorDefault, 'red', 'green', 'blue'];
    var menuPickerColorCollection = colorSelections.map(function (color) {
        return {
            label: color,
            value: color,
        };
    });
    var _p = React.useState(undefined), selectedBackgroundColor = _p[0], setSelectedBackgroundColor = _p[1];
    var _q = React.useState(undefined), selectedBorderColor = _q[0], setSelectedBorderColor = _q[1];
    var borderWidthDefault = react_native_1.Platform.OS === 'macos' ? '0' : '1';
    var borderWidthSelections = ['0', '1', '2', '4', '10'];
    var menuPickerBorderWidthCollection = borderWidthSelections.map(function (width) {
        return {
            label: width,
            value: width,
        };
    });
    var borderRadiusDefault = '5';
    var borderRadiusSelections = ['0', '5', '7', '15'];
    var menuPickerBorderRadiusCollection = borderRadiusSelections.map(function (width) {
        return {
            label: width,
            value: width,
        };
    });
    var _r = React.useState(undefined), selectedBorderWidth = _r[0], setSelectedBorderWidth = _r[1];
    var _s = React.useState(undefined), selectedBorderRadius = _s[0], setSelectedBorderRadius = _s[1];
    var _t = React.useState(false), showScrollViewCallout = _t[0], setShowScrollViewCalout = _t[1];
    var _u = React.useState([1, 2, 3]), scrollviewContents = _u[0], setScrollviewContents = _u[1];
    var removeButton = React.useCallback(function () {
        var tempArray = scrollviewContents;
        tempArray.pop();
        setScrollviewContents(tslib_1.__spreadArray([], tempArray, true));
    }, [setScrollviewContents, scrollviewContents]);
    var addButton = React.useCallback(function () {
        setScrollviewContents(function (arr) { return tslib_1.__spreadArray(tslib_1.__spreadArray([], arr, true), [1], false); });
    }, [setScrollviewContents]);
    var calloutTargetOrAnchor = {};
    if (anchorRef) {
        calloutTargetOrAnchor.target = anchorRef;
    }
    else {
        calloutTargetOrAnchor.anchorRect = { screenX: 50, screenY: 50, width: 1, height: 1 };
    }
    return (React.createElement(react_native_1.View, null,
        React.createElement(react_native_1.View, { style: { flexDirection: 'row', paddingVertical: 5 } },
            React.createElement(react_native_1.View, { style: { flexDirection: 'column', paddingHorizontal: 5 } },
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: openCalloutOnHoverAnchor, onValueChange: setOpenCalloutOnHoverAnchor }),
                    React.createElement(react_native_1.Text, null, "Show Callout On Hover Anchor")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: shouldSetInitialFocus, onValueChange: onInitialFocusChange }),
                    React.createElement(react_native_1.Text, null, "Set Initial Focus")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: customRestoreFocus, onValueChange: onRestoreFocusChange }),
                    React.createElement(react_native_1.Text, null, "Customize Restore Focus")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: isBeakVisible, onValueChange: onIsBeakVisibleChange }),
                    React.createElement(react_native_1.Text, null, "Beak Visible")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: preventDismissOnKeyDown, onValueChange: onPreventDismissOnKeyDownChange }),
                    React.createElement(react_native_1.Text, null, "Prevent Dismiss On Key Down")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: preventDismissOnClickOutside, onValueChange: onPreventDismissOnClickOutsideChange }),
                    React.createElement(react_native_1.Text, null, "Prevent Dismiss On Click Outside")),
                React.createElement(react_native_1.View, { style: { flexDirection: 'row' } },
                    React.createElement(react_native_1.Switch, { value: showScrollViewCallout, onValueChange: setShowScrollViewCalout }),
                    React.createElement(react_native_1.Text, null, "Enable ScrollView Callout")),
                React.createElement(MenuPicker_1.MenuPicker, { prompt: "Background Color", selected: selectedBackgroundColor || colorDefault, onChange: function (color) { return setSelectedBackgroundColor(color === colorDefault ? undefined : color); }, collection: menuPickerColorCollection }),
                React.createElement(MenuPicker_1.MenuPicker, { prompt: "Border Color", selected: selectedBorderColor || colorDefault, onChange: function (color) { return setSelectedBorderColor(color === colorDefault ? undefined : color); }, collection: menuPickerColorCollection }),
                React.createElement(MenuPicker_1.MenuPicker, { prompt: "Border Width", selected: selectedBorderWidth || borderWidthDefault, onChange: function (color) { return setSelectedBorderWidth(color === colorDefault ? undefined : color); }, collection: menuPickerBorderWidthCollection }),
                React.createElement(MenuPicker_1.MenuPicker, { prompt: "Border Radius", selected: selectedBorderRadius || borderRadiusDefault, onChange: function (radius) { return setSelectedBorderRadius(radius === borderRadiusDefault ? undefined : radius); }, collection: menuPickerBorderRadiusCollection })),
            React.createElement(react_native_2.Separator, { vertical: true }),
            React.createElement(react_native_1.View, { style: { flexDirection: 'column', paddingHorizontal: 5 } },
                React.createElement(react_native_2.Button, { content: (openCalloutOnHoverAnchor ? 'Hover Color Anchor ' : 'Press Here ') + 'for Callout', onClick: toggleShowStandardCallout, disabled: openCalloutOnHoverAnchor }),
                React.createElement(react_native_1.Text, null,
                    React.createElement(react_native_1.Text, null, "Visibility: "),
                    isStandardCalloutVisible ? React.createElement(react_native_1.Text, { style: { color: 'green' } }, "Visible") : React.createElement(react_native_1.Text, { style: { color: 'red' } }, "Not Visible"))),
            React.createElement(react_native_2.Separator, { vertical: true }),
            React.createElement(react_native_1.View, { style: { flexDirection: 'column', paddingHorizontal: 5 } },
                React.createElement(react_native_2.Pressable, { onHoverIn: function () { return updateCalloutTargetsHoverState(true, redTargetRef); }, onHoverOut: function () { return updateCalloutTargetsHoverState(false, redTargetRef); } },
                    React.createElement(react_native_1.View, { ref: redTargetRef, style: { height: 40, width: 40, backgroundColor: 'red', padding: 5 } }, anchorRefsInfo.isCurrentAnchor[0] && React.createElement(react_native_1.Text, null, anchorRefsInfo.hoverCount))),
                React.createElement(react_native_2.Pressable, { onHoverIn: function () { return updateCalloutTargetsHoverState(true, greenTargetRef); }, onHoverOut: function () { return updateCalloutTargetsHoverState(false, greenTargetRef); } },
                    React.createElement(react_native_1.View, { ref: greenTargetRef, style: { height: 40, width: 40, backgroundColor: 'green', padding: 5 } }, anchorRefsInfo.isCurrentAnchor[1] && React.createElement(react_native_1.Text, null, anchorRefsInfo.hoverCount))),
                React.createElement(react_native_2.Pressable, { onHoverIn: function () { return updateCalloutTargetsHoverState(true, blueTargetRef); }, onHoverOut: function () { return updateCalloutTargetsHoverState(false, blueTargetRef); } },
                    React.createElement(react_native_1.View, { ref: blueTargetRef, style: { height: 40, width: 40, backgroundColor: 'blue', padding: 5 } }, anchorRefsInfo.isCurrentAnchor[2] && React.createElement(react_native_1.Text, { style: { color: 'white' } }, anchorRefsInfo.hoverCount))))),
        React.createElement(react_native_2.Separator, null),
        React.createElement(react_native_1.View, { style: { paddingVertical: 5 } },
            React.createElement(react_native_2.Button, { componentRef: decoyBtn1Ref, content: "Custom reFocus w/ focus in Callout" }),
            React.createElement(react_native_2.Button, { componentRef: decoyBtn2Ref, content: "Custom reFocus w/o focus in Callout" })),
        showStandardCallout && (React.createElement(react_native_2.Callout, tslib_1.__assign({}, tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({ doNotTakePointerCapture: openCalloutOnHoverAnchor !== null && openCalloutOnHoverAnchor !== void 0 ? openCalloutOnHoverAnchor : undefined }, calloutTargetOrAnchor), { onDismiss: onDismissStandardCallout, onShow: onShowStandardCallout }), (customRestoreFocus && { onRestoreFocus: onRestoreFocusStandardCallout })), { accessibilityLabel: 'Standard Callout', setInitialFocus: shouldSetInitialFocus, isBeakVisible: isBeakVisible }), (selectedBorderColor && { borderColor: selectedBorderColor })), (selectedBackgroundColor && { backgroundColor: selectedBackgroundColor })), (selectedBorderWidth && { borderWidth: parseInt(selectedBorderWidth) })), (selectedBorderRadius && { borderRadius: parseInt(selectedBorderRadius) })), (calloutDismissBehaviors && { dismissBehaviors: calloutDismissBehaviors }))),
            React.createElement(react_native_2.Pressable, { onHoverIn: function () { return calloutHoveredCallback(true); }, onHoverOut: function () { return calloutHoveredCallback(false); } }, showScrollViewCallout ? (React.createElement(react_native_1.View, { style: styles_1.fluentTesterStyles.scrollViewContainer },
                React.createElement(react_native_1.ScrollView, { contentContainerStyle: styles_1.fluentTesterStyles.scrollViewStyle, showsVerticalScrollIndicator: true },
                    React.createElement(react_native_2.StealthButton, { content: "click to change anchor", onClick: toggleCalloutRef }),
                    React.createElement(react_native_2.StealthButton, { content: "click to switch between anchor and rect", onClick: switchTargetRefOrRect }),
                    React.createElement(react_native_2.StealthButton, { content: "Click to add a button", style: styles_1.fluentTesterStyles.testListItem, onClick: addButton }),
                    React.createElement(react_native_2.StealthButton, { content: "Click to remove a button", style: styles_1.fluentTesterStyles.testListItem, onClick: removeButton }),
                    scrollviewContents.map(function (value) {
                        return React.createElement(react_native_2.StealthButton, { key: value, content: "Button", style: styles_1.fluentTesterStyles.testListItem });
                    })))) : (
            //else
            React.createElement(react_native_1.View, { style: { padding: 20, backgroundColor: calloutHovered ? 'lightgreen' : 'pink' } },
                React.createElement(react_native_2.Button, { content: "click to change anchor", onClick: toggleCalloutRef }),
                React.createElement(react_native_2.Button, { content: "click to switch between anchor and rect", onClick: switchTargetRefOrRect }))))))));
};
var CustomCallout = function () {
    var _a = React.useState(false), showCustomizedCallout = _a[0], setShowCustomizedCallout = _a[1];
    var _b = React.useState(false), isCustomizedCalloutVisible = _b[0], setIsCustomizedCalloutVisible = _b[1];
    var toggleShowCustomizedCallout = React.useCallback(function () {
        setShowCustomizedCallout(!showCustomizedCallout);
        // Unmounting a callout does not invoke onDismiss; onDismiss is only invoked
        // for dismissals generated by the native app.  When toggling to 'show',
        // the isVisible state will be corrected to 'true' by the onShow callback.
        setIsCustomizedCalloutVisible(false);
    }, [showCustomizedCallout, setIsCustomizedCalloutVisible, setShowCustomizedCallout]);
    var onShowCustomizedCallout = React.useCallback(function () {
        setIsCustomizedCalloutVisible(true);
    }, [setIsCustomizedCalloutVisible]);
    var onDismissCustomizedCallout = React.useCallback(function () {
        setIsCustomizedCalloutVisible(false);
        // setting the internal state to false will instigate unmounting the
        // zombie Callout control.
        setShowCustomizedCallout(false);
    }, [setIsCustomizedCalloutVisible, setShowCustomizedCallout]);
    var myRect = { screenX: 10, screenY: 10, width: 100, height: 100 };
    return (React.createElement(react_native_1.View, null,
        React.createElement(react_native_1.View, { style: { flexDirection: 'column', paddingVertical: 5 } },
            React.createElement(react_native_2.Button, { content: "Press for Callout", onClick: toggleShowCustomizedCallout }),
            React.createElement(react_native_1.Text, { selectable: true },
                React.createElement(react_native_1.Text, null, "Visibility: "),
                isCustomizedCalloutVisible ? React.createElement(react_native_1.Text, { style: { color: 'green' } }, "Visible") : React.createElement(react_native_1.Text, { style: { color: 'red' } }, "Not Visible"))),
        showCustomizedCallout && (React.createElement(react_native_2.Callout, { anchorRect: myRect, onDismiss: onDismissCustomizedCallout, onShow: onShowCustomizedCallout, accessibilityLabel: "Customized Callout", accessibilityRole: "alert", accessibilityOnShowAnnouncement: "Be informed that a customized callout has been opened." },
            React.createElement(react_native_1.View, { style: { padding: 20, borderWidth: 2, borderColor: 'black' } },
                React.createElement(react_native_1.Text, null, "just some text so it does not take focus and is not empty."))))));
};
var calloutSections = [
    {
        name: 'Standard Usage',
        testID: consts_1.CALLOUT_TESTPAGE,
        component: StandardCallout,
    },
    {
        name: 'Customized Usage',
        component: CustomCallout,
    },
];
var e2eSections = [
    {
        name: 'E2E Testing Callout',
        component: CalloutE2ETest_1.E2ECalloutTest,
    },
];
var CalloutTest = function () {
    var status = {
        win32Status: 'Beta',
        uwpStatus: 'Backlog',
        iosStatus: 'Backlog',
        macosStatus: 'Beta',
        androidStatus: 'Backlog',
    };
    var description = 'A callout is an anchored tip that can be used to teach people or guide them through the app without blocking them.';
    return React.createElement(Test_1.Test, { name: "Callout Test", description: description, sections: calloutSections, status: status, e2eSections: e2eSections });
};
exports.CalloutTest = CalloutTest;
//# sourceMappingURL=CalloutTest.js.map