tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FeatureHighlight.jsx (2851B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 import React, { useState, useCallback, useRef, useEffect } from "react";
      6 import { actionCreators as ac } from "common/Actions.mjs";
      7 
      8 export function FeatureHighlight({
      9  message,
     10  icon,
     11  toggle,
     12  arrowPosition = "",
     13  position = "top-left",
     14  verticalPosition = "",
     15  title,
     16  ariaLabel,
     17  feature = "FEATURE_HIGHLIGHT_DEFAULT",
     18  dispatch = () => {},
     19  windowObj = global,
     20  openedOverride = false,
     21  showButtonIcon = true,
     22  dismissCallback = () => {},
     23  outsideClickCallback = () => {},
     24  modalClassName = "",
     25 }) {
     26  const [opened, setOpened] = useState(openedOverride);
     27  const ref = useRef(null);
     28 
     29  useEffect(() => {
     30    const handleOutsideClick = e => {
     31      if (!ref?.current?.contains(e.target)) {
     32        setOpened(false);
     33        outsideClickCallback();
     34      }
     35    };
     36 
     37    const handleKeyDown = e => {
     38      if (e.key === "Escape") {
     39        outsideClickCallback();
     40      }
     41    };
     42 
     43    windowObj.document.addEventListener("click", handleOutsideClick);
     44    windowObj.document.addEventListener("keydown", handleKeyDown);
     45    return () => {
     46      windowObj.document.removeEventListener("click", handleOutsideClick);
     47      windowObj.document.removeEventListener("keydown", handleKeyDown);
     48    };
     49  }, [windowObj, outsideClickCallback]);
     50 
     51  const onToggleClick = useCallback(() => {
     52    if (!opened) {
     53      dispatch(
     54        ac.DiscoveryStreamUserEvent({
     55          event: "CLICK",
     56          source: "FEATURE_HIGHLIGHT",
     57          value: {
     58            feature,
     59          },
     60        })
     61      );
     62    }
     63    setOpened(!opened);
     64  }, [dispatch, feature, opened]);
     65 
     66  const onDismissClick = useCallback(() => {
     67    setOpened(false);
     68    dismissCallback();
     69  }, [dismissCallback]);
     70 
     71  const hideButtonClass = showButtonIcon ? `` : `isHidden`;
     72  const openedClassname = opened ? `opened` : `closed`;
     73  return (
     74    <div ref={ref} className={`feature-highlight ${verticalPosition}`}>
     75      <button
     76        title={title}
     77        aria-haspopup="true"
     78        aria-label={ariaLabel}
     79        className={`toggle-button ${hideButtonClass}`}
     80        onClick={onToggleClick}
     81      >
     82        {toggle}
     83      </button>
     84      <div
     85        className={`feature-highlight-modal ${position} ${arrowPosition} ${modalClassName} ${openedClassname}`}
     86      >
     87        <div className="message-icon">{icon}</div>
     88        <p className="content-wrapper">{message}</p>
     89        <moz-button
     90          type="icon ghost"
     91          size="small"
     92          data-l10n-id="feature-highlight-dismiss-button"
     93          iconsrc="chrome://global/skin/icons/close.svg"
     94          onClick={onDismissClick}
     95          onKeyDown={onDismissClick}
     96        />
     97      </div>
     98    </div>
     99  );
    100 }