react#Element JavaScript Examples

The following examples show how to use react#Element. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: KeyValue.js    From ReactSourceCodeAnalyze with MIT License 4 votes vote down vote up
export default function KeyValue({
  alphaSort,
  depth,
  inspectPath,
  isReadOnly,
  hidden,
  name,
  overrideValueFn,
  path,
  value,
}: KeyValueProps) {
  const [isOpen, setIsOpen] = useState<boolean>(false);
  const prevIsOpenRef = useRef(isOpen);

  const isInspectable =
    value !== null &&
    typeof value === 'object' &&
    value[meta.inspectable] &&
    value[meta.size] !== 0;

  useEffect(
    () => {
      if (
        isInspectable &&
        isOpen &&
        !prevIsOpenRef.current &&
        typeof inspectPath === 'function'
      ) {
        inspectPath(path);
      }
      prevIsOpenRef.current = isOpen;
    },
    [inspectPath, isInspectable, isOpen, path],
  );

  const toggleIsOpen = () => setIsOpen(prevIsOpen => !prevIsOpen);

  const dataType = typeof value;
  const isSimpleType =
    dataType === 'number' ||
    dataType === 'string' ||
    dataType === 'boolean' ||
    value == null;

  const style = {
    paddingLeft: `${(depth - 1) * 0.75}rem`,
  };

  let children = null;
  if (isSimpleType) {
    let displayValue = value;
    if (dataType === 'string') {
      displayValue = `"${value}"`;
    } else if (dataType === 'boolean') {
      displayValue = value ? 'true' : 'false';
    } else if (value === null) {
      displayValue = 'null';
    } else if (value === undefined) {
      displayValue = 'undefined';
    }

    const isEditable = typeof overrideValueFn === 'function' && !isReadOnly;

    children = (
      <div key="root" className={styles.Item} hidden={hidden} style={style}>
        <div className={styles.ExpandCollapseToggleSpacer} />
        <span className={isEditable ? styles.EditableName : styles.Name}>
          {name}
        </span>
        {isEditable ? (
          <EditableValue
            overrideValueFn={((overrideValueFn: any): OverrideValueFn)}
            path={path}
            value={value}
          />
        ) : (
          <span className={styles.Value}>{displayValue}</span>
        )}
      </div>
    );
  } else if (
    value.hasOwnProperty(meta.type) &&
    !value.hasOwnProperty(meta.unserializable)
  ) {
    children = (
      <div key="root" className={styles.Item} hidden={hidden} style={style}>
        {isInspectable ? (
          <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
        ) : (
          <div className={styles.ExpandCollapseToggleSpacer} />
        )}
        <span
          className={styles.Name}
          onClick={isInspectable ? toggleIsOpen : undefined}>
          {name}
        </span>
        <span className={styles.Value}>{getMetaValueLabel(value)}</span>
      </div>
    );
  } else {
    if (Array.isArray(value)) {
      const hasChildren = value.length > 0;

      children = value.map((innerValue, index) => (
        <KeyValue
          key={index}
          alphaSort={alphaSort}
          depth={depth + 1}
          inspectPath={inspectPath}
          isReadOnly={isReadOnly}
          hidden={hidden || !isOpen}
          name={index}
          overrideValueFn={overrideValueFn}
          path={path.concat(index)}
          value={value[index]}
        />
      ));
      children.unshift(
        <div
          key={`${depth}-root`}
          className={styles.Item}
          hidden={hidden}
          style={style}>
          {hasChildren ? (
            <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
          ) : (
            <div className={styles.ExpandCollapseToggleSpacer} />
          )}
          <span
            className={styles.Name}
            onClick={hasChildren ? toggleIsOpen : undefined}>
            {name}
          </span>
          <span>
            Array{' '}
            {hasChildren ? '' : <span className={styles.Empty}>(empty)</span>}
          </span>
        </div>,
      );
    } else {
      // TRICKY
      // It's important to use Object.entries() rather than Object.keys()
      // because of the hidden meta Symbols used for hydration and unserializable values.
      const entries = Object.entries(value);
      if (alphaSort) {
        entries.sort(alphaSortEntries);
      }

      const hasChildren = entries.length > 0;
      const displayName = value.hasOwnProperty(meta.unserializable)
        ? getMetaValueLabel(value)
        : 'Object';

      let areChildrenReadOnly = isReadOnly || !!value[meta.readonly];
      children = entries.map<Element<any>>(([key, keyValue]) => (
        <KeyValue
          key={key}
          alphaSort={alphaSort}
          depth={depth + 1}
          inspectPath={inspectPath}
          isReadOnly={areChildrenReadOnly}
          hidden={hidden || !isOpen}
          name={key}
          overrideValueFn={overrideValueFn}
          path={path.concat(key)}
          value={keyValue}
        />
      ));
      children.unshift(
        <div
          key={`${depth}-root`}
          className={styles.Item}
          hidden={hidden}
          style={style}>
          {hasChildren ? (
            <ExpandCollapseToggle isOpen={isOpen} setIsOpen={setIsOpen} />
          ) : (
            <div className={styles.ExpandCollapseToggleSpacer} />
          )}
          <span
            className={styles.Name}
            onClick={hasChildren ? toggleIsOpen : undefined}>
            {name}
          </span>
          <span>
            {`${displayName || ''} `}
            {hasChildren ? '' : <span className={styles.Empty}>(empty)</span>}
          </span>
        </div>,
      );
    }
  }

  return children;
}
Example #2
Source File: ReactOverlay.js    From covid19-testing with Apache License 2.0 4 votes vote down vote up
export function createReactOverlay(factoryProps: ReactOverlayProps) {
  /**
   * GoogleCustomOverlay extends google.maps.OverlayView and is used to manage the overlay div's interactions with the
   * map, namely:
   *   1. Ensuring the overlay div is added to the map.
   *   2. Ensuring the div is positioned (or re-positioned) when it is added or the map's bounding box changes.
   *   3. Ensuring the div is removed when necessary.
   * It takes in an id, position, and the map to mount the marker on. It is *not* responsible for rendering the React
   * component.
   *
   * Reference: https://developers.google.com/maps/documentation/javascript/reference/#OverlayView
   * Tutorial: https://developers.google.com/maps/documentation/javascript/customoverlays
   *
   * Usage:
   *   new GoogleCustomOverlay({
   *     id: 'someId',
   *     map: someMapInstance,
   *     position: {lat: 37.751439, -122.202875}
   *   });
   */
  class GoogleCustomOverlay extends window.google.maps.OverlayView {
    constructor({id, map, position}: GoogleCustomOverlayProps) {
      super();
      this.id = id;
      this.position = position;
      // containerElement is a div that holds the overlay.
      this.containerElement = document.createElement('div');
      // The overlay elements are not initialized until onAdd is called. This property is set to true (in onAdd) when
      // the overlay is ready to be used.
      this.initialized = false;

      this.setMap(map);
    }

    // onAdd is called when the map's panes are ready and the overlay has been added to the map.
    onAdd() {
      // Get map panes and append child to the pane. Append to overlayMouseTarget pane layer so we can receive DOM
      // events.
      this.getPanes().overlayMouseTarget.appendChild(this.containerElement);
      this.containerElement.style.position = 'absolute';

      this.initialized = true;
    }

    // draws or updates the overlay. This is called after onAdd and when zoom or center change. That last part is
    // important - we *need* a new point projection after the user moves the map in any way so that the overlay appears
    // in the correct spot on the map.
    draw() {
      const latlng = new window.google.maps.LatLng(
        this.position.lat,
        this.position.lng
      );
      // Correctly position the overlay relative to the map panes.
      const point = this.getProjection().fromLatLngToDivPixel(latlng);

      this.containerElement.style.left = `${point.x}px`;
      this.containerElement.style.top = `${point.y}px`;
    }

    // onRemove is called after a call to .setMap(null).
    onRemove() {
      this.containerElement.parentNode.removeChild(this.containerElement);
      this.containerElement = null;
    }

    // Custom method to remove the overlay from the map. Abstracted this out so client doesn't need to know about
    // .setMap(null) Google Maps-y paradigm.
    remove() {
      this.setMap(null);
    }

    // Custom method to get marker's Google Maps LatLng.
    getPosition() {
      return new window.google.maps.LatLng(this.position.lat, this.position.lng);
    }
  }

  /**
   * ReactOverlay extends the GoogleCustomOverlay. It is responsible for React component operations on the map, mainly
   * drawing and removing.
   *
   * Usage:
   *   new ReactOverlay({
   *     id: 'someId',
   *     map: someMapInstance,
   *     position: {lat: 37.751439, -122.202875},
   *     reactComponent: someReactComponent
   *   });
   */
  class ReactOverlay extends GoogleCustomOverlay {
    constructor(props: ReactOverlayProps) {
      super(props);
      this.reactComponent = props.reactComponent;
    }

    draw() {
      super.draw();
      ReactDOM.render(this.reactComponent, this.containerElement);
    }

    onRemove() {
      ReactDOM.unmountComponentAtNode(this.containerElement);
      super.onRemove();
    }

    // We want to update the React component (ex: pin changes) and manually trigger draw. draw is automatically called
    // by Google Maps whenever the map loads or the map bounds have changed, neither of which is guaranteed if the
    // React component is being updated.
    redrawWithComponent(reactComponent: Element<typeof Marker>) {
      // Don't manually draw the overlay until the overlay is initialized.
      if (!this.initialized) {
        return;
      }

      this.reactComponent = reactComponent;
      this.draw();
    }
  }

  return new ReactOverlay(factoryProps);
}