Skip to content

Commit

Permalink
feat(Inline): migrate to tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
vbulant authored and mvidalgarcia committed Mar 11, 2024
1 parent e89fe8c commit 22464a6
Show file tree
Hide file tree
Showing 32 changed files with 234 additions and 120 deletions.
2 changes: 1 addition & 1 deletion docs/src/data/tailwind-migration-status.yaml
Expand Up @@ -41,7 +41,7 @@ InputField: true
InputFile: true
InputGroup: true
InputSelect: true
Inline: false
Inline: true
Itinerary: true
ItineraryBadgeList: true
ItinerarySegment: true
Expand Down
79 changes: 79 additions & 0 deletions packages/orbit-components/src/Inline/Inline.ct-story.tsx
@@ -0,0 +1,79 @@
import * as React from "react";

import { SPACINGS } from "../utils/layout/consts";
import { QUERIES } from "../utils/mediaQuery/consts";
import type { MediaQuery } from "./types";

import Inline from ".";

const ALIGN = [undefined, "start", "end", "center"] as const;
const JUSTIFY = [undefined, "start", "end", "center", "between", "around"] as const;

enum QUERIES_BACKGROUNDS {
mediumMobile = "bg-blue-light",
largeMobile = "bg-product-light",
tablet = "bg-green-light",
desktop = "bg-orange-light",
largeDesktop = "bg-red-light",
}

const DUMMY_CHILDREN = (
<>
<div className="size-xxxs bg-blue-normal" />
<div className="size-xxs bg-blue-normal" />
<div className="size-xs bg-blue-normal" />
<div className="size-sm bg-blue-normal" />
<div className="size-md bg-blue-normal" />
<div className="size-lg bg-blue-normal" />
<div className="size-xl bg-blue-normal" />
<div className="size-xxl bg-blue-normal" />
<div className="size-xxxl bg-blue-normal" />
</>
);

export default function InlineStory() {
return (
<>
<Inline />
{Object.values(SPACINGS).map(spacing => (
<Inline key={spacing} spacing={spacing}>
{DUMMY_CHILDREN}
</Inline>
))}
{ALIGN.map(align => (
<Inline key={align} align={align}>
{DUMMY_CHILDREN}
</Inline>
))}
{JUSTIFY.map(justify => (
<Inline key={justify} justify={justify}>
{DUMMY_CHILDREN}
</Inline>
))}
{Object.values(QUERIES).map(query => {
const propByQuery = (prop: MediaQuery) => ({
[query]: prop,
});
return (
<div className={QUERIES_BACKGROUNDS[query]}>
{Object.values(SPACINGS).map(spacing => (
<Inline key={spacing} {...propByQuery({ spacing })}>
{DUMMY_CHILDREN}
</Inline>
))}
{ALIGN.map(align => (
<Inline key={align} {...propByQuery({ align })}>
{DUMMY_CHILDREN}
</Inline>
))}
{JUSTIFY.map(justify => (
<Inline key={justify} {...propByQuery({ justify })}>
{DUMMY_CHILDREN}
</Inline>
))}
</div>
);
})}
</>
);
}
23 changes: 23 additions & 0 deletions packages/orbit-components/src/Inline/Inline.ct.tsx
@@ -0,0 +1,23 @@
import * as React from "react";
import { test, expect } from "@playwright/experimental-ct-react";

import InlineStory from "./Inline.ct-story";
import RenderInRtl from "../utils/rtl/RenderInRtl";

