Skip to content

Commit

Permalink
ECNIM-657 (#89)
Browse files Browse the repository at this point in the history
* refactor: removed subcomponent Link.Button

* refactor: removed subcomponent Link.Button

* feat: added polymorphic typing support to component

* docs: added polymorphic typing support to component

* test: added polymorphic typing support to component

* refactor: removed subcomponent Button.Link

* feat: added polymorphic typing support to component Button

* docs: added polymorphic typing support to component Button

* test: added polymorphic typing support to component Button

* feat: added polymorphic typing support to components Button and Link

* chore: adjusted component typing and documentation

* feat: update versions

* feat: update versions

* feat: update versions
  • Loading branch information
juniorconquista authored Feb 13, 2023
1 parent c738a3d commit c74c1ed
Show file tree
Hide file tree
Showing 28 changed files with 375 additions and 339 deletions.
15 changes: 15 additions & 0 deletions .yarn/versions/e1af40d2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
releases:
"@nimbus-ds/box": minor
"@nimbus-ds/button": minor
"@nimbus-ds/components": minor
"@nimbus-ds/link": minor

declined:
- nimbus-design-system
- "@nimbus-ds/popover"
- "@nimbus-ds/accordion"
- "@nimbus-ds/alert"
- "@nimbus-ds/card"
- "@nimbus-ds/modal"
- "@nimbus-ds/pagination"
- "@nimbus-ds/sidebar"
14 changes: 14 additions & 0 deletions packages/react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

This package is intended for internal use in generating builds of each design system package. It contains all the necessary settings and dependencies to optimize the creation of our builds.

## 2023-02-13 `2.7.0`

### 🎉 New features

- Added polymorphic typing support to component `Button`. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))
- Added `as` property to the Component `Button`. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))
- Added polymorphic typing support to component `Lnk`. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))
- Added `as` property to the Component `Lnk`. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))

### 💡 Others

