react-spring#useSpring TypeScript Examples

The following examples show how to use react-spring#useSpring. 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: ZapQuakeDisplay.tsx    From zapquaker with MIT License 6 votes vote down vote up
export function ZapQuakeDisplay(props: Props) {
  const fade = useSpring({ from: { opacity: 0 }, to: { opacity: 1 } });
  return (
    <animated.div
      style={fade}
      className="mb-2 flex justify-center items-center space-x-2"
    >
      {props.zapQuake.nbZaps !== 0 && (
        <SpellDisplay
          name="lightning"
          maxLevel={DATA_SPELLS[1].damage.length}
          level={props.zapLevel}
          quantity={props.zapQuake.nbZaps}
          size="sm"
        />
      )}
      {props.zapQuake.nbQuakes !== 0 && (
        <SpellDisplay
          name="quake"
          maxLevel={DATA_SPELLS[0].damage.length}
          level={props.quakeLevel}
          quantity={props.zapQuake.nbQuakes}
          size="sm"
        />
      )}
      <span className="spell-capacity-usage font-semibold text-gray-800 dark:text-gray-100">
        ({props.zapQuake.nbQuakes + props.zapQuake.nbZaps}/{props.spellCapacity}
        )
      </span>
    </animated.div>
  );
}
Example #2
Source File: CategoryItem.tsx    From Cromwell with MIT License 6 votes vote down vote up
function TransitionComponent(props: TransitionProps & { children: React.ReactNode }) {
    const style = useSpring({
        from: { opacity: 0, transform: 'translate3d(20px,0,0)' },
        to: { opacity: props.in ? 1 : 0, transform: `translate3d(${props.in ? 0 : 20}px,0,0)` },
    });

    return (
        <animated.div style={style}>
            <Collapse {...props} />
        </animated.div>
    );
}
Example #3
Source File: XarrowV2.stories.tsx    From react-xarrows with MIT License 6 votes vote down vote up
MyComponent = (props: MyComponentPropsType) => {
  const parsedProps = useParseProps(props);

  console.log('look it me', parsedProps.parsedProp1);
  const { myVar } = useSpring({
    from: { myVar: 0 },
    to: { myVar: parsedProps.parsedProp1 },
    loop: true,
    config: { duration: 3000 },
  });
  return (
    <div>
      current val: <animated.div>{myVar}</animated.div>
    </div>
  );
}
Example #4
Source File: hearts.tsx    From wikitrivia with MIT License 6 votes vote down vote up
function Heart(props: HeartProps) {
  const { have } = props;
  const { opacity } = useSpring({
    opacity: have ? 1 : 0.4,
    config: { duration: 300 },
  });
  const { scale } = useSpring({
    scale: have ? 1 : 0.8,
    config: { mass: 1, tension: 200, friction: 20, duration: 300 },
    delay: 200,
  });

  return (
    <animated.img
      className={styles.heart}
      style={{ opacity, scale }}
      src="/images/heart.svg"
    />
  );
}
Example #5
Source File: index.tsx    From documentation with MIT License 6 votes vote down vote up
SectionRightItem: React.FC<Props> = (props) => {
  const { icon, title, description, onClick, active } = props;
  const descriptionRef = useRef(null);

  const animatedDescriptionProps = useSpring({
    to: {
      height: active ? descriptionRef.current?.clientHeight || 'auto' : 0,
      marginTop: active ? 5 : 0,
    },
    config: { tension: 2000, friction: 100, precision: 1 },
  });

  return (
    <div
      className={clsx(styles.Container, {
        [styles.Container_Active]: active,
      })}
      onClick={onClick}>
      <h3 className={styles.Header}>
        {icon && <Icons type={icon} className={styles.Icon} />}
        {title}
      </h3>
      <animated.div
        className={styles.Description}
        style={animatedDescriptionProps}>
        <p ref={descriptionRef}>{description}</p>
      </animated.div>
    </div>
  );
}
Example #6
Source File: Orbit.tsx    From react-planet with MIT License 6 votes vote down vote up
export function Orbit(props: Props) {
	const { orbitRadius, planetWidth, planetHeight, open, tension, friction, mass } = props;
	const classes = useStyles(props);
	const position = useSpring({
		reverse: !open,
		from: getInitalOrbitPosition(planetWidth, planetHeight),
		to: getFinalOrbitPosition(planetWidth, planetHeight, orbitRadius),
		config: { mass, tension, friction },
	});

	return <animated.div className={classes.orbit} style={position} />;
}
Example #7
Source File: index.tsx    From luaswap-interface with GNU General Public License v3.0 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss = () => {},
  minHeight = false,
  maxHeight = 90,
  initialFocusRef,
  children
}: ModalProps) {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  })

  const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
  const bind = useGesture({
    onDrag: state => {
      set({
        y: state.down ? state.movement[1] : 0
      })
      if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
        onDismiss()
      }
    }
  })

  return (
    <>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </>
  )
}
Example #8
Source File: BetterYield.tsx    From anchor-web-app with Apache License 2.0 5 votes vote down vote up
function BetterYieldBase({ className }: BetterYieldProps) {
  const elementRef = useRef<HTMLElement>(null);

  const elementIntersection = useElementIntersection({
    elementRef,
    threshold: 0.8,
    observeOnce: true,
  });

  const intersection = useSpring<Value>({
    ratio: elementIntersection?.isIntersecting === true ? 1 : 0,
    config: {
      friction: 60,
    },
  });

  return (
    <section
      ref={elementRef}
      className={className}
      data-intersection={elementIntersection?.isIntersecting}
    >
      <article>
        <h2>
          Anchor
          <br />
          offers
          <br />
          better yield
        </h2>
        <p>
          Anchor's yield is stable and attractive - powered by staking returns
          from multiple Proof of Stake blockchains.
          <br />
          <a href={links.betterYield} target="_blank" rel="noreferrer">
            Learn more <CircleArrowRight />
          </a>
        </p>
      </article>

      <figure>
        <Circle ratio={intersection.ratio} />
      </figure>
    </section>
  );
}
Example #9
Source File: game-over.tsx    From wikitrivia with MIT License 5 votes vote down vote up
export default function GameOver(props: Props) {
  const { highscore, resetGame, score } = props;

  const animProps = useSpring({
    opacity: 1,
    from: { opacity: 0 },
    config: { duration: 500 },
  });

  const [shareText, setShareText] = React.useState(defaultShareText);

  const share = React.useCallback(async () => {
    await navigator?.clipboard?.writeText(
      `?️ wikitrivia.tomjwatson.com\n\n${getMedal(
        score
      )}Streak: ${score}\n${getMedal(highscore)}Best Streak: ${highscore}`
    );
    setShareText("Copied");
    setTimeout(() => {
      setShareText(defaultShareText);
    }, 2000);
  }, [highscore, score]);

  return (
    <animated.div style={animProps} className={styles.gameOver}>
      <div className={styles.scoresWrapper}>
        <div className={styles.score}>
          <Score score={score} title="Streak" />
        </div>
        <div className={styles.score}>
          <Score score={highscore} title="Best streak" />
        </div>
      </div>
      <div className={styles.buttons}>
        <Button onClick={resetGame} text="Play again" />
        <Button onClick={share} text={shareText} minimal />
      </div>
    </animated.div>
  );
}
Example #10
Source File: index.tsx    From sushiswap-exchange with GNU General Public License v3.0 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss,
  minHeight = false,
  maxHeight = 50,
  initialFocusRef,
  children
}: ModalProps) {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  })

  const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
  const bind = useGesture({
    onDrag: state => {
      set({
        y: state.down ? state.movement[1] : 0
      })
      if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
        onDismiss()
      }
    }
  })

  return (
    <>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </>
  )
}
Example #11
Source File: PokemonDetailsHeader.tsx    From react-pokedex with MIT License 5 votes vote down vote up
PokemonDetailsHeader = ({
  pokemon,
  species,
  selectedBackgroundColor,
}: Props) => {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const { width, height, top, left } = useResize(containerRef);
  const [props, set] = useSpring(() => ({
    xy: [0, 0],
    config: { mass: 10, tension: 550, friction: 140 },
  }));

  const kanjiName = species.names.find(
    (name) => name.language.name === "ja-Hrkt"
  );
  const imagePlaceholder = pokemon.types.map(({ type }) => {
    const [[, image]] = Object.entries(PokemonTypePlaceholders).filter(
      ([key, _]) => key === type.name
    );

    return image;
  });

  return (
    <>
      <div
        className="w-full"
        ref={containerRef}
        onMouseMove={({ clientX, clientY }) =>
          set({
            xy: calc(clientX - left, clientY - top, width + left, height + top),
          })
        }
      >
        <div className="px-4 md:px-8">
          <p className="text-md mt-4 text-white font-medium">
            #{leftPad(pokemon.id, 3)}
          </p>
          <h1 className="text-2xl md:text-3xl lg:text-4xl text-white font-bold pb-6 capitalize">
            {pokemon.name}
          </h1>
        </div>

        <div className="relative text-center mx-auto w-full h-96 mt-8 lg:mt-24">
          <h1 className="absolute -mt-2 text-6xl z-0 w-full text-white opacity-50 font-extrabold overflow-hidden">
            {kanjiName && kanjiName.name}
          </h1>

          <animated.div
            style={{
              ...MaskStyling,
              backgroundColor: selectedBackgroundColor.light,
              //@ts-ignore
              transform: props.xy.interpolate(trans1),
            }}
            className="rounded-full absolute inset-x-auto mx-auto z-0 inline-block left-0 right-0"
          />

          <animated.div
            style={{
              ...PokemonImageStyling,
              position: "absolute",
              //@ts-ignore
              transform: props.xy.interpolate(trans2),
            }}
          >
            <ProgressiveImage
              preview={imagePlaceholder[0]}
              src={pokemon.sprites.frontDefault}
              render={(src, style) => (
                <img src={src} alt={pokemon.name} style={style} />
              )}
            />
          </animated.div>
        </div>
      </div>
      <div className="-mt-12" />
    </>
  );
}
Example #12
Source File: DragControls.tsx    From spacesvr with MIT License 5 votes vote down vote up
/**
 * DragControls allows for a click-and-drag control
 * of the camera
 *
 * @param props
 * @constructor
 */