test.describe("visual Inline", () => {
test("default", async ({ mount }) => {
const component = await mount(<InlineStory />);

await expect(component).toHaveScreenshot();
});

test("rtl", async ({ mount }) => {
const component = await mount(
<RenderInRtl>
<InlineStory />
</RenderInRtl>,
);

await expect(component).toHaveScreenshot();
});
});
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion packages/orbit-components/src/Inline/README.md
Expand Up @@ -19,7 +19,8 @@ Table below contains all types of the props available in the Inline component.
| Name | Type | Default | Description |
| :----------- | :------------------------------- | :------ | :-------------------------------------------------------------- |
| as | `string` | `"div"` | Render as element. |
| className | `string` | `"div"` | Optional className of component. |
| id | `string` | | Optional id of component. |
| className | `string` | | Optional className of component. |
| children | `React.Node` | | The children of the Inline. |
| dataTest | `string` | | Optional prop for testing purposes. |
| spacing | [`spacingToken`](#spacingToken) | | The spacing between children elements of the Inline |
Expand Down
52 changes: 10 additions & 42 deletions packages/orbit-components/src/Inline/__tests__/index.test.tsx
@@ -1,58 +1,26 @@
import * as React from "react";

import { screen, render } from "../../test-utils";
import theme from "../../defaultTheme";
import type { SpacingToken } from "../types";
import Inline from "..";

const tokens = {
none: "",
XXXSmall: theme.orbit.spaceXXXSmall,
XXSmall: theme.orbit.spaceXXSmall,
XSmall: theme.orbit.spaceXSmall,
small: theme.orbit.spaceSmall,
medium: theme.orbit.spaceMedium,
large: theme.orbit.spaceLarge,
XLarge: theme.orbit.spaceXLarge,
XXLarge: theme.orbit.spaceXXLarge,
XXXLarge: theme.orbit.spaceXXXLarge,
};

const Elements = () => (
<>
<div data-test="child-0">kek</div>
<div>bur</div>
<div>cheburek</div>
<div>blin</div>
</>
);

describe("#Inline", () => {
it("should have props", () => {
it("should have expected DOM output", () => {
const dataTest = "test";

render(
<Inline align="center" justify="start" dataTest={dataTest}>
<Elements />
<Inline align="center" justify="start" dataTest={dataTest} id="ID" className="CLASS">
<div>kek</div>
<div>bur</div>
<div>cheburek</div>
<div>blin</div>
</Inline>,
);
expect(screen.getByTestId(dataTest)).toBeInTheDocument();
const el = screen.getByTestId(dataTest);
expect(el).toBeInTheDocument();
expect(el).toHaveAttribute("id", "ID");
expect(el).toHaveAttribute("class", "orbit-inline CLASS");
const inner = screen.getByTestId(dataTest).firstChild;
expect(inner).toHaveStyle({ alignItems: "center" });
expect(inner).toHaveStyle({ justifyContent: "flex-start" });
});

it.each(Object.entries(tokens))(
'should have expected spacing for token "%s"',
(token, spacing) => {
render(
<Inline align="start" justify="center" spacing={token as SpacingToken}>
<div data-test={token}>kek</div>
<div>bur</div>
</Inline>,
);

expect(screen.getByTestId(token)).toHaveStyle({ marginLeft: spacing });
},
);
});
131 changes: 92 additions & 39 deletions packages/orbit-components/src/Inline/helpers.ts
@@ -1,44 +1,97 @@
import { left } from "../utils/rtl";
import type { Theme, ThemeProps } from "../defaultTheme";
import { getAlign, getJustify, formatCSS } from "../utils/layout";
import { TOKENS } from "../utils/layout/consts";
import type { SpacingToken, Align, Justify } from "./types";
import { SPACINGS } from "../utils/layout/consts";
import type { MediaQuery } from "./types";
import { getJustifyClasses, getAlignItemsClasses } from "../common/tailwind";
import { QUERIES } from "../utils/mediaQuery/consts";

type Prop = "align" | "justify" | "spacing";

export const normalizeSpacing = (el: SpacingToken, theme: Theme): string => {
const tokens = TOKENS(theme);

if (el !== "none") {
return `
margin-${left({ theme })}: -${tokens[el]};
margin-top: -${tokens[el]};
& > * {
margin-${left({ theme })}: ${tokens[el]};
margin-top: ${tokens[el]};
}
`;
}

return "";
// TODO refactor to gap once we no longer support iOS Safari < 14.5
const spacingClasses: {
[K in QUERIES | SPACINGS]: K extends QUERIES ? Record<SPACINGS, string> : string;
} = {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "-mt-xxxs -ms-xxxs [&>*]:mt-xxxs [&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "-mt-xxs -ms-xxs [&>*]:mt-xxs [&>*]:ms-xxs",
[SPACINGS.XSMALL]: "-mt-xs -ms-xs [&>*]:mt-xs [&>*]:ms-xs",
[SPACINGS.SMALL]: "-mt-sm -ms-sm [&>*]:mt-sm [&>*]:ms-sm",
[SPACINGS.MEDIUM]: "-mt-md -ms-md [&>*]:mt-md [&>*]:ms-md",
[SPACINGS.LARGE]: "-mt-lg -ms-lg [&>*]:mt-lg [&>*]:ms-lg",
[SPACINGS.XLARGE]: "-mt-xl -ms-xl [&>*]:mt-xl [&>*]:ms-xl",
[SPACINGS.XXLARGE]: "-mt-xxl -ms-xxl [&>*]:mt-xxl [&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "-mt-xxxl -ms-xxxl [&>*]:mt-xxxl [&>*]:ms-xxxl",
[QUERIES.LARGEDESKTOP]: {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "ld:-mt-xxxs ld:-ms-xxxs ld:[&>*]:mt-xxxs ld:[&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "ld:-mt-xxs ld:-ms-xxs ld:[&>*]:mt-xxs ld:[&>*]:ms-xxs",
[SPACINGS.XSMALL]: "ld:-mt-xs ld:-ms-xs ld:[&>*]:mt-xs ld:[&>*]:ms-xs",
[SPACINGS.SMALL]: "ld:-mt-sm ld:-ms-sm ld:[&>*]:mt-sm ld:[&>*]:ms-sm",
[SPACINGS.MEDIUM]: "ld:-mt-md ld:-ms-md ld:[&>*]:mt-md ld:[&>*]:ms-md",
[SPACINGS.LARGE]: "ld:-mt-lg ld:-ms-lg ld:[&>*]:mt-lg ld:[&>*]:ms-lg",
[SPACINGS.XLARGE]: "ld:-mt-xl ld:-ms-xl ld:[&>*]:mt-xl ld:[&>*]:ms-xl",
[SPACINGS.XXLARGE]: "ld:-mt-xxl ld:-ms-xxl ld:[&>*]:mt-xxl ld:[&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "ld:-mt-xxxl ld:-ms-xxxl ld:[&>*]:mt-xxxl ld:[&>*]:ms-xxxl",
},
[QUERIES.DESKTOP]: {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "de:-mt-xxxs de:-ms-xxxs de:[&>*]:mt-xxxs de:[&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "de:-mt-xxs de:-ms-xxs de:[&>*]:mt-xxs de:[&>*]:ms-xxs",
[SPACINGS.XSMALL]: "de:-mt-xs de:-ms-xs de:[&>*]:mt-xs de:[&>*]:ms-xs",
[SPACINGS.SMALL]: "de:-mt-sm de:-ms-sm de:[&>*]:mt-sm de:[&>*]:ms-sm",
[SPACINGS.MEDIUM]: "de:-mt-md de:-ms-md de:[&>*]:mt-md de:[&>*]:ms-md",
[SPACINGS.LARGE]: "de:-mt-lg de:-ms-lg de:[&>*]:mt-lg de:[&>*]:ms-lg",
[SPACINGS.XLARGE]: "de:-mt-xl de:-ms-xl de:[&>*]:mt-xl de:[&>*]:ms-xl",
[SPACINGS.XXLARGE]: "de:-mt-xxl de:-ms-xxl de:[&>*]:mt-xxl de:[&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "de:-mt-xxxl de:-ms-xxxl de:[&>*]:mt-xxxl de:[&>*]:ms-xxxl",
},
[QUERIES.TABLET]: {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "tb:-mt-xxxs tb:-ms-xxxs tb:[&>*]:mt-xxxs tb:[&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "tb:-mt-xxs tb:-ms-xxs tb:[&>*]:mt-xxs tb:[&>*]:ms-xxs",
[SPACINGS.XSMALL]: "tb:-mt-xs tb:-ms-xs tb:[&>*]:mt-xs tb:[&>*]:ms-xs",
[SPACINGS.SMALL]: "tb:-mt-sm tb:-ms-sm tb:[&>*]:mt-sm tb:[&>*]:ms-sm",
[SPACINGS.MEDIUM]: "tb:-mt-md tb:-ms-md tb:[&>*]:mt-md tb:[&>*]:ms-md",
[SPACINGS.LARGE]: "tb:-mt-lg tb:-ms-lg tb:[&>*]:mt-lg tb:[&>*]:ms-lg",
[SPACINGS.XLARGE]: "tb:-mt-xl tb:-ms-xl tb:[&>*]:mt-xl tb:[&>*]:ms-xl",
[SPACINGS.XXLARGE]: "tb:-mt-xxl tb:-ms-xxl tb:[&>*]:mt-xxl tb:[&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "tb:-mt-xxxl tb:-ms-xxxl tb:[&>*]:mt-xxxl tb:[&>*]:ms-xxxl",
},
[QUERIES.LARGEMOBILE]: {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "lm:-mt-xxxs lm:-ms-xxxs lm:[&>*]:mt-xxxs lm:[&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "lm:-mt-xxs lm:-ms-xxs lm:[&>*]:mt-xxs lm:[&>*]:ms-xxs",
[SPACINGS.XSMALL]: "lm:-mt-xs lm:-ms-xs lm:[&>*]:mt-xs lm:[&>*]:ms-xs",
[SPACINGS.SMALL]: "lm:-mt-sm lm:-ms-sm lm:[&>*]:mt-sm lm:[&>*]:ms-sm",
[SPACINGS.MEDIUM]: "lm:-mt-md lm:-ms-md lm:[&>*]:mt-md lm:[&>*]:ms-md",
[SPACINGS.LARGE]: "lm:-mt-lg lm:-ms-lg lm:[&>*]:mt-lg lm:[&>*]:ms-lg",
[SPACINGS.XLARGE]: "lm:-mt-xl lm:-ms-xl lm:[&>*]:mt-xl lm:[&>*]:ms-xl",
[SPACINGS.XXLARGE]: "lm:-mt-xxl lm:-ms-xxl lm:[&>*]:mt-xxl lm:[&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "lm:-mt-xxxl lm:-ms-xxxl lm:[&>*]:mt-xxxl lm:[&>*]:ms-xxxl",
},
[QUERIES.MEDIUMMOBILE]: {
[SPACINGS.NONE]: "",
[SPACINGS.XXXSMALL]: "mm:-mt-xxxs mm:-ms-xxxs mm:[&>*]:mt-xxxs mm:[&>*]:ms-xxxs",
[SPACINGS.XXSMALL]: "mm:-mt-xxs mm:-ms-xxs mm:[&>*]:mt-xxs mm:[&>*]:ms-xxs",
[SPACINGS.XSMALL]: "mm:-mt-xs mm:-ms-xs mm:[&>*]:mt-xs mm:[&>*]:ms-xs",
[SPACINGS.SMALL]: "mm:-mt-sm mm:-ms-sm mm:[&>*]:mt-sm mm:[&>*]:ms-sm",
[SPACINGS.MEDIUM]: "mm:-mt-md mm:-ms-md mm:[&>*]:mt-md mm:[&>*]:ms-md",
[SPACINGS.LARGE]: "mm:-mt-lg mm:-ms-lg mm:[&>*]:mt-lg mm:[&>*]:ms-lg",
[SPACINGS.XLARGE]: "mm:-mt-xl mm:-ms-xl mm:[&>*]:mt-xl mm:[&>*]:ms-xl",
[SPACINGS.XXLARGE]: "mm:-mt-xxl mm:-ms-xxl mm:[&>*]:mt-xxl mm:[&>*]:ms-xxl",
[SPACINGS.XXXLARGE]: "mm:-mt-xxxl mm:-ms-xxxl mm:[&>*]:mt-xxxl mm:[&>*]:ms-xxxl",
},
};

type PropObject = Record<Prop, Align | Justify | SpacingToken>;

export const normalize =
(object: PropObject) =>
({ theme }: ThemeProps): string[] | null => {
if (!object) return null;

return Object.keys(object).reduce<string[]>((acc, key) => {
const val = object[key];
const getSpacingClasses = (spacing: `${SPACINGS}`, viewport?: QUERIES): string => {
return viewport ? spacingClasses[viewport][spacing] : spacingClasses[spacing];
};

if (key === "spacing") return [...acc, normalizeSpacing(val, theme)];
if (key === "justify") return [...acc, formatCSS("justify-content", getJustify(val))];
if (key === "align") return [...acc, formatCSS("align-items", getAlign(val))];
if (val) return [...acc, formatCSS(key, val)];
export const getTailwindClasses = (
props: MediaQuery,
viewport?: QUERIES,
): (string | null | undefined | (string | boolean)[])[] => {
const { align, justify, spacing } = props;

return acc;
}, []);
};
return [
align && getAlignItemsClasses(align, viewport),
justify && getJustifyClasses(justify, viewport),
spacing && getSpacingClasses(spacing, viewport),
];
};

0 comments on commit 22464a6

Please sign in to comment.