- Removed subcomponent `Link.Button`. [#89](https://github.com/TiendaNube/nimbus-design-system/pull/#89) by [@juniorconquista](https://github.com/juniorconquista))
- Removed subcomponent `Button.Link`. [#89](https://github.com/TiendaNube/nimbus-design-system/pull/#89) by [@juniorconquista](https://github.com/juniorconquista))

## 2023-02-09 `2.3.0`

### 🎉 New features
Expand Down
6 changes: 6 additions & 0 deletions packages/react/src/atomic/Box/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

A low-level utility component that accepts styled system props to enable custom theme-aware styling

## 2023-02-13 `2.6.0`

### 💡 Others

- Adjusted component typing and documentation. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juanchigallego](https://github.com/juanchigallego))

## 2023-02-10 `2.5.0`

### 🎉 New features
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/atomic/Box/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nimbus-ds/box",
"version": "2.5.0",
"version": "2.5.0-rc.2",
"license": "MIT",
"main": "dist/index.js",
"files": [
Expand Down Expand Up @@ -28,5 +28,6 @@
"devDependencies": {
"@vanilla-extract/dynamic": "^2.0.2",
"webpack": "^5.74.0"
}
},
"stableVersion": "2.4.0"
}
102 changes: 77 additions & 25 deletions packages/react/src/atomic/Box/src/box.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import React from "react";
import { ComponentMeta, ComponentStory } from "@storybook/react";
import { withA11y } from "@storybook/addon-a11y";
import { box } from "@nimbus-ds/styles";
import { box as boxStyles } from "@nimbus-ds/styles";

import { Box } from "./Box";
import { Box as BoxComponent } from "./Box";
import { BoxProps } from "./box.types";

export const Base: React.FC<BoxProps> = (props) => <Box {...props} />;
export const Box: React.FC<BoxProps> = (props) => <BoxComponent {...props} />;

export default {
title: "Atomic/Box",
component: Base,
component: Box,
argTypes: {
children: { control: { disable: true } },
as: {
control: { disable: true },
defaultValue: "div",
table: {
type: {
required: false,
summary: '"HTML tags" | "ReactNode of type HTML tag"',
},
defaultValue: { summary: "div" },
},
description:
"The underlying element to render — either a HTML element name or a React component.",
},
Expand All @@ -24,32 +30,78 @@ export default {
description:
"A ref to the element rendered by this component. Because this component is polymorphic, the type will vary based on the value of the as prop.",
},
backgroundColor: { options: Object.keys(box.properties.backgroundColor) },
borderColor: { options: Object.keys(box.properties.borderColor) },
borderStyle: { options: box.properties.borderStyle },
boxSizing: { options: box.properties.boxSizing },
cursor: { options: box.properties.cursor },
position: { options: box.properties.position },
overflow: { options: box.properties.overflow },
overflowX: { options: box.properties.overflowX },
overflowY: { options: box.properties.overflowY },
display: { options: box.properties.display },
flexDirection: { options: box.properties.flexDirection },
flexWrap: { options: box.properties.flexWrap },
justifyContent: { options: box.properties.justifyContent },
alignItems: { options: box.properties.alignItems },
gridGap: { options: Object.keys(box.properties.gridGap) },
gap: { options: Object.keys(box.properties.gap) },
backgroundColor: {
options: Object.keys(boxStyles.properties.backgroundColor),
},
borderColor: {
options: Object.keys(boxStyles.properties.borderColor),
},
borderStyle: {
control: { type: "radio" },
options: boxStyles.properties.borderStyle,
},
boxSizing: {
control: { type: "radio" },
options: boxStyles.properties.boxSizing,
},
cursor: {
control: { type: "radio" },
options: boxStyles.properties.cursor,
},
position: {
control: { type: "radio" },
options: boxStyles.properties.position,
},
overflow: {
control: { type: "radio" },
options: boxStyles.properties.overflow,
},
overflowX: {
control: { type: "radio" },
options: boxStyles.properties.overflowX,
},
overflowY: {
control: { type: "radio" },
options: boxStyles.properties.overflowY,
},
display: {
control: { type: "radio" },
options: boxStyles.properties.display,
},
flexDirection: {
control: { type: "radio" },
options: boxStyles.properties.flexDirection,
},
flexWrap: {
control: { type: "radio" },
options: boxStyles.properties.flexWrap,
},
justifyContent: {
control: { type: "radio" },
options: boxStyles.properties.justifyContent,
},
alignItems: {
control: { type: "radio" },
options: boxStyles.properties.alignItems,
},
gridGap: {
options: Object.keys(boxStyles.properties.gridGap),
},
gap: {
options: Object.keys(boxStyles.properties.gap),
},
},
parameters: {
withA11y: { decorators: [withA11y] },
},
} as ComponentMeta<typeof Base>;
} as ComponentMeta<typeof BoxComponent>;

const Template: ComponentStory<typeof Base> = (args) => <Box {...args} />;
const Template: ComponentStory<typeof BoxComponent> = (args) => (
<Box {...args} />
);

