hooks#useOnScreen TypeScript Examples

The following examples show how to use hooks#useOnScreen. 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: index.tsx    From exevo-pan with The Unlicense 6 votes vote down vote up
LazyRender = ({
  estimatedHeight,
  mediaQuery,
  children,
  ...props
}: LazyRenderProps) => {
  const [shouldRender, setShouldRender] = useState(true)

  const ref = useRef<HTMLDivElement>()
  const onScreen = useOnScreen<HTMLDivElement>(ref)

  useEffect(() => {
    const mediaQueryMatches = mediaQuery
      ? window.matchMedia(mediaQuery).matches
      : false

    setShouldRender(onScreen || mediaQueryMatches)
  }, [onScreen])

  return (
    <div
      ref={ref as React.RefObject<HTMLDivElement>}
      style={{ minHeight: onScreen ? undefined : `${estimatedHeight}px` }}
      {...props}
    >
      {shouldRender && children}
    </div>
  )
}
Example #2
Source File: index.tsx    From exevo-pan with The Unlicense 6 votes vote down vote up
Sticker = ({
  localStorageKey,
  className,
  children,
  ...props
}: StickerProps) => {
  const [hasSticker] = useState(() =>
    getFromLocalStorage(localStorageKey, true),
  )

  const ref = useRef<HTMLSpanElement>(null)
  const onScreen = useOnScreen<HTMLSpanElement>(ref)

  useEffect(() => {
    saveToLocalStorage(localStorageKey, false)
  }, [onScreen])

  if (!hasSticker) return null
  return (
    <span
      className={clsx(
        'bg-battleYellow border-1 border-separator rounded-md border-dashed p-[3px] text-[9px] uppercase tracking-wider text-black opacity-80',
        className,
      )}
      {...props}
      ref={ref}
    >
      {children}
    </span>
  )
}
Example #3
Source File: useShouldRender.tsx    From exevo-pan with The Unlicense 6 votes vote down vote up
useShouldRender = (
  isLazy: boolean,
  ref: React.MutableRefObject<HTMLDivElement | undefined>,
): boolean => {
  if (!isLazy) return true

  const onScreen = useOnScreen(ref, LAZY_LOAD_OVERSCAN)

  const [shouldRender, setShouldRender] = useState(true)

  const debouncedSetRender = useMemo(
    () =>
      debounce((value: boolean) => {
        setShouldRender(value)
      }, UPDATE_SCREEN_DELAY),
    [],
  )

  useEffect(() => {
    debouncedSetRender(onScreen)
  }, [onScreen])

  return shouldRender
}
Example #4
Source File: index.tsx    From exevo-pan with The Unlicense 5 votes vote down vote up
HeadingSection = ({
  children,
  ...props
}: React.HTMLAttributes<HTMLHeadingElement>) => {
  const {
    translations: { common },
  } = useTranslations()

  const [anchorId] = useState(generateSectionId(children as string))

  const elementRef = useRef<HTMLDivElement>(null)
  const onScreen = useOnScreen(elementRef)

  const { setSectionStatus } = useCurrentSection()

  useEffect(() => {
    setSectionStatus({
      title: children?.toString() ?? '',
      status: onScreen,
      offset: elementRef.current?.offsetTop ?? 0,
    })
  }, [onScreen, setSectionStatus])

  return (
    <div
      ref={elementRef}
      className="mt-3 flex w-fit items-center justify-start gap-4"
    >
      <H2 {...props} id={anchorId} className="flex-grow">
        {children}
      </H2>
      <a
        href={`#${anchorId}`}
        onClick={() => CopyToClipboard(anchorId)}
        className="block h-9 w-9 shrink-0"
      >
        <AnchorIcon
          aria-label={common.AnchorIconLabel}
          className="fill-separator hover:fill-primary clickable m-0 h-full w-full cursor-pointer rounded p-0.5 transition-all"
        />
      </a>
    </div>
  )
}
Example #5
Source File: index.tsx    From exevo-pan with The Unlicense 5 votes vote down vote up
LastFrags = ({ fragsList, ...props }: LastFragsProps) => {
  const {
    translations: { war },
  } = useTranslations()

  const [currentIndex, setCurrentIndex] = useState(0)
  const maxIndex = Math.ceil(fragsList.length / PAGE_SIZE) - 1
  const reachedMaxPage = currentIndex >= maxIndex

  const currentList = useMemo(
    () => fragsList.slice(0, (currentIndex + 1) * PAGE_SIZE),
    [currentIndex],
  )

  const ref = useRef<HTMLDivElement>()
  const onScreen = useOnScreen<HTMLDivElement>(ref)
  useEffect(() => {
    if (onScreen) setCurrentIndex((prevIndex) => prevIndex + 1)
  }, [onScreen])

  return (
    <div className="relative">
      <Table {...props}>
        <Table.Element>
          <Table.Head>
            <Table.Row>
              <Table.HeadColumn className="w-20 text-left">
                {war.OverallGrid.LastFrags.killedHeadColumn}
              </Table.HeadColumn>
              <Table.HeadColumn
                highlighted
                desc
                title={war.OverallGrid.LastFrags.characterHeadColumnTitle}
                className="px-4 text-left"
              >
                Character
              </Table.HeadColumn>
            </Table.Row>
          </Table.Head>

          <Table.Body>
            {currentList.map((frag) => (
              <Table.Row key={`${frag.timeStamp}-${frag.nickname}`}>
                <Table.Column className="w-20 text-left align-top text-xs leading-relaxed">{`${getTimeDiff(
                  frag.timeStamp,
                )} ${war.OverallGrid.LastFrags.timeDiffSuffix}`}</Table.Column>
                <CharacterInfoColumn
                  nickname={frag.nickname}
                  level={frag.level}
                  vocation={frag.vocation}
                  className="px-4 text-left"
                />
              </Table.Row>
            ))}
          </Table.Body>
        </Table.Element>
      </Table>
      {!reachedMaxPage && (
        <div
          className="z-1 absolute bottom-[440px] left-0"
          ref={ref as React.RefObject<HTMLDivElement>}
        />
      )}
    </div>
  )
}