react#MouseEvent TypeScript Examples

The following examples show how to use react#MouseEvent. 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: BackupPopover.tsx    From extension with MIT License 7 votes vote down vote up
BackupPopover = () => {
  const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null)
  const open = Boolean(anchorEl)

  const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
    setAnchorEl(event.currentTarget)
  }

  const handleClose = () => {
    setAnchorEl(null)
  }

  return (
    <>
      <IconButton onClick={handleClick}>
        <SyncIcon />
      </IconButton>
      <Popover
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'center',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'center',
        }}
      >
        <PopoverContainer>
          <BackupCard noCard />
        </PopoverContainer>
      </Popover>
    </>
  )
}
Example #2
Source File: dialog-delete-filter-preset.tsx    From keycaplendar with MIT License 6 votes vote down vote up
DialogDeleteFilterPreset = ({
  close,
  open,
  preset,
}: DialogDeleteFilterPresetProps) => {
  const deleteFn = (e: MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    if (preset.global) {
      deleteGlobalPreset(preset);
    } else {
      deletePreset(preset);
    }
    close();
  };
  return (
    <Dialog open={open}>
      <DialogTitle>Delete {`"${preset.name}"`}</DialogTitle>
      <DialogContent>
        Are you sure you want to delete the{preset.global ? ` global` : ""}{" "}
        filter preset {`"${preset.name}"`}?
      </DialogContent>
      <DialogActions>
        <DialogButton action="close" isDefaultAction onClick={close}>
          Cancel
        </DialogButton>
        <DialogButton action="accept" className="delete" onClick={deleteFn}>
          Delete
        </DialogButton>
      </DialogActions>
    </Dialog>
  );
}
Example #3
Source File: useRegionClick.ts    From fe-foundation with Apache License 2.0 6 votes vote down vote up
export function useRegionClick(elem: HTMLElement | RefObject<HTMLElement> | null): (e: MouseEvent) => void {

    const region = useRegion();
    const elemGetter = useContainer(elem);

    return useCallback((e: MouseEvent) => {

        const el = elemGetter();

        if (el == null) {
            return;
        }

        const offset = getElementPosition(el);
        const x = e.clientX - offset.left;
        const y = e.clientY - offset.top;
        const point = region.getPointByOffset({x, y});

        if (point.getDragging()) {
            point.setDragging(false);
        }

        point.updateRealOffset(point.getOffset(), {x, y});
    }, []);
}
Example #4
Source File: MouseSensor.ts    From dnd-kit with MIT License 6 votes vote down vote up
static activators = [
    {
      eventName: 'onMouseDown' as const,
      handler: (
        {nativeEvent: event}: MouseEvent,
        {onActivation}: MouseSensorOptions
      ) => {
        if (event.button === MouseButton.RightClick) {
          return false;
        }

        onActivation?.({event});

        return true;
      },
    },
  ];