export const base = Template.bind({});
base.args = {
export const box = Template.bind({});
box.args = {
height: "5rem",
width: "12rem",
borderColor: "neutral.interactive",
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/atomic/Box/src/box.types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ReactNode, CSSProperties } from "react";
import { ReactNode, HTMLAttributes } from "react";
import { BoxSprinkle } from "@nimbus-ds/styles";

export interface BoxProps extends BoxSprinkle {
className?: string;
style?: CSSProperties;
type BoxExtends = BoxSprinkle & HTMLAttributes<HTMLElement>;

export interface BoxProps extends BoxExtends {
/** Element to be rendered inside the Box component */
children?: ReactNode;
}
11 changes: 11 additions & 0 deletions packages/react/src/atomic/Button/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

The Button component allows us to initiate actions, make state or page changes.

## 2023-02-13 `2.2.0`

### 🎉 New features

- Added polymorphic typing support to component. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))
- Added `as` property to the Component. ([#89](https://github.com/TiendaNube/nimbus-design-system/pull/89) by [@juniorconquista](https://github.com/juniorconquista))

### 💡 Others

- Removed subcomponent `Button.Link`. [#89](https://github.com/TiendaNube/nimbus-design-system/pull/#89) by [@juniorconquista](https://github.com/juniorconquista))

## 2023-02-06 `2.1.0`

### 🎉 New features
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/atomic/Button/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nimbus-ds/button",
"version": "2.1.0",
"version": "2.2.0-rc.1",
"license": "MIT",
"main": "dist/index.js",
"files": [
Expand Down Expand Up @@ -35,5 +35,6 @@
"@nimbus-ds/skeleton": "workspace:^",
"@tiendanube/icons": "^0.3.1",
"webpack": "^5.74.0"
}
},
"stableVersion": "2.1.0"
}
70 changes: 52 additions & 18 deletions packages/react/src/atomic/Button/src/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,61 @@
import React from "react";
import React, {
forwardRef,
createRef,
useEffect,
useImperativeHandle,
} from "react";
import { PolymorphicForwardRefComponent } from "@nimbus-ds/typings";
import { button } from "@nimbus-ds/styles";

import { ButtonProps, ButtonComponents } from "./button.types";
import { ButtonSkeleton, ButtonLink } from "./components";
import { ButtonSkeleton } from "./components";

const Button: React.FC<ButtonProps> & ButtonComponents = ({
className: _className,
style: _style,
appearance = "neutral",
children,
...rest
}: ButtonProps) => (
<button
type="button"
{...rest}
className={button.classnames.appearance[appearance]}
>
{children}
</button>
);
const Button = forwardRef(
(
{
className: _className,
style: _style,
as: As = "button",
appearance = "neutral",
children,
...rest
}: ButtonProps & { as: any },
ref
) => {
const innerRef = createRef<HTMLButtonElement>();
useImperativeHandle<
HTMLButtonElement | HTMLAnchorElement | null,
HTMLButtonElement | null
>(ref, () => innerRef?.current);

useEffect(() => {
if (
innerRef.current &&
!(innerRef.current instanceof HTMLAnchorElement) &&
!(innerRef.current instanceof HTMLButtonElement)
) {
console.error(
"Error: Found `Button` component that renders an inaccessible element",
innerRef.current,
"Please ensure `Button` always renders as <a> or <button>"
);
}
}, [innerRef]);

return (
<As
{...rest}
className={button.classnames.appearance[appearance]}
ref={innerRef}
>
{children}
</As>
);
}
) as PolymorphicForwardRefComponent<"button" | "a", ButtonProps> &
ButtonComponents;

Button.Skeleton = ButtonSkeleton;
Button.Link = ButtonLink;
Button.displayName = "Button";
Button.Skeleton.displayName = "Button.Skeleton";

Expand Down
17 changes: 12 additions & 5 deletions packages/react/src/atomic/Button/src/button.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { render, screen } from "@testing-library/react";
import { Button } from "./Button";
import { ButtonProps } from "./button.types";

const makeSut = (rest: ButtonProps) => {
const makeSut = (
rest: ButtonProps & { as?: "button" | "a"; href?: string }
) => {
render(<Button {...rest} data-testid="button-element" />);
};

Expand All @@ -16,6 +18,11 @@ describe("GIVEN <Button />", () => {
screen.getByRole<HTMLButtonElement>("button").disabled
).toBeTruthy();
});

it("THEN should correctly render the button element", () => {
makeSut({ children: "Link", as: "a", href: "/" });
expect(screen.getByRole("link")).toBeDefined();
});
});

describe("THEN should correctly render the submitted appearance", () => {
Expand All @@ -26,28 +33,28 @@ describe("GIVEN <Button />", () => {
);
});

it("THEN should correctly render the appearance primary", () => {
it("AND should correctly render the appearance primary", () => {
makeSut({ appearance: "primary", children: "button" });
expect(
screen.getByRole("button", { name: "button" }).getAttribute("class")
).toContain("appearance_primary");
});

it("THEN should correctly render the appearance danger", () => {
it("AND should correctly render the appearance danger", () => {
makeSut({ appearance: "danger", children: "button" });
expect(
screen.getByRole("button", { name: "button" }).getAttribute("class")
).toContain("appearance_danger");
});

it("THEN should correctly render the appearance neutral", () => {
it("AND should correctly render the appearance neutral", () => {
makeSut({ appearance: "neutral", children: "button" });
expect(
screen.getByRole("button", { name: "button" }).getAttribute("class")
).toContain("appearance_neutral");
});

it("THEN should correctly render the appearance transparent", () => {
it("AND should correctly render the appearance transparent", () => {
makeSut({ appearance: "transparent", children: "button" });
expect(
screen.getByRole("button", { name: "button" }).getAttribute("class")
Expand Down
Loading

0 comments on commit c74c1ed

Please sign in to comment.