Skip to content

Commit

Permalink
Complete component version # 2
Browse files Browse the repository at this point in the history
  • Loading branch information
renato1010 committed Sep 22, 2022
1 parent 2ad07f5 commit 695156a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
38 changes: 36 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,45 @@ and of course, it will flag the error with any attribute that does not match tha

</details>

<details open >
<summary>Version 2: Component should own props</summary>
<details >
<summary>Version 2: Component must handle own props</summary>

**New Requirements:**

- The component must be able to handle its own props, such as color, in a type-safe way, of course.!

Let say our component will accept **color** prop. Color will be a pre-made list of colors
let say "primary" and "accent"

_small refactoring_
<br />
<img src="https://losormorpino-public-media.s3.us-east-2.amazonaws.com/8s00ea7.png" />
<br />

An additional precaution: it is possible that some values that exist in **ComponentPropsWithoutRef<C>** also exist
in the definition of the props type of our component.
Instead of relying on our **color** prop to override what's coming from ComponentPropsWithoutRef<C>, we better remove
any type that also exit in our component types definition.

So, guess what... another refactoring

```tsx
type PolyColor = "primary" | "accent";
type PolyButtonOwnProps<C extends ElementType> = { as?: C; color: PolyColor };
type PolyButtonV2Props<C extends ElementType> = PolyButtonOwnProps<C> &
Omit<ComponentPropsWithoutRef<C>, keyof PolyButtonOwnProps<C>>;

const PolyButtonV2 = <C extends ElementType = "button">({
as,
children,
style,
color,
...restProps
}: PropsWithChildren<PolyButtonV2Props<C>>) => {
```
</details>
<details>
<summary>Version 3: Make component reusable, work with any component</summary>
</details>
7 changes: 2 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { PolyButtonV1 } from "@components/index";
import { PolyButtonV2 } from "@components/index";
import "./App.css";

function App() {
return (
<div className="App">
<PolyButtonV1 as="a" href="https://www.google.com" style={{ display: "block" }}>
anchor element
</PolyButtonV1>
<PolyButtonV1 >default element</PolyButtonV1>
<PolyButtonV2 color="primary" >default element</PolyButtonV2>
</div>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./polymorphicv0";
export * from "./polymorphicv1";
export * from "./polymorphicv2";
24 changes: 24 additions & 0 deletions src/components/polymorphicv2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ElementType, PropsWithChildren, ComponentPropsWithoutRef } from "react";

type PolyColor = "primary" | "accent";
type PolyButtonOwnProps<C extends ElementType> = { as?: C; color: PolyColor };
type PolyButtonV2Props<C extends ElementType> = PolyButtonOwnProps<C> &
Omit<ComponentPropsWithoutRef<C>, keyof PolyButtonOwnProps<C>>;

const PolyButtonV2 = <C extends ElementType = "button">({
as,
children,
style,
color,
...restProps
}: PropsWithChildren<PolyButtonV2Props<C>>) => {
const PolyButton = as ?? "button";
const outStyle = { ...style, color: color === "primary" ? "#058ed9" : "#df6066" };
return (
<PolyButton style={outStyle} {...restProps}>
{children}
</PolyButton>
);
};

export { PolyButtonV2 };

0 comments on commit 695156a

Please sign in to comment.