react-intersection-observer#InView TypeScript Examples

The following examples show how to use react-intersection-observer#InView. 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: InViewObserver.tsx    From clearflask with Apache License 2.0 6 votes vote down vote up
render() {
    if (this.props.disabled) return this.props.children;
    return (
      <InView onChange={(inView, entry) => {
        if (inView) {
          this.resolve(entry);
        } else {
          this.promise = new Promise(resolve => { this.resolve = resolve });
        }
      }}>
        {this.props.children}
      </InView>
    );
  }
Example #2
Source File: FadeIn.tsx    From papercups.io with MIT License 6 votes vote down vote up
FadeIn = ({
  direction = 'up',
  delay = 0,
  once = true,
  children,
}: {
  direction?: FadeDirection;
  delay?: FadeDelay;
  once?: boolean;
  children: JSX.Element;
}) => {
  const [hidden, visible] = getClassNamesByDirection(direction);
  const delayClassName = getClassNameByDelay(delay);

  return (
    <InView triggerOnce={once}>
      {({inView, ref, entry}) => {
        return (
          <div
            ref={ref}
            className={`transform transition-all ease-in-out duration-500 ${delayClassName} ${
              inView ? `opacity-100 ${visible}` : `opacity-0 ${hidden}`
            }`}
          >
            {children}
          </div>
        );
      }}
    </InView>
  );
}
Example #3
Source File: crewchallenge.tsx    From website with MIT License 4 votes vote down vote up
CrewPicker = (props: CrewPickerProps) => {
	const { rules, guesses, handleSelect } = props;
	const portalCrew = React.useContext(PortalCrewContext);

	const [modalIsOpen, setModalIsOpen] = React.useState(false);
	const [searchFilter, setSearchFilter] = React.useState('');
	const [paginationPage, setPaginationPage] = React.useState(1);
	const [selectedCrew, setSelectedCrew] = React.useState(undefined);
	const [showHints, setShowHints] = React.useState(true);

	const guessesLeft = rules.guesses - guesses.length;

	const inputRef = React.createRef();

	React.useEffect(() => {
		if (modalIsOpen) inputRef.current.focus();
	}, [modalIsOpen]);

	return (
		<Modal
			open={modalIsOpen}
			onClose={() => setModalIsOpen(false)}
			onOpen={() => setModalIsOpen(true)}
			trigger={renderButton()}
			size='tiny'
			centered={false}
			closeIcon
		>
			<Modal.Header>
				<Input ref={inputRef}
					size='mini' fluid
					iconPosition='left'
					placeholder='Search for crew by name'
					value={searchFilter}
					onChange={(e, { value }) => { setSearchFilter(value); setPaginationPage(1); setSelectedCrew(undefined); }}>
						<input />
						<Icon name='search' />
						<Button icon onClick={() => { setSearchFilter(''); setPaginationPage(1); setSelectedCrew(undefined); inputRef.current.focus(); }} >
							<Icon name='delete' />
						</Button>
				</Input>
			</Modal.Header>
			<Modal.Content scrolling>
				{renderGrid()}
			</Modal.Content>
			<Modal.Actions>
				<Button content='Show hints' onClick={() => setShowHints(!showHints) } />
				{selectedCrew && (
					<Button color='blue'
						content={`Guess ${selectedCrew.name}`}
						onClick={() => confirmGuess(selectedCrew.symbol)} />
				)}
				{!selectedCrew && (
					<Button content='Close' onClick={() => setModalIsOpen(false)} />
				)}
			</Modal.Actions>
		</Modal>
	);

	function renderButton(): JSX.Element {
		return (
			<Button fluid size='big' color='blue'>
				<Icon name='zoom-in' />
				Guess Crew
				<span style={{ fontSize: '.95em', fontWeight: 'normal', paddingLeft: '1em' }}>
					({guessesLeft} guess{guessesLeft !== 1 ? 'es' : ''} remaining)
				</span>
			</Button>
		);
	}

	function renderGrid(): JSX.Element {
		if (!modalIsOpen) return (<></>);

		let data = portalCrew.slice();

		if (rules.excludedCrew.length > 0)
			data = data.filter(crew => !rules.excludedCrew.includes(crew.symbol));

		// Filtering
		if (searchFilter !== '') {
			const filter = (input: string) => input.toLowerCase().indexOf(searchFilter.toLowerCase()) >= 0;
			data = data.filter(crew => filter(crew.name));
		}
		if (data.length === 0) return (
			<Message>
				<p>No crew names match your current search.</p>
				<p>Only crew that are currently <b>available in the time portal</b> will be used as mystery crew and valid guesses.</p>
			</Message>
		);

		// Pagination
		const itemsPerPage = 24, itemsToShow = itemsPerPage*paginationPage;

		return (
			<div>
				<Grid doubling columns={3} textAlign='center'>
					{data.slice(0, itemsToShow).map(crew => (
						<Grid.Column key={crew.symbol} style={{ cursor: 'pointer' }}
							onClick={() => { if (!guesses.includes(crew.symbol)) setSelectedCrew(crew); }}
							onDoubleClick={() => { if (!guesses.includes(crew.symbol)) confirmGuess(crew.symbol); }}
							color={selectedCrew?.symbol === crew.symbol ? 'blue' : null}
						>
							<img width={48} height={48} src={`${process.env.GATSBY_ASSETS_URL}${crew.imageUrlPortrait}`} />
							<div>
								{guesses.includes(crew.symbol) && (<Icon name='x' color='red' />)}
								{crew.name}
							</div>
							{!showHints && (
								<div>({[crew.series.toUpperCase(), `${crew.max_rarity}*`].join(', ')})</div>
							)}
						</Grid.Column>
					))}
				</Grid>
				{itemsToShow < data.length && (
					<InView as='div' style={{ margin: '2em 0', textAlign: 'center' }}
						onChange={(inView, entry) => { if (inView) setPaginationPage(prevState => prevState + 1); }}
					>
						<Icon loading name='spinner' /> Loading...
					</InView>
				)}
				{itemsToShow >= data.length && (
					<Message>Tip: Double-tap a crew to make your guess more quickly.</Message>
				)}
			</div>
		);
	}

	function confirmGuess(symbol: string): void {
		handleSelect(symbol);
		setModalIsOpen(false);
		setSelectedCrew(undefined);
	}
}