♻️ refactor: cherry pick fomr main

This commit is contained in:
Andre H 2024-02-28 13:49:11 +07:00
parent 319822c8e6
commit 4519494be8
4 changed files with 56 additions and 0 deletions

View File

@ -0,0 +1,7 @@
import { tv, type VariantProps } from 'tailwind-variants';
export const headingTheme = tv({
base: ['text-elements-high-em', 'font-display', 'font-normal'],
});
export type HeadingVariants = VariantProps<typeof headingTheme>;

View File

@ -0,0 +1,30 @@
import React, { type PropsWithChildren } from 'react';
import { headingTheme, type HeadingVariants } from './Heading.theme';
import { PolymorphicProps } from 'types/common';
export type HeadingElementType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
export type HeadingProps<Element extends HeadingElementType> =
PropsWithChildren<PolymorphicProps<Element, HeadingVariants>>;
export const Heading = <Element extends HeadingElementType>({
children,
as,
className,
...props
}: HeadingProps<Element>) => {
// Component is the element that will be rendered
const Component = as ?? 'h1';
return (
<Component
{...props}
className={headingTheme({
className,
})}
>
{children}
</Component>
);
};

View File

@ -0,0 +1 @@
export * from './Heading';

View File

@ -1,3 +1,9 @@
import {
type ElementType,
type ComponentPropsWithoutRef,
forwardRef,
} from 'react';
/** /**
* Construct a type by excluding common keys from one type to another. * Construct a type by excluding common keys from one type to another.
* @template T - The type from which to omit properties. * @template T - The type from which to omit properties.
@ -7,3 +13,15 @@
* @returns A new type that includes all properties from T except those that are common with U. * @returns A new type that includes all properties from T except those that are common with U.
*/ */
export type OmitCommon<T, U> = Pick<T, Exclude<keyof T, keyof U>>; export type OmitCommon<T, U> = Pick<T, Exclude<keyof T, keyof U>>;
export type PolymorphicProps<Element extends ElementType, Props> = Props &
Omit<ComponentPropsWithoutRef<Element>, 'as'> & {
as?: Element;
};
// taken from : https://github.com/total-typescript/react-typescript-tutorial/blob/main/src/08-advanced-patterns/72-as-prop-with-forward-ref.solution.tsx
type FixedForwardRef = <T, P = object>(
render: (props: P, ref: React.Ref<T>) => React.ReactNode,
) => (props: P & React.RefAttributes<T>) => JSX.Element;
export const fixedForwardRef = forwardRef as FixedForwardRef;