Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Tile to Tailwind #4101

Merged
merged 6 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions packages/orbit-components/src/Tile/Tile.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const DefaultJustWrapper = () => {
const as = text("as", "");

return (
<Tile as={as} onClick={action("clicked")} noPadding={noPadding}>
<Tile as={as === "" ? undefined : "div"} onClick={action("clicked")} noPadding={noPadding}>
{content}
</Tile>
);
Expand Down Expand Up @@ -185,7 +185,7 @@ export const Playground = () => {
return (
<Tile
href={href}
as={as}
as={as === "" ? undefined : "div"}
onClick={action("clicked")}
icon={Icon && <Icon />}
expanded={expanded}
Expand Down Expand Up @@ -234,3 +234,36 @@ Rtl.story = {
info: "This is a preview of this component in RTL setup.",
},
};

export const VisualTest = () => {
return (
<div className="space-y-xs">
<Tile>Tile child</Tile>
<Tile noPadding>Tile child</Tile>
<Tile title="Tile" />
<Tile title="Tile" icon={<Icons.Airplane />} />
<Tile title="Tile" description="Tile description" />
<Tile title="Tile">Tile child</Tile>
<Tile header="Tile header" />
<Tile header="Tile header" noHeaderIcon />
<Tile expandable title="Tile">
Tile expandable
</Tile>
<Tile expandable expanded title="Tile">
Tile expanded
</Tile>
<Tile dataTest="tile-hover">Tile hover</Tile>
</div>
);
};

VisualTest.story = {
parameters: {
chromatic: {
disableSnapshot: false,
},
pseudo: {
hover: ["[data-test='tile-hover']"],
},
},
};
4 changes: 0 additions & 4 deletions packages/orbit-components/src/Tile/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import userEvent from "@testing-library/user-event";

import { render, screen, fireEvent } from "../../test-utils";
import KEY_CODE_MAP from "../../common/keyMaps";
import theme from "../../defaultTheme";
import Tile from "..";
import Airplane from "../../icons/Airplane";

Expand Down Expand Up @@ -34,9 +33,6 @@ describe("Tile", () => {
expect(screen.getByText(description)).toBeInTheDocument();
expect(screen.getByRole("button")).toHaveAttribute("tabindex", "0");
expect(screen.getByText("kek")).toHaveStyle({ padding: "16px" });
expect(screen.getByText("kek")).toHaveStyle({
borderTop: `1px solid ${theme.orbit.paletteCloudNormal}`,
});

await user.click(screen.getByRole("button"));
fireEvent.keyDown(screen.getByRole("button"), { keyCode: KEY_CODE_MAP.ENTER });
Expand Down
72 changes: 10 additions & 62 deletions packages/orbit-components/src/Tile/components/TileContent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import * as React from "react";
import styled, { css } from "styled-components";

import mq from "../../../utils/mediaQuery";
import defaultTheme from "../../../defaultTheme";
import cx from "clsx";

interface Props {
noPadding: boolean;
Expand All @@ -11,70 +8,21 @@ interface Props {
useMargins?: boolean;
}

const getPadding = ({
noPadding,
useMargins,
theme,
}: {
noPadding?: Props["noPadding"];
useMargins?: Props["useMargins"];
theme: typeof defaultTheme;
}) => {
if (noPadding) return null;

if (!useMargins) {
return css`
padding: ${theme.orbit.spaceMedium};

${mq.largeMobile(css`
padding: ${theme.orbit.spaceLarge};
`)}
`;
}

return css`
padding: ${theme.orbit.spaceMedium} 0;
margin: 0 ${theme.orbit.spaceMedium};

${mq.largeMobile(css`
padding: ${theme.orbit.spaceLarge} 0;
margin: 0 ${theme.orbit.spaceLarge};
`)}
`;
};

const StyledTileContent = styled.div<Props>`
${({ theme, withBorder, withPointer }) => css`
font-size: ${theme.orbit.fontSizeTextNormal};
line-height: ${theme.orbit.lineHeightTextNormal};
${withPointer &&
css`
cursor: pointer;
`};
${withBorder &&
css`
border-top: 1px solid ${theme.orbit.paletteCloudNormal};
`};
${getPadding};
`}
`;

StyledTileContent.defaultProps = {
theme: defaultTheme,
};

const TileContent = React.forwardRef<HTMLDivElement, React.PropsWithChildren<Props>>(
({ children, noPadding, withPointer, withBorder, useMargins = true }, ref) => {
return (
<StyledTileContent
noPadding={noPadding}
<div
ref={ref}
withPointer={withPointer}
withBorder={withBorder}
useMargins={useMargins}
className={cx(
"text-normal leading-normal",
withPointer === true && "cursor-pointer",
withBorder === true && "border-cloud-normal border-t",
!noPadding && !useMargins && "p-md lm:p-lg",
!noPadding && useMargins && "py-md mx-md lm:py-lg lm:mx-lg",
DSil marked this conversation as resolved.
Show resolved Hide resolved
)}
>
{children}
</StyledTileContent>
</div>
);
},
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @flow
import * as React from "react";
import type { StyledComponent } from "styled-components";

import type { TileOnClick } from "../../index.js.flow";

Expand All @@ -22,12 +21,4 @@ export type Props = {|
noHeaderIcon?: boolean,
|};

type IconProps = {|
external: boolean,
expandable: boolean,
expanded: boolean,
|};

declare export var StyledIconRight: StyledComponent<IconProps, any, HTMLElement>;

declare export default React.ComponentType<Props>;
129 changes: 29 additions & 100 deletions packages/orbit-components/src/Tile/components/TileHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import * as React from "react";
import styled, { css } from "styled-components";
import cx from "clsx";

import type * as Common from "../../../common/types";
import defaultTheme from "../../../defaultTheme";
import { rtlSpacing } from "../../../utils/rtl";
import Stack from "../../../Stack";
import Heading from "../../../Heading";
import ChevronDown from "../../../icons/ChevronDown";
import NewWindow from "../../../icons/NewWindow";
import ChevronForward from "../../../icons/ChevronForward";
import transition from "../../../utils/transition";
import mq from "../../../utils/mediaQuery";

interface Props {
icon?: React.ReactNode;
Expand All @@ -32,71 +28,6 @@ interface Props {
noHeaderIcon?: boolean;
}

const StyledTileHeader = styled.div`
${({ theme }) => css`
display: block;
width: 100%;
box-sizing: border-box;
cursor: pointer;
padding: ${theme.orbit.spaceMedium};
font-size: ${theme.orbit.fontSizeTextNormal};
line-height: ${theme.orbit.lineHeightTextNormal};
transition: ${transition(["background-color"], "fast", "ease-in-out")};

${mq.largeMobile(css`
padding: ${theme.orbit.spaceLarge};
`)}
`}
`;

StyledTileHeader.defaultProps = {
theme: defaultTheme,
};

const StyledTileIcon = styled.div`
${({ theme }) => css`
color: ${theme.orbit.colorIconPrimary};
flex-shrink: 0;
align-items: center;
align-self: flex-start;
margin: ${rtlSpacing(`0 ${theme.orbit.spaceXSmall} 0 0`)};
`}
`;

StyledTileIcon.defaultProps = {
theme: defaultTheme,
};

const StyledTileTitle = styled.div`
display: flex;
align-items: center;
width: 100%;
`;

StyledTileTitle.defaultProps = {
theme: defaultTheme,
};

const StyledTileDescription = styled.div<{ hasTitle?: boolean }>`
${({ theme, hasTitle }) => css`
font-family: ${theme.orbit.fontFamily};
font-size: ${theme.orbit.fontSizeTextNormal};
color: ${theme.orbit.colorTextPrimary};
line-height: ${theme.orbit.lineHeightTextNormal};
font-weight: ${theme.orbit.fontWeightNormal};
-webkit-text-size-adjust: 100%;
width: 100%;
${hasTitle &&
css`
margin-top: ${theme.orbit.spaceXXSmall};
`};
`}
`;

StyledTileDescription.defaultProps = {
theme: defaultTheme,
};

const IconRight = ({
external,
expandable,
Expand All @@ -114,29 +45,6 @@ const IconRight = ({
return <ChevronForward color="secondary" className={className} reverseOnRtl />;
};

export const StyledIconRight = styled(IconRight)`
${({
theme,
expanded,
}: {
theme: typeof defaultTheme;
expanded?: Props["expanded"];
expandable?: Props["expandable"];
}) => css`
color: ${theme.orbit.colorIconSecondary};
margin: ${rtlSpacing(`0 0 0 ${theme.orbit.spaceSmall}`)};
transition: ${transition(["color", "transform"], "fast", "ease-in-out")};
${expanded &&
css`
transform: rotate(-180deg);
`};
`}
`;

StyledIconRight.defaultProps = {
theme: defaultTheme,
};

const TileHeader = ({
icon,
title,
Expand All @@ -154,7 +62,9 @@ const TileHeader = ({
onKeyDown,
noHeaderIcon,
}: React.PropsWithChildren<Props>) => (
<StyledTileHeader
// eslint-disable-next-line jsx-a11y/no-static-element-interactions -- has been like this before
<div
className="p-md text-normal duration-fast lm:p-lg w-full cursor-pointer leading-normal transition-colors ease-in-out"
onClick={onClick}
onKeyDown={onKeyDown}
role={role}
Expand All @@ -164,27 +74,46 @@ const TileHeader = ({
tabIndex={tabIndex ? Number(tabIndex) : undefined}
>
<Stack align="center" justify="between" shrink spacing="none">
{icon && <StyledTileIcon>{icon}</StyledTileIcon>}
{icon && (
<div className="text-icon-primary-foreground me-xs shrink-0 items-center self-start">
{icon}
</div>
)}
{header ||
((title || description) && (
<Stack spacing="none" direction="column" shrink>
{title && (
<StyledTileTitle>
<div className="flex w-full items-center">
<Heading type="title4" as="h3">
{title}
</Heading>
</StyledTileTitle>
</div>
)}
{description && (
<StyledTileDescription hasTitle={!!title}>{description}</StyledTileDescription>
<div
className={cx(
"font-base text-normal text-primary-foreground w-full font-normal leading-normal",
title != null && "mt-xxs",
)}
>
{description}
</div>
)}
</Stack>
))}
{!noHeaderIcon && (
<StyledIconRight external={external} expandable={expandable} expanded={expanded} />
<IconRight
className={cx(
"orbit-tile-header-icon-right text-icon-secondary-foreground ms-sm duration-fast transition-all ease-in-out",
expanded === true && "-rotate-180",
)}
external={external}
expandable={expandable}
expanded={expanded}
/>
)}
</Stack>
</StyledTileHeader>
</div>
);

export default TileHeader;
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// @flow
import * as React from "react";
import type { StyledComponent } from "styled-components";

import type { Globals } from "../../../common/common.js.flow";

Expand All @@ -21,5 +20,3 @@ export type Props = {|
|};

declare export default React.ComponentType<Props>;

declare export var StyledTileWrapper: StyledComponent<Props, any, HTMLElement>;
Loading
Loading