Skip to content

Commit

Permalink
feat: text component (#34)
Browse files Browse the repository at this point in the history
* fix: add required as tag to heading test

* fix: pass classname through to heading

* fix: format heading test

* feat: text component

* docs(changeset): add changeset

* fix: correct type for html attributes
  • Loading branch information
kylemcd authored Feb 7, 2024
1 parent ba4e477 commit befcb4f
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/funny-papayas-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@telegraph/typography": patch
---

Adds text component, fixes className persistence issue
22 changes: 17 additions & 5 deletions packages/typography/src/Heading/Heading.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,35 @@ import { Heading } from "./Heading";

describe("Heading", () => {
it("should render without a11y issues", async () => {
const { container } = render(<Heading>Heading</Heading>);
const { container } = render(<Heading as="h1">Heading</Heading>);
expect(await axe(container)).toHaveNoViolations();
});
it("size props applies correct className", () => {
const { container } = render(<Heading size="9">Heading</Heading>);
const { container } = render(
<Heading size="9" as="h1">
Heading
</Heading>,
);
expect(container.firstChild).toHaveClass("text-9");
});
it("color props applies correct className", () => {
const { container } = render(<Heading color="red">Heading</Heading>);
const { container } = render(
<Heading color="red" as="h1">
Heading
</Heading>,
);
expect(container.firstChild).toHaveClass("text-red-11");
});
it("align props applies correct className", () => {
const { container } = render(<Heading align="left">Heading</Heading>);
const { container } = render(
<Heading align="left" as="h1">
Heading
</Heading>,
);
expect(container.firstChild).toHaveClass("text-left");
});
it("default props applies correct className", () => {
const { container } = render(<Heading>Heading</Heading>);
const { container } = render(<Heading as="h1">Heading</Heading>);
expect(container.firstChild).toHaveClass("text-gray-12");
expect(container.firstChild).toHaveClass("text-2");
expect(container.firstChild).toHaveClass("leading-2");
Expand Down
6 changes: 5 additions & 1 deletion packages/typography/src/Heading/Heading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ type HeadingProps = React.HTMLAttributes<HTMLHeadingElement> & {
type HeadingRef = HTMLHeadingElement;

const Heading = React.forwardRef<HeadingRef, HeadingProps>(
({ color = "black", size = "2", align, ...props }, forwardedRef) => {
(
{ color = "black", size = "2", align, className, ...props },
forwardedRef,
) => {
return (
<h3
className={clsx(
align && alignMap[align],
color && colorMap[color],
size && sizeMap[size],
"font-semi-bold",
className,
)}
ref={forwardedRef}
{...props}
Expand Down
53 changes: 53 additions & 0 deletions packages/typography/src/Text/Text.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { render } from "@testing-library/react";
import React from "react";
import { describe, expect, it } from "vitest";
import { axe } from "vitest-axe";

import { Text } from "./Text";

describe("Text", () => {
it("should render without a11y issues", async () => {
const { container } = render(<Text as="p">Text</Text>);
expect(await axe(container)).toHaveNoViolations();
});
it("size props applies correct className", () => {
const { container } = render(
<Text size="9" as="p">
Text
</Text>,
);
expect(container.firstChild).toHaveClass("text-9");
});
it("color props applies correct className", () => {
const { container } = render(
<Text color="red" as="p">
Text
</Text>,
);
expect(container.firstChild).toHaveClass("text-red-11");
});
it("align props applies correct className", () => {
const { container } = render(
<Text align="left" as="p">
Text
</Text>,
);
expect(container.firstChild).toHaveClass("text-left");
});
it("weight props applies correct className", () => {
const { container } = render(
<Text weight="medium" as="p">
Text
</Text>,
);
expect(container.firstChild).toHaveClass("font-medium");
});
it("default props applies correct className", () => {
const { container } = render(<Text as="p">Text</Text>);
expect(container.firstChild).toHaveClass("text-gray-12");
expect(container.firstChild).toHaveClass("text-2");
expect(container.firstChild).toHaveClass("leading-2");
expect(container.firstChild).toHaveClass("tracking-2");
expect(container.firstChild).toHaveClass("font-regular");
});
});
60 changes: 57 additions & 3 deletions packages/typography/src/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
function Text() {
return <p className="text-amber-400">Text</p>;
}
import clsx from "clsx";
import React from "react";

import {
alignMap,
colorMap,
sizeMap,
weightMap,
} from "../helpers/prop-mappings";

type TextProps = React.HTMLAttributes<HTMLElement> & {
as:
| "p"
| "span"
| "div"
| "label"
| "em"
| "strong"
| "b"
| "i"
| "pre"
| "code";
align?: keyof typeof alignMap;
size?: keyof typeof sizeMap;
color?: keyof typeof colorMap;
weight?: keyof typeof weightMap;
};

type TextRef = HTMLElement;

const Text = React.forwardRef<TextRef, TextProps>(
(
{
color = "black",
size = "2",
weight = "regular",
align,
className,
...props
},
forwardedRef,
) => {
return (
<span
className={clsx(
align && alignMap[align],
color && colorMap[color],
size && sizeMap[size],
weight && weightMap[weight],
className,
)}
ref={forwardedRef}
{...props}
/>
);
},
);

export { Text };

0 comments on commit befcb4f

Please sign in to comment.