Skip to content

Conversation

@mikemajara
Copy link

Add props and style to forward styling and enable the use of custom components as a wrapper.

Example: Use with Chakra-UI

import { Heading } from '@chakra/react'
...
const [primary, secondary] = useToken("colors", ["gray.500", "blue.500"]);
  ...
<Typical
  steps={["Hello", 1000, "Hello world!", 500]}
  loop={Infinity}
  wrapper={Heading}
  props={{
    bgGradient:`linear(to-t, ${primary}, ${secondary})`,
    bgClip:"text"
  }}
  style={{
    fontSize: "5rem"
  }}
/>

example

Closes #18

pump version minor change
Copy link

@archcorsair archcorsair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also update the examples for this?

@leon0399
Copy link

I ended up rewriting it to the following code for TypeScript support:

import React, { useRef, useEffect, memo } from 'react'
import { type } from '@camwiegert/typical'

// const memo: <T>(component: T) => T = baseMemo

export interface Props<
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  T extends React.ComponentType<any> | keyof JSX.IntrinsicElements,
> {
  steps: Parameters<typeof type>[1]
  loop?: number
  className?: string
  wrapper?: T
}

const Typical = <
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  T extends React.ComponentType<any> | keyof JSX.IntrinsicElements,
>({
  steps,
  loop,
  className,
  wrapper = 'p',
  ...props
}: Props<T> & React.ComponentProps<T>) => {
  const typicalRef = useRef<HTMLElement>(null)
  const Component = wrapper

  useEffect(() => {
    if (loop === Infinity) {
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      type(typicalRef.current!, ...steps, type)
    } else if (typeof loop === 'number') {
      const timesStep = Array(loop).fill(steps).flat()
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      type(typicalRef.current!, ...timesStep)
    } else {
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      type(typicalRef.current!, ...steps)
    }

    return () => {
      // alive.current = false
    }
  }, [typicalRef, loop, steps])

  return <Component ref={typicalRef} className={className} {...props} />
}

export default memo(Typical) as typeof Typical

and using it as follows:

      <Typical<'span'>
        steps={['Example', 800, 'Another', 800, 'Third', 800])}
        loop={Infinity}
        wrapper="span"
      />

Not only can you add props to the component without weird props prop, but it also dynamically checks all supported props of the wrapper!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Forward props to wrapper

3 participants