Skip to content

Commit

Permalink
refactor: use polimorphy from utils package
Browse files Browse the repository at this point in the history
  • Loading branch information
abelflopes committed Feb 27, 2024
1 parent cac532a commit fd56534
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 34 deletions.
1 change: 1 addition & 0 deletions packages/components/text/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
},
"dependencies": {
"@react-ck/scss-utils": "^1.1.3",
"@react-ck/react-utils": "^1.1.1",
"@react-ck/theme": "^1.5.1",
"classnames": "^2.3.2"
}
Expand Down
55 changes: 21 additions & 34 deletions packages/components/text/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ import React, { type ReactHTML, useMemo } from "react";
// Utils
import classNames from "classnames";
import { useThemeContext } from "@react-ck/theme";
import {
type ConsumerPolymorphicProps,
type HTMLTag,
PolymorphicComponent,
type BaseHTMLProps,
} from "@react-ck/react-utils";

export type TextVariation = "smallest" | "small" | "bold" | "link" | "link_hidden" | "inverted";

export interface TextProps extends React.HTMLAttributes<HTMLElement> {
export interface TextProps<T extends HTMLTag> extends BaseHTMLProps, ConsumerPolymorphicProps<T> {
/** Adds margin to the text element */
margin?: boolean;
/** Specifies the type/visual variation of text element to be rendered */
type?: "huge" | "soft" | keyof Pick<ReactHTML, "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p">;
/* Specifies the visual style variation(s) for the text */
variation?: TextVariation | TextVariation[];
/** Specifies the custom element to be used as the text container */
as?: keyof ReactHTML | React.ReactElement;
}

/**
Expand All @@ -25,15 +29,15 @@ export interface TextProps extends React.HTMLAttributes<HTMLElement> {
* @returns a React element
*/

export const Text = ({
export const Text = <T extends HTMLTag>({
as,
margin = true,
type = "p",
variation,
className,
children,
...otherProps
}: Readonly<TextProps>): React.ReactElement => {
}: Readonly<TextProps<T>>): React.ReactElement => {
const theme = useThemeContext();

const computedVariations = useMemo(
Expand All @@ -58,9 +62,7 @@ export const Text = ({
[className, computedVariations, theme, margin, type],
);

const tag = useMemo<keyof ReactHTML>(() => {
if (typeof as === "string") return as;

const defaultTag = useMemo<keyof ReactHTML>(() => {
let value: keyof ReactHTML | undefined = undefined;

switch (type) {
Expand All @@ -75,32 +77,17 @@ export const Text = ({
}

return value;
}, [type, as]);

const element = useMemo<React.ReactElement>(
() =>
as && React.isValidElement<HTMLElement>(as)
? React.cloneElement(
as,
{
className: classNames(as.props.className, computedClassNames),
},
<>
{as.props.children}
}, [type]);

{children}
</>,
)
: React.createElement(
tag,
{
...otherProps,
className: computedClassNames,
},
children,
),
[as, computedClassNames, children, tag, otherProps],
return (
<PolymorphicComponent
as={as}
fallback={defaultTag}
commonProps={{
className: computedClassNames,
children,
...otherProps,
}}
/>
);

return element;
};

0 comments on commit fd56534

Please sign in to comment.