export function DragControls() {
  const originEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
  const setEuler = useRef<Euler>(new Euler(0, 0, 0, "YXZ"));
  const mouseDownPos = useRef<Vector2>(new Vector2(0, 0));
  const dragging = useRef(false);
  const camera = useThree((state) => state.camera);
  const { containerRef } = useEnvironment();
  const [xyz, setXYZ] = useState([0, 0, 0]);

  const { x, y, z } = useSpring({
    x: xyz[0],
    y: xyz[1],
    z: xyz[2],
    config: { ...config.default, precision: 0.0001 },
  });

  useFrame(() => {
    if (setEuler.current) {
      setEuler.current.set(x.get(), y.get(), z.get());
      camera.quaternion.setFromEuler(setEuler.current);
    }
  });

  const getNewEuler = (
    dragX: number,
    dragY: number,
    isHover?: boolean
  ): Euler => {
    const newEuler = originEuler.current.clone();
    const moveX = dragX - mouseDownPos.current.x;
    const moveY = dragY - mouseDownPos.current.y;

    const SENSITIVITY = isHover ? HOVER_SENSITIVITY : DRAG_SENSITIVITY;

    newEuler.setFromQuaternion(camera.quaternion);
    newEuler.y = originEuler.current.y - (moveX * SENSITIVITY.x) / 100;
    newEuler.x = originEuler.current.x - (moveY * SENSITIVITY.y) / 100;
    // newEuler.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, newEuler.x));

    return newEuler;
  };

  // touch move scripts
  const onMouseDown = (ev: MouseEvent) => {
    dragging.current = true;
    mouseDownPos.current.set(ev.clientX, ev.clientY);
    containerRef?.current?.classList.add("grabbing");
  };
  const onMouseMove = (ev: MouseEvent) => {
    const newEuler = getNewEuler(ev.clientX, ev.clientY, !dragging.current);
    setXYZ(newEuler.toArray());
  };
  const onMouseUp = (ev: MouseEvent) => {
    dragging.current = false;
    originEuler.current = getNewEuler(ev.clientX, ev.clientY);
    mouseDownPos.current.set(ev.clientX, ev.clientY);
    containerRef?.current?.classList.remove("grabbing");
  };

  useEffect(() => {
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseup", onMouseUp);

    return () => {
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
    };
  }, [containerRef]);

  return null;
}
Example #13
Source File: PopupItem.tsx    From pancake-swap-exchange-testnet with GNU General Public License v3.0 5 votes vote down vote up
export default function PopupItem({
  removeAfterMs,
  content,
  popKey
}: {
  removeAfterMs: number | null
  content: PopupContent
  popKey: string
}) {
  const removePopup = useRemovePopup()
  const removeThisPopup = useCallback(() => removePopup(popKey), [popKey, removePopup])
  useEffect(() => {
    if (removeAfterMs === null) return undefined

    const timeout = setTimeout(() => {
      removeThisPopup()
    }, removeAfterMs)

    return () => {
      clearTimeout(timeout)
    }
  }, [removeAfterMs, removeThisPopup])

  const theme = useContext(ThemeContext)

  let popupContent
  if ('txn' in content) {
    const {
      txn: { hash, success, summary }
    } = content
    popupContent = <TransactionPopup hash={hash} success={success} summary={summary} />
  } else if ('listUpdate' in content) {
    const {
      listUpdate: { listUrl, oldList, newList, auto }
    } = content
    popupContent = <ListUpdatePopup popKey={popKey} listUrl={listUrl} oldList={oldList} newList={newList} auto={auto} />
  }

  const faderStyle = useSpring({
    from: { width: '100%' },
    to: { width: '0%' },
    config: { duration: removeAfterMs ?? undefined }
  })

  return (
    <Popup>
      <StyledClose color={theme.colors.textSubtle} onClick={removeThisPopup} />
      {popupContent}
      {removeAfterMs !== null ? <AnimatedFader style={faderStyle} /> : null}
    </Popup>
  )
}
Example #14
Source File: chip.tsx    From monopoly with MIT License 5 votes vote down vote up
Chip = memo(
  ({ points, color }: ChipProps) => {
    const chipAnimatedDisabled = ls.get('chipAnimatedDisabled');

    const handleStartAnimation = () => {
      console.log('animation start');
      gameSettingStore.setChipMoveActive(true);
    };

    const handleEndAnimation = () => {
      console.log('animation end');
      gameSettingStore.setChipMoveActive(false);
    };

    const props = useSpring({
      // @ts-ignore
      to: async (animate: any) => {
        for (const { x, y, duration } of points) {
          await animate({
            transform: `translate(${x}px, ${y}px)`,
            config: {
              easing: easeQuadInOut,
              duration: chipAnimatedDisabled ? 0 : duration,
              precision: 0.01,
            },
          });
        }
      },
      from: {
        transform: `translate(${0}px, ${0}px)`,
      },
      onStart: handleStartAnimation,
      onRest: handleEndAnimation,
    });

    return <ChipWrapper color={color} style={props} />;
  },
  (prevProps, nextProps) => {
    return (
      JSON.stringify(prevProps.points) === JSON.stringify(nextProps.points)
    );
  },
)
Example #15
Source File: Satellite.tsx    From react-planet with MIT License 5 votes vote down vote up
export function Satellite(props: Props) {
  const {
    children,
    index,
    satelliteCount,
    open,
    planetWidth,
    planetHeight,
    tension,
    friction,
    mass,
    orbitRadius,
    rotation,
    dragable,
    dragRadius,
    orientation,
  } = props;
  const classes = useStyles(props);
  const { ref, height = 0, width = 0 } = useResizeObserver();
  const position = useSpring({
    reverse: !open,
    from: getInitalSatellitePosition(width, height, planetWidth, planetHeight),
    to: getFinalSatellitePosition(
      index,
      satelliteCount,
      width,
      height,
      planetWidth,
      planetHeight,
      orbitRadius,
      rotation,
      orientation
    ),
    config: { mass, tension, friction },
  });

  return (
    <animated.div className={classes.root} style={position}>
      <DragableContainer
        on={dragable}
        dragRadius={dragRadius}
        dragable={dragable}
      >
        <div ref={ref as any}>{children}</div>
      </DragableContainer>
    </animated.div>
  );
}
Example #16
Source File: index.tsx    From limit-orders-lib with GNU General Public License v3.0 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss,
  minHeight = false,
  maxHeight = 90,
  initialFocusRef,
  children,
}: ModalProps) {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
  });

  const [{ y }, set] = useSpring(() => ({
    y: 0,
    config: { mass: 1, tension: 210, friction: 20 },
  }));
  const bind = useGesture({
    onDrag: (state) => {
      set({
        y: state.down ? state.movement[1] : 0,
      });
      if (
        state.movement[1] > 300 ||
        (state.velocity > 3 && state.direction[1] > 0)
      ) {
        onDismiss();
      }
    },
  });

  return (
    <Fragment>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay
              key={key}
              style={props}
              onDismiss={onDismiss}
              initialFocusRef={initialFocusRef}
              unstable_lockFocusAcrossFrames={false}
            >
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: {
                        transform: y.interpolate(
                          (y) => `translateY(${(y as number) > 0 ? y : 0}px)`
                        ),
                      },
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </Fragment>
  );
}
Example #17
Source File: index.tsx    From dyp with Do What The F*ck You Want To Public License 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss,
  minHeight = false,
  maxHeight = 90,
  initialFocusRef,
  children
}: ModalProps) {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  })

  const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
  const bind = useGesture({
    onDrag: state => {
      set({
        y: state.down ? state.movement[1] : 0
      })
      if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
        onDismiss()
      }
    }
  })

  return (
    <>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </>
  )
}
Example #18
Source File: Reveal.tsx    From covid19map with MIT License 5 votes vote down vote up
Reveal = ({
  button,
  full,
  open,
  toggle,
  children,
}: {
  button: any;
  full: boolean;
  open: boolean;
  toggle: (open: boolean) => void;
  children: React.ReactNode;
}) => {
  const defaultHeight = 0;

  // if (!open && !toggle) {
  //   [open, toggle] = useState(false);
  // }

  const [contentHeight, setContentHeight] = useState<number>(defaultHeight);
  const [ref, { height }] = useMeasure();

  // Animations
  const expand = useSpring({
    // config: {
    // friction: 10,
    // duration: 300,
    // },
    height: open ? `${contentHeight}px` : defaultHeight,
  });

  useEffect(() => {
    //Sets initial height
    setContentHeight(height);

    //Adds resize event listener
    // window.addEventListener("resize", setContentHeight(height));
    // return window.removeEventListener("resize", setContentHeight(height));
  }, [height]);

  return (
    <>
      {button && (
        <InvisibleButton
          onClick={() => {
            toggle(!open);
          }}
          active={open}
        >
          {button}
        </InvisibleButton>
      )}
      <Container full={full}>
        <animated.div style={expand}>
          <div ref={ref}>{children}</div>
        </animated.div>
      </Container>
    </>
  );
}
Example #19
Source File: index.tsx    From documentation with MIT License 5 votes vote down vote up
LiveCoderReact: React.FC<Props> = (props) => {
  const { code, theme, transformCode } = props;
  const { windowWidth } = useWindowSize();
  const [showCodeLabel, setShowCodeLabel] = useState(true);
  const [displayCodeLabel, setDisplayCodeLabel] = useState(true);
  const labelShowAnimationProps = useSpring({
    to: {
      opacity: showCodeLabel ? 1 : 0,
    },
    onRest: () => {
      if (!showCodeLabel) setDisplayCodeLabel(showCodeLabel);
    },
    onStart: () => {
      if (showCodeLabel) setDisplayCodeLabel(showCodeLabel);
    },
  });

  const [mounted, setMounted] = useState(false);
  // The Prism theme on SSR is always the default theme but the site theme
  // can be in a different mode. React hydration doesn't update DOM styles
  // that come from SSR. Hence force a re-render after mounting to apply the
  // current relevant styles. There will be a flash seen of the original
  // styles seen using this current approach but that's probably ok. Fixing
  // the flash will require changing the theming approach and is not worth it
  // at this point.
  useEffect(() => {
    setMounted(true);
  }, []);

  return (
    <LiveProvider
      key={String(mounted)}
      code={code.replace(/\n$/, '')}
      transformCode={transformCode || ((code) => `${code};`)}
      theme={theme}
      noInline={true}
      scope={ReactLiveScope}>
      <div
        className={styles.EditorContainer}
        onMouseEnter={() => {
          if (windowWidth <= 800) setShowCodeLabel(false);
        }}
        onMouseLeave={() => setShowCodeLabel(true)}>
        <LiveEditor className={styles.Editor} />
        <animated.div
          className={styles.LiveLabel}
          style={{
            ...labelShowAnimationProps,
            ...{ display: displayCodeLabel ? 'block' : 'none' },
          }}>
          Live
        </animated.div>
      </div>
      <div className={styles.PreviewOuterContainer}>
        <div className={styles.PreviewContainer}>
          <LivePreview />
          <LiveError />
        </div>
        <div className={styles.Label}>Preview</div>
      </div>
    </LiveProvider>
  );
}
Example #20
Source File: index.tsx    From documentation with MIT License 5 votes vote down vote up
Astronaut: React.FC<Props> = (props) => {
  const { className } = props;
  const [isRaised, setIsRaised] = useState(false);
  const [inAnimation, setInAnimation] = useState(false);
  const [triggeredAnimationColor, setTriggeredAnimationColor] = useState(false);
  const dark = useAgile(core.ui.ASTRONAUT_DARK);

  // Animation
  const animatedAstronautProps = useSpring({
    to: { x: isRaised ? 0 : 1 },
    config: {
      mass: 1,
      tension: 400,
      friction: 15,
      duration: 500,
    },
    onRest: () => {
      if (inAnimation) {
        setInAnimation(false);
        setTriggeredAnimationColor(false);
      }
    },
    onChange: ({ value }) => {
      if (value.x >= 0.45 && value.x <= 0.5 && !triggeredAnimationColor) {
        core.ui.toggleAstronautColor(!dark);
        setTriggeredAnimationColor(true);
      }
    },
  });

  const onMouseEnter = () => {
    if (!inAnimation) {
      setInAnimation(true);
      setIsRaised(!isRaised);
    }
  };

  return (
    <div className={clsx(styles.Container, className)}>
      <animated.div
        style={{
          transform: (animatedAstronautProps as any).x.to({
            range: [0, 0.5, 1],
            output: [
              `translateY(${0}px)`,
              `translateY(-${30}px)`,
              `translateY(${0}px)`,
            ],
          }),
        }}
        className={styles.ImageContainer}>
        {dark ? (
          <AstronautDark onMouseEnter={onMouseEnter} />
        ) : (
          <AstronautLight onMouseEnter={onMouseEnter} />
        )}
      </animated.div>
      <p className={styles.Text}>Poke me ? to mutate my color State.</p>
    </div>
  );
}
Example #21
Source File: index.tsx    From sybil-interface with GNU General Public License v3.0 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss,
  minHeight = false,
  maxHeight = 90,
  initialFocusRef,
  children,
}: ModalProps): JSX.Element {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
  })

  const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
  const bind = useGesture({
    onDrag: (state) => {
      set({
        y: state.down ? state.movement[1] : 0,
      })
      if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
        onDismiss()
      }
    },
  })

  return (
    <>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: { transform: y.interpolate((y: any) => `translateY(${y > 0 ? y : 0}px)`) },
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </>
  )
}
Example #22
Source File: index.tsx    From cuiswap with GNU General Public License v3.0 5 votes vote down vote up
export default function Modal({
  isOpen,
  onDismiss,
  minHeight = false,
  maxHeight = 50,
  initialFocusRef = null,
  children
}: ModalProps) {
  const fadeTransition = useTransition(isOpen, null, {
    config: { duration: 200 },
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 }
  })

  const [{ y }, set] = useSpring(() => ({ y: 0, config: { mass: 1, tension: 210, friction: 20 } }))
  const bind = useGesture({
    onDrag: state => {
      set({
        y: state.down ? state.movement[1] : 0
      })
      if (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) {
        onDismiss()
      }
    }
  })

  return (
    <>
      {fadeTransition.map(
        ({ item, key, props }) =>
          item && (
            <StyledDialogOverlay key={key} style={props} onDismiss={onDismiss} initialFocusRef={initialFocusRef}>
              <StyledDialogContent
                {...(isMobile
                  ? {
                      ...bind(),
                      style: { transform: y.interpolate(y => `translateY(${y > 0 ? y : 0}px)`) }
                    }
                  : {})}
                aria-label="dialog content"
                minHeight={minHeight}
                maxHeight={maxHeight}
                mobile={isMobile}
              >
                {/* prevents the automatic focusing of inputs on mobile by the reach dialog */}
                {!initialFocusRef && isMobile ? <div tabIndex={1} /> : null}
                {children}
              </StyledDialogContent>
            </StyledDialogOverlay>
          )
      )}
    </>
  )
}
Example #23
Source File: DragableContainer.tsx    From react-planet with MIT License 4 votes vote down vote up
export function DragableContainer(props: Props) {
  const {
    children,
    on,
    dragable,
    dragRadius,
    bounceRadius,
    open,
    bounceOnOpen,
    bounceOnClose,
    bounceDirection,
  } = props;

  if (on) {
    const [{ x, y, cursor }, set] = useSpring(() => ({
      x: 0,
      y: 0,
      config: { tension: 400, friction: 7, precision: 0.1 },
      cursor: "pointer",
    }));

    const classes = useStyles(props);

    React.useEffect(() => {
      if ((open && bounceOnOpen) || (!open && bounceOnClose)) {
        const bRadius = bounceRadius ? bounceRadius : DEFAULT_BOUNCE_RADIUS;
        let x = bRadius;
        let y = bRadius;
        switch (bounceDirection) {
          case "LEFT":
            x = -bRadius;
            y = 0;
            break;
          case "RIGHT":
            x = bRadius;
            y = 0;
            break;
          case "TOP":
            x = 0;
            y = -bRadius;
            break;
          case "BOTTOM":
            x = 0;
            y = bRadius;
            break;
        }
        set({ x, y });
        setTimeout(() => set({ x: 0, y: 0 }), 100);
      }
    }, [open]);

    // Creates a drag gesture
    const bind = useDrag(({ down, movement: [dX, dY] }) => {
      if (dragable) {
        const rMax = dragRadius ? dragRadius : DEFAULT_DRAG_RADIUS;
        const r = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2));
        // Find point along radius with rMax length
        // See: https://math.stackexchange.com/q/1630886
        if (r > rMax) {
          dX *= rMax / r;
          dY *= rMax / r;
        }
        set({
          x: down ? dX : 0,
          y: down ? dY : 0,
          immediate: down,
          cursor: down ? "grabbing" : "pointer",
        });
      }
    });

    return (
      <div className={classes.root}>
        <animated.div
          {...bind()}
          className={classes.dragable}
          style={{ cursor: cursor, left: x, top: y }}
        >
          {children}
        </animated.div>
      </div>
    );
  } else {
    return <>{children}</>;
  }
}
Example #24
Source File: ModalLogin.tsx    From FaztCommunityMatch with MIT License 4 votes vote down vote up
ModalLogin = ({ showModal, setShowModal }) => {
  const [formState, setFormState] = useState<FormStateValues>(formInitialValues)
  const [formErrors, setFormErrors] = useState<FormErrors>(formInitialErrors)
  const isEmpty = (value: string): boolean => {
    return value.trim().length === 0
  }

  const handleOnChange = (
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ): void => {
    console.log(e.target.name)
    const hasError = isEmpty(e.target.value)
    setFormState({ ...formState, [e.target.name]: e.target.value })
    setFormErrors({ ...formErrors, [e.target.name]: hasError })
  }

  const modalRef = useRef()

  const animation = useSpring({
    config: {
      duration: 250
    },
    opacity: showModal ? 1 : 0,
    transform: showModal ? `translateY(0%)` : `translateY(-100%)`
  });

  const closeModal = e => {
    if (modalRef.current === e.target) {
      setShowModal(false)
    }
  };

  const keyPress = useCallback(e => {
    if (e.key === 'Escape' && showModal) {
      setShowModal(false)
    }
  }, [setShowModal, showModal])

  useEffect(() => {
    document.addEventListener('keydown', keyPress);
    return () => document.removeEventListener('keydown', keyPress);
  },
    [keyPress]
  )

  return (
    <>

      {showModal
        ? (
          <section
            className="section-modal-login"
            ref={modalRef}
            onClick={closeModal}
          >
            <animated.div style={animation}>
              <div className="backgron-modal-login">
                <LoginImage />
                <h1 className="title-modal-login">Iniciar Sesión</h1>
                <CloseModalButton
                  aria-label='Close modal'
                  onClick={() => setShowModal(prev => !prev)} />
                <div className="inputs-modal-login">
                  <label htmlFor="" className="label-modal-login"> Correo:
              <EmailInput
                      className="margin-input-email"
                      required
                      placeHolder="*Ingresa tu Correo"
                      handleOnChange={handleOnChange}
                      error={formErrors.email}
                      name="email"
                      value={formState.email}
                    />
                  </label>
                  <label htmlFor="" className="label-modal-login"> Contraseña:
              <InputPass
                      required
                      placeHolder="*Ingresa tu contraseña"
                      handleOnChange={handleOnChange}
                      error={formErrors.password}
                      name="password"
                      value={formState.password}
                    />
                  </label>
                </div>

                <div className="content-btn-next-mondal-login">
                  <a className="btn-medium-next-modal-login" href="">
                    Conectarme
      </a>
                </div>


              </div>
            </animated.div>
          </section>
        )

        : null}

    </>
  )
}
Example #25
Source File: GyroControls.tsx    From spacesvr with MIT License 4 votes vote down vote up
GyroControls = (props: GyroControlsProps) => {
  const { fallback } = props;

  const camera = useThree((state) => state.camera);

  const [controls, setControls] = useState<DeviceOrientationControls>();
  const [enableGyro, setEnableGyro] = useState(false);
  const [alphaVal, setAlphaVal] = useState(0);

  // dragging for y axis offset
  const touchStartPos = useRef<Touch>(DefaultTouch);
  const currentOffset = useRef(0);
  const { alpha } = useSpring({
    alpha: alphaVal,
    config: { ...config.default, precision: 0.001 },
  });

  // try to prompt user for device controls
  useEffect(() => {
    if (!controls) {
      const func = () => {
        const cont = new DeviceOrientationControls(camera);
        cont.enabled = false; // set to disabled in case they're not working yet
        setControls(cont);
      };
      window.addEventListener("click", func);

      return () => {
        window.removeEventListener("click", func);
      };
    }
  }, [controls]);

  useFrame(() => {
    if (controls && !enableGyro) {
      // check if an event has been received yet
      if (Object.keys(controls.deviceOrientation).length !== 0) {
        setEnableGyro(true);
        controls.enabled = true;
      }
    }

    if (controls) {
      controls.alphaOffset = -alpha.get() * ALPHA_SENSITIVITY;
      controls.update();
    }
  });

  // touch move scripts
  const onTouchStart = (ev: TouchEvent) => {
    if (touchStartPos.current.id !== -1) {
      return;
    }

    if (tappedNipple(ev)) {
      touchStartPos.current = DefaultTouch;
      return;
    }

    // get last in list (most recent touch) to not confuse with movement
    const touchIndex = ev.touches.length - 1;
    const { clientX, clientY, identifier: id } = ev.touches[touchIndex];

    touchStartPos.current = { pos: new Vector2(clientX, clientY), id };
  };

  const onTouchMove = (ev: TouchEvent) => {
    const touch = getCurrentTouch(touchStartPos.current.id, ev.touches);

    if (!touch) {
      return;
    }

    const extraOffset = touch.clientX - touchStartPos.current.pos.x;
    setAlphaVal(currentOffset.current + extraOffset);
  };
  const onTouchEnd = (ev: TouchEvent) => {
    const touch = getCurrentTouch(touchStartPos.current.id, ev.changedTouches);

    if (!touch) {
      return;
    }

    const finalOffset = touch.clientX - touchStartPos.current.pos.x;
    setAlphaVal(currentOffset.current + finalOffset);
    currentOffset.current += finalOffset;
    touchStartPos.current.id = -1;
  };

  // register touch events
  useEffect(() => {
    document.addEventListener("touchstart", onTouchStart);
    document.addEventListener("touchmove", onTouchMove);
    document.addEventListener("touchend", onTouchEnd);

    return () => {
      document.removeEventListener("touchstart", onTouchStart);
      document.removeEventListener("touchmove", onTouchMove);
      document.removeEventListener("touchend", onTouchEnd);
    };
  }, []);

  if (!enableGyro) {
    return <>{fallback}</>;
  }

  return null;
}
Example #26
Source File: item-card.tsx    From wikitrivia with MIT License 4 votes vote down vote up
export default function ItemCard(props: Props) {
  const { draggable, flippedId, index, item, setFlippedId } = props;

  const flipped = item.id === flippedId;

  const cardSpring = useSpring({
    opacity: flipped ? 1 : 0,
    transform: `perspective(600px) rotateY(${flipped ? 180 : 0}deg)`,
    config: { mass: 5, tension: 750, friction: 100 },
  });

  const type = React.useMemo(() => {
    const safeDescription = item.description.replace(/ \(.+\)/g, "");

    if (item.description.length < 60 && !/\d\d/.test(safeDescription)) {
      return item.description.replace(/ \(.+\)/g, "");
    }

    if (item.instance_of.includes("human") && item.occupations !== null) {
      return item.occupations[0];
    }

    return item.instance_of[0];
  }, [item]);

  return (
    <Draggable draggableId={item.id} index={index} isDragDisabled={!draggable}>
      {(provided, snapshot) => {
        return (
          <div
            className={classNames(styles.itemCard, {
              [styles.played]: "played" in item,
              [styles.flipped]: flipped,
              [styles.dragging]: snapshot.isDragging,
            })}
            ref={provided.innerRef}
            {...provided.draggableProps}
            {...provided.dragHandleProps}
            onClick={() => {
              if ("played" in item && setFlippedId) {
                if (flipped) {
                  setFlippedId(null);
                } else {
                  setFlippedId(item.id);
                }
              }
            }}
          >
            <animated.div
              className={styles.front}
              style={{
                opacity: cardSpring.opacity.to((o) => 1 - o),
                transform: cardSpring.transform,
              }}
            >
              <div className={styles.top}>
                <div className={styles.label}>{capitalize(item.label)}</div>
                <div className={styles.description}>{capitalize(type)}</div>
              </div>
              <div
                className={styles.image}
                style={{
                  backgroundImage: `url("${createWikimediaImage(item.image)}")`,
                }}
              ></div>
              <animated.div
                className={classNames(styles.bottom, {
                  [styles.correct]: "played" in item && item.played.correct,
                  [styles.incorrect]: "played" in item && !item.played.correct,
                })}
              >
                <span>
                  {"played" in item
                    ? item.year < -10000
                      ? item.year.toLocaleString()
                      : item.year.toString()
                    : datePropIdMap[item.date_prop_id]}
                </span>
              </animated.div>
            </animated.div>
            <animated.div
              className={styles.back}
              style={{
                opacity: cardSpring.opacity,
                transform: cardSpring.transform.to(
                  (t) => `${t} rotateX(180deg) rotateZ(180deg)`
                ),
              }}
            >
              <span className={styles.label}>{capitalize(item.label)}</span>
              <span className={styles.date}>
                {capitalize(datePropIdMap[item.date_prop_id])}: {item.year}
              </span>
              <span className={styles.description}>{item.description}.</span>
              <a
                href={`https://www.wikipedia.org/wiki/${encodeURIComponent(
                  item.wikipedia_title
                )}`}
                className={styles.wikipedia}
                target="_blank"
                rel="noopener noreferrer"
                onClick={(e) => {
                  e.stopPropagation();
                }}
              >
                Wikipedia
              </a>
            </animated.div>
          </div>
        );
      }}
    </Draggable>
  );
}