Example #5
Source File: DisableCompanionModal.tsx    From apps with GNU Affero General Public License v3.0 6 votes vote down vote up
export default function DisableCompanionModal({
  onConfirm,
  ...props
}: DisableCompanionModalProps): ReactElement {
  const onDisableClick = async (event: MouseEvent): Promise<void> => {
    onConfirm();
    props.onRequestClose(event);
  };

  return (
    <ConfirmationModal {...props}>
      <ConfirmationHeading>Disable the companion widget?</ConfirmationHeading>
      <ConfirmationDescription>
        You can always re-enable it through the customize menu.
      </ConfirmationDescription>
      <ConfirmationButtons>
        <Button className="btn-secondary" onClick={props.onRequestClose}>
          Cancel
        </Button>
        <Button className="btn-primary" onClick={onDisableClick}>
          Disable
        </Button>
      </ConfirmationButtons>
    </ConfirmationModal>
  );
}
Example #6
Source File: PasswordElement.tsx    From react-hook-form-mui with MIT License 6 votes vote down vote up
export default function PasswordElement({iconColor, ...props}: PasswordElementProps): JSX.Element {
  const [password, setPassword] = useState<boolean>(true)
  return (
    <TextFieldElement
      {...props}
      InputProps={{
        endAdornment: (
          <InputAdornment position={'end'}>
            <IconButton
              onMouseDown={(e: MouseEvent<HTMLButtonElement>) =>
                e.preventDefault()
              }
              onClick={() => setPassword(!password)}
              tabIndex={-1}
              color={iconColor ?? 'default'}
            >
              {password ? <Visibility /> : <VisibilityOff />}
            </IconButton>
          </InputAdornment>
        )
      }}
      type={password ? 'password' : 'text'}
    />
  )
}
Example #7
Source File: Modal.tsx    From gear-js with GNU General Public License v3.0 6 votes vote down vote up
Modal = ({ heading, close, children, className }: Props) => {
  const [root, setRoot] = useState<HTMLDivElement>();
  const bodyClassName = clsx(styles.body, className);

  const handleOverlayClick = ({ target, currentTarget }: MouseEvent) => {
    if (target === currentTarget) close();
  };

  useEffect(() => {
    const div = document.createElement('div');
    div.id = 'modal-root';
    document.body.appendChild(div);
    setRoot(div);

    return () => {
      document.body.removeChild(div);
    };
  }, []);

  const component = (
    <div className={styles.overlay} onClick={handleOverlayClick} data-testid="overlay">
      <div className={styles.modal} data-testid="modal">
        <Button className={styles.button} icon={icon} color="transparent" onClick={close} />
        <h3 className={styles.heading}>{heading}</h3>
        {children && (
          <div className={bodyClassName} data-testid="body">
            {children}
          </div>
        )}
      </div>
    </div>
  );

  return root ? createPortal(component, root) : null;
}
Example #8
Source File: layouts.ts    From geist-ui with MIT License 6 votes vote down vote up
useRect = (initialState?: ReactiveDomReact | (() => ReactiveDomReact)) => {
  const [rect, setRect] = useState<ReactiveDomReact>(initialState || defaultRect)

  const updateRect = (
    eventOrRef:
      | MouseEvent<HTMLElement>
      | FocusEvent<HTMLElement>
      | MutableRefObject<HTMLElement | null>,
    getContainer?: () => HTMLElement | null,
  ) => {
    if (isRefTarget(eventOrRef)) return setRect(getRefRect(eventOrRef, getContainer))
    setRect(getEventRect(eventOrRef, getContainer))
  }

  return {
    rect,
    setRect: updateRect,
  }
}
Example #9
Source File: DangerButton.tsx    From ble with Apache License 2.0 6 votes vote down vote up
DangerButton: FunctionComponent<Props> = ({ onClick, ...props }) => {
	function clickHandler(ev: MouseEvent): void {
		if (onClick === undefined) return;

		onClick(ev);
	}

	return (
		<Button {...props} onClick={onClick ? clickHandler : undefined}/>
	);
}
Example #10
Source File: TorrentListRow.tsx    From flood with GNU General Public License v3.0 6 votes vote down vote up
displayContextMenu = (hash: string, event: KeyboardEvent | MouseEvent | TouchEvent) => {
  if (event.cancelable === true) {
    event.preventDefault();
  }

  const mouseClientX = (event as unknown as MouseEvent).clientX;
  const mouseClientY = (event as unknown as MouseEvent).clientY;
  const touchClientX = (event as unknown as TouchEvent).touches?.[0].clientX;
  const touchClientY = (event as unknown as TouchEvent).touches?.[0].clientY;

  if (!TorrentStore.selectedTorrents.includes(hash)) {
    TorrentStore.setSelectedTorrents({hash, event});
  }

  const {torrentContextMenuActions = defaultFloodSettings.torrentContextMenuActions} = SettingStore.floodSettings;
  const torrent = TorrentStore.torrents[hash];

  UIStore.setActiveContextMenu({
    id: 'torrent-list-item',
    clickPosition: {
      x: mouseClientX || touchClientX || 0,
      y: mouseClientY || touchClientY || 0,
    },
    items: getContextMenuItems(torrent).filter((item) => {
      if (item.type === 'separator') {
        return true;
      }

      return torrentContextMenuActions.some((action) => action.id === item.action && action.visible === true);
    }),
  });
}
Example #11
Source File: use-mouse.ts    From mantine with MIT License 6 votes vote down vote up
export function useMouse<T extends HTMLElement = any>() {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const ref = useRef<T>();

  const setMousePosition = (event: MouseEvent<HTMLElement>) => {
    if (ref.current) {
      const rect = event.currentTarget.getBoundingClientRect();

      const x = Math.max(
        0,
        Math.round(event.pageX - rect.left - (window.pageXOffset || window.scrollX))
      );

      const y = Math.max(
        0,
        Math.round(event.pageY - rect.top - (window.pageYOffset || window.scrollY))
      );

      setPosition({ x, y });
    } else {
      setPosition({ x: event.clientX, y: event.clientY });
    }
  };

  useEffect(() => {
    const element = ref?.current ? ref.current : document;
    element.addEventListener('mousemove', setMousePosition as any);

    return () => element.removeEventListener('mousemove', setMousePosition as any);
  }, [ref.current]);

  return { ref, ...position };
}
Example #12
Source File: Builder.tsx    From crosshare with GNU Affero General Public License v3.0 6 votes vote down vote up
PotentialFillItem = (props: PotentialFillItemProps) => {
  function click(e: MouseEvent) {
    e.preventDefault();
    props.dispatch({
      type: 'CLICKEDFILL',
      entryIndex: props.entryIndex,
      value: props.value[0],
    });
    if (props.gridRef.current) {
      props.gridRef.current.focus();
    }
  }
  return (
    <ButtonReset
      css={{
        width: '100%',
        padding: '0.5em 1em',
        color: 'var(--text)',
        '&:hover': {
          backgroundColor: 'var(--bg-hover)',
        },
        alignItems: 'center',
        height: 35,
      }}
      onClick={click}
      text={props.value[0]}
    />
  );
}
Example #13
Source File: Table.tsx    From mStable-apps with GNU Lesser General Public License v3.0 6 votes vote down vote up
TableRow: FC<{ className?: string; onClick?: () => void; buttonTitle?: string }> = ({
  children,
  buttonTitle,
  onClick,
  className,
}) => {
  const handleOnClick = (e: MouseEvent<HTMLButtonElement | HTMLTableRowElement>): void => {
    e?.stopPropagation()
    onClick?.()
  }
  return (
    <Row className={className} role="row" onClick={handleOnClick} isSelectable={!!onClick}>
      {children}
      <Cell role="cell">
        {buttonTitle && (
          <Button highlighted onClick={handleOnClick}>
            {buttonTitle}
          </Button>
        )}
      </Cell>
    </Row>
  )
}
Example #14
Source File: Modal.tsx    From flame with MIT License 6 votes vote down vote up
Modal = ({
  isOpen,
  setIsOpen,
  children,
  cb,
}: Props): JSX.Element => {
  const modalRef = useRef(null);
  const modalClasses = [
    classes.Modal,
    isOpen ? classes.ModalOpen : classes.ModalClose,
  ].join(' ');

  const clickHandler = (e: MouseEvent) => {
    if (e.target === modalRef.current) {
      setIsOpen(false);

      if (cb) cb();
    }
  };

  return (
    <div className={modalClasses} onClick={clickHandler} ref={modalRef}>
      {children}
    </div>
  );
}
Example #15
Source File: Contexts.tsx    From plasmic with MIT License 6 votes vote down vote up
DeleteButtonContext = React.createContext<
  | {
      id: string;
      count: number;
      onCancel: (e: MouseEvent) => void;
      onOk: (e: MouseEvent) => void;
    }
  | undefined
>(undefined)
Example #16
Source File: SchoolPageMenu.tsx    From po8klasie with GNU General Public License v3.0 6 votes vote down vote up
SchoolPageMenu: FC<SchoolPageMenuProps> = ({ sectionConfigs }) => {
  const handleLinkClick = (id: string) => (e: MouseEvent) => {
    e.preventDefault();
    const section = document.getElementById(id);
    if (section) {
      const y = section.getBoundingClientRect().top + window.scrollY;
      window.scroll({
        top: y - 100,
        behavior: 'smooth',
      });
    }
  };
  return (
    <ul className="top-navbarHeight sticky pt-5 flex md:block">
      {sectionConfigs.map(({ id, name }) => (
        <li
          key={id}
          className="font-semibold first:mt-0 md:my-5 text-gray"
          data-to-scrollspy-id={id}
        >
          <a href={`#${id}`} onClick={handleLinkClick(id)}>
            {name}
          </a>
        </li>
      ))}
    </ul>
  );
}
Example #17
Source File: PaginationButtons.tsx    From listo with MIT License 6 votes vote down vote up
PaginationButtons = () => {
  const classes = useStyles();
  const {
    activeStep,
    handleBack,
    handleNext,
    checkStepValid,
    loading,
    setLoading,
  } = useContext(StepContext);

  const stepValid = checkStepValid(activeStep);

  return (
    <div className={classes.buttons}>
      {activeStep !== 0 && (
        <Button onClick={handleBack} className={classes.button}>
          Back
        </Button>
      )}
      {loading ? (
        <CircularProgress size={20} color="secondary" />
      ) : (
        <Button
          variant="contained"
          color="primary"
          onClick={(e: MouseEvent) => {
            setLoading(true);
            handleNext(e);
          }}
          className={classes.button}
          disabled={!stepValid}
        >
          {activeStep === STEPS.length - 1 ? 'Submit' : 'Next'}
        </Button>
      )}
    </div>
  );
}
Example #18
Source File: WalletModalButton.tsx    From wallet-adapter with Apache License 2.0 6 votes vote down vote up
WalletModalButton: FC<ButtonProps> = ({ children = 'Select Wallet', onClick, ...props }) => {
    const { visible, setVisible } = useWalletModal();

    const handleClick = useCallback(
        (event: MouseEvent<HTMLButtonElement>) => {
            if (onClick) onClick(event);
            if (!event.defaultPrevented) setVisible(!visible);
        },
        [onClick, visible]
    );

    return (
        <Button className="wallet-adapter-button-trigger" onClick={handleClick} {...props}>
            {children}
        </Button>
    );
}
Example #19
Source File: index.tsx    From electron-playground with MIT License 6 votes vote down vote up
EditorToolbar: React.FunctionComponent<IEditorToolbarProps> = props => {
  const { tools, style } = props

  const ToolItems = useMemo(() => {
    if (!tools?.length) return null
    const items: ReactElement[] = []
    tools.forEach((tool, index) => {
      const { icon, text, onClick } = { ...iconMap.get(tool.type), ...tool }

      items.push(
        <div onClick={onClick} className={styles.item} key={index}>
          {icon}
          <span>{text}</span>
        </div>,
      )
    })
    return items
  }, [tools])

  const handleOpenEditor = (event: MouseEvent<HTMLElement>) => {
    event.preventDefault()

    window.$EB.openWindow('editor')
  }

  return (
    <div className={styles.container} style={style}>
      <div className={styles.btn}>{ToolItems}</div>
    </div>
  )
}
Example #20
Source File: time-slider.tsx    From covid_dashboard with MIT License 5 votes vote down vote up
dragTimeline(e: MouseEvent<HTMLDivElement>) {
        if (!this.mouseDown) return
        const dx = e.clientX - this.initX
        let newDate = new Date(this.initT.getTime() - dx / this.caliberInterval * 6 * 3600 * 1000)
        this.setTime(newDate)
    }
Example #21
Source File: MoreMenu.tsx    From anchor-web-app with Apache License 2.0 5 votes vote down vote up
function MoreMenuBase({ children, className }: MoreMenuProps) {
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);

  return (
    <>
      <MoreButton
        onClick={(event: MouseEvent<HTMLButtonElement>) =>
          setAnchorEl(event.currentTarget)
        }
      >
        More {anchorEl ? <ExpandLess /> : <ExpandMore />}
      </MoreButton>

      <Popover
        open={!!anchorEl}
        anchorEl={anchorEl}
        onClose={() => setAnchorEl(null)}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'right',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'right',
        }}
        className={className}
      >
        <MenuList variant="menu">
          {Children.map(children, (child) => {
            return cloneElement(child, {
              children: (
                <IconSpan>
                  {child.props.children} <ChevronRightRounded />
                </IconSpan>
              ),
            });
          })}
        </MenuList>
      </Popover>
    </>
  );
}
Example #22
Source File: ContextMenuTrigger.tsx    From wiregui with MIT License 5 votes vote down vote up
ContextMenuTrigger: React.FC<Props> = ({
  children,
  menuId,
  passData,
  onTrigger = () => {
    return;
  },
}) => {
  const [, setContextMenusState] = useRecoilState(contextMenusAtom);

  // when the trigger is right clicked,
  // we want to add a menu in our context or update it if it already exists
  return (
    <Box
      onContextMenu={(event: MouseEvent) => {
        // dont show the browser menu
        event.preventDefault();

        // run an optional action on trigger
        onTrigger();

        // update the position where the ContextMenuList should be shown
        setContextMenusState((oldState) => ({
          ...oldState,
          // set the passthrough data
          passData,
          // update the mouse position
          position: {
            x: event.clientX,
            y: event.clientY,
          },
          // update which menu should be showing
          menus: oldState.menus.find((m) => m.id === menuId)
            ? // open the menu if it exists and close all others
              oldState.menus.map((m) => {
                if (m.id === menuId) {
                  return {
                    ...m,
                    isOpen: true,
                  };
                }
                return {
                  ...m,
                  isOpen: false,
                };
              })
            : // create the menu if it doesnt exist and close all others
              [
                {
                  id: menuId,
                  isOpen: true,
                },
                ...oldState.menus.map((m) => {
                  return {
                    ...m,
                    isOpen: false,
                  };
                }),
              ],
        }));
      }}
    >
      {children}
    </Box>
  );
}
Example #23
Source File: dialog-delete.tsx    From keycaplendar with MIT License 5 votes vote down vote up
DialogDelete = ({
  close,
  open,
  openSnackbar,
  set,
}: DialogDeleteProps) => {
  const user = useAppSelector(selectUser);
  const deleteEntry = (e: MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    firestore
      .collection("keysets")
      .doc(set.id as KeysetId)
      .set({
        latestEditor: user.id,
      } as KeysetDoc)
      .then(() => {
        openSnackbar();
        getData();
      })
      .catch((error) => {
        console.error("Error deleting document: ", error);
        queue.notify({ title: `Error deleting document: ${error}` });
      });
    close();
  };
  return (
    <Dialog open={open}>
      <DialogTitle>{`Delete ${set.profile} ${set.colorway}`}</DialogTitle>
      <DialogContent>
        {`Are you sure you want to delete the entry for ${set.profile} ${set.colorway}`}
        ?
      </DialogContent>
      <DialogActions>
        <DialogButton action="close" isDefaultAction onClick={close}>
          Cancel
        </DialogButton>
        <DialogButton
          /*action="accept"*/ className="delete"
          onClick={deleteEntry}
        >
          Delete
        </DialogButton>
      </DialogActions>
    </Dialog>
  );
}
Example #24
Source File: TextArea.tsx    From Notepad with MIT License 5 votes vote down vote up
function TextArea() {
  const [linesNum, setLineNum] = useState(1);
  const [columnIndex, setColumnIndex] = useState(0);
  const [textAreaContent, setTextAreaContent] = useState(() => {
    return getFromLocalStorage("notepad_textarea_content") || "";
  });

  function handleTextAreaChange(
    event:
      | ChangeEvent<HTMLTextAreaElement>
      | KeyboardEvent<HTMLTextAreaElement>
      | MouseEvent<HTMLTextAreaElement>
  ) {
    setLineNum(getLineNumber(event.target as HTMLTextAreaElement));
    setColumnIndex(getColumnIndex(event.target as HTMLTextAreaElement));
    setTextAreaContent((event.target as HTMLTextAreaElement).value);
    setToLocalStorage(
      "notepad_textarea_content",
      event.target as HTMLTextAreaElement
    );
  }

  useEffect(() => {
    let textAreaElem: HTMLTextAreaElement = document.getElementById(
      "text-area"
    ) as HTMLTextAreaElement;
    enableTabIndentation(textAreaElem);

    new UserPreference().setFontSettings();
  }, []);

  return (
    <>
      <textarea
        name="text-area"
        id="text-area"
        autoFocus
        spellCheck="false"
        value={textAreaContent}
        onKeyUp={handleTextAreaChange}
        onKeyDown={handleTextAreaChange}
        onKeyPress={handleTextAreaChange}
        onChange={handleTextAreaChange}
        onFocus={handleTextAreaChange}
        onMouseUp={handleTextAreaChange}
        data-testid="text-area"
      />
      <div className="details-tab">
        <div className="line-number">
          <p data-testid="line-index">
            Ln {linesNum}, Col {columnIndex}
          </p>
        </div>
        <div className="extra-details"></div>
      </div>
    </>
  );
}
Example #25
Source File: Section.tsx    From nhsuk-react-components-extensions with MIT License 5 votes vote down vote up
Section: React.FC<SectionProps> = ({
  children,
  className,
  heading,
  open,
  defaultOpen,
  tabIndex,
  ...rest
}) => {
  const [isOpen, setIsOpen] = useState<boolean>(open === undefined ? Boolean(defaultOpen) : open);

  const onSummaryClick = (event: MouseEvent<HTMLDetailsElement>) => {
    event.preventDefault();
    if (open === undefined) {
      setIsOpen(!isOpen);
    }
  };

  useEffect(() => {
    if (open !== undefined && isOpen !== open) {
      setIsOpen(open);
    }
  }, [isOpen, open]);

  return (
    <details
      className={classNames('nhsuk-accordion-menu__section', className)}
      open={isOpen}
      {...rest}
    >
      {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
      <summary
        className="nhsuk-accordion-menu__section-summary"
        role="tab"
        tabIndex={tabIndex || 1}
        onClick={onSummaryClick}
      >
        <span className="nhsuk-accordion-menu__section-summary-text">{heading}</span>
        <ToggleIcon open={isOpen} />
      </summary>
      {children}
    </details>
  );
}
Example #26
Source File: Big.tsx    From hive with MIT License 5 votes vote down vote up
preventDefault = (e: MouseEvent) => {
        const { edit } = this.props;
        if (!edit) e.stopPropagation();
    };
Example #27
Source File: scrollingCarousel.spec.tsx    From react-carousel with MIT License 5 votes vote down vote up
describe('<ScrollingCarousel />', () => {
	let mockGetPageX: jest.SpyInstance<
		number,
		[React.TouchEvent<Element> | React.MouseEvent<Element, globalThis.MouseEvent>]
	>;

	afterEach(() => {
		mockGetPageX.mockRestore();
		jest.clearAllTimers();
		jest.resetAllMocks();
		cleanup();
	});

	beforeEach(() => {
		Object.defineProperties(HTMLDivElement.prototype, {
			scrollWidth: {
				value: 1000,
				writable: true
			},
			scrollLeft: {
				value: 100,
				writable: true
			},
			offsetWidth: {
				value: 200,
				writable: true
			},
		});

		jest.useFakeTimers();
		mockGetPageX = jest
			.spyOn(helpers, 'getPageX')
			.mockImplementation((_: MouseEvent) => 600);
	});

	it('should render right layout', async () => {
		const { getByTestId } = render(
			<ScrollingCarousel
				children={carouselItemNodes(6)}
			/>,
		);
		const carousel = getByTestId('carousel');

		expect(carousel.firstChild);
		expect(carousel.firstChild!.firstChild).toBeTruthy();
	});

	it('should render arrow icons', async () => {
		const { getByTestId } = render(
			<ScrollingCarousel
				rightIcon={<i />}
				children={carouselItemNodes(6)}
			/>,
		);
		const carousel = getByTestId('carousel');
		const rightArrow = carousel.querySelector('[data-arrow="right"]');
		const leftArrow = carousel.querySelector('[data-arrow="left"]');
		expect(carousel.firstChild);
		expect(carousel.firstChild!.firstChild).toBeTruthy();
		expect(rightArrow!.firstChild).toBeInstanceOf(HTMLElement);
		expect(leftArrow!.firstChild).toBeInstanceOf(HTMLElement);
	});
});
Example #28
Source File: EntityRelationsGraph.tsx    From backstage with Apache License 2.0 5 votes vote down vote up
EntityRelationsGraph = (props: {
  rootEntityNames: CompoundEntityRef | CompoundEntityRef[];
  maxDepth?: number;
  unidirectional?: boolean;
  mergeRelations?: boolean;
  kinds?: string[];
  relations?: string[];
  direction?: Direction;
  onNodeClick?: (value: EntityNode, event: MouseEvent<unknown>) => void;
  relationPairs?: RelationPairs;
  className?: string;
  zoom?: 'enabled' | 'disabled' | 'enable-on-click';
  renderNode?: DependencyGraphTypes.RenderNodeFunction<EntityNode>;
  renderLabel?: DependencyGraphTypes.RenderLabelFunction<EntityEdge>;
}) => {
  const {
    rootEntityNames,
    maxDepth = Number.POSITIVE_INFINITY,
    unidirectional = true,
    mergeRelations = true,
    kinds,
    relations,
    direction = Direction.LEFT_RIGHT,
    onNodeClick,
    relationPairs = ALL_RELATION_PAIRS,
    className,
    zoom = 'enabled',
    renderNode,
    renderLabel,
  } = props;

  const theme = useTheme();
  const classes = useStyles();
  const rootEntityRefs = useMemo(
    () =>
      (Array.isArray(rootEntityNames)
        ? rootEntityNames
        : [rootEntityNames]
      ).map(e => stringifyEntityRef(e)),
    [rootEntityNames],
  );
  const errorApi = useApi(errorApiRef);
  const { loading, error, nodes, edges } = useEntityRelationNodesAndEdges({
    rootEntityRefs,
    maxDepth,
    unidirectional,
    mergeRelations,
    kinds,
    relations,
    onNodeClick,
    relationPairs,
  });

  useEffect(() => {
    if (error) {
      errorApi.post(error);
    }
  }, [errorApi, error]);

  return (
    <div className={classNames(classes.container, className)}>
      {loading && <CircularProgress className={classes.progress} />}
      {nodes && edges && (
        <DependencyGraph
          nodes={nodes}
          edges={edges}
          renderNode={renderNode || CustomNode}
          renderLabel={renderLabel || CustomLabel}
          direction={direction}
          className={classes.graph}
          paddingX={theme.spacing(4)}
          paddingY={theme.spacing(4)}
          labelPosition={DependencyGraphTypes.LabelPosition.RIGHT}
          labelOffset={theme.spacing(1)}
          zoom={zoom}
        />
      )}
    </div>
  );
}
Example #29
Source File: SelectList.tsx    From ke with MIT License 5 votes vote down vote up
SelectList = ({
  values,
  selectedValues,
  getOptionLabel,
  getOptionValue,
  handleChange,
  disabledValues = [],
  handleScrollBottom,
}: SelectListProps): JSX.Element => {
  const trueValues = values.map((value) => {
    const listValue = getOptionValue(value)
    const listLabel = getOptionLabel(value)

    return {
      value: listValue,
      label: listLabel,
      selected: selectedValues.find((s) => s === listValue) !== undefined,
      disabled: disabledValues.find((d) => d === listValue) !== undefined,
      self: value,
    }
  })

  const onListClick: (e: MouseEvent<HTMLUListElement>) => void = (e: MouseEvent<HTMLUListElement>) => {
    e.stopPropagation()
    const target: HTMLElement = e.target as HTMLElement
    const valueAttribute = target.attributes.getNamedItem('value')
    const listItemValue: string = valueAttribute ? valueAttribute.value : ''
    const item = trueValues.find((tv) => tv.value === listItemValue)

    if (item !== undefined && !item.disabled) {
      let items: string[] = []
      if (!e.ctrlKey) {
        items = item.selected ? [] : [item.value]
      } else {
        items = item.selected
          ? selectedValues.filter((svItem) => svItem !== item.value)
          : selectedValues.concat([item.value])
      }
      handleChange(items)
    }
  }

  return (
    <List
      onClick={onListClick}
      onScroll={
        handleScrollBottom
          ? (e) => {
              const target: HTMLElement = e.target as HTMLElement
              if (target.scrollTop + target.clientHeight === target.scrollHeight) {
                handleScrollBottom()
              }
            }
          : undefined
      }
    >
      {trueValues.map((v) => {
        const { value, label, selected: vSelected, disabled: vDisabled } = v

        return (
          <ListItem key={value} value={value} className={`${vSelected && 'selected'} ${vDisabled && 'disabled'}`}>
            {label}
          </ListItem>
        )
      })}
    </List>
  )
}