diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2fd89ce31e..ffb99f3fb4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,6 +105,7 @@ jobs: - name: Cypress uses: cypress-io/github-action@v5 with: + browser: chrome install: false working-directory: packages/orbit-components start: yarn cy:dev diff --git a/packages/orbit-components/cypress.config.ts b/packages/orbit-components/cypress.config.ts index e9af8024a4..8006103c07 100644 --- a/packages/orbit-components/cypress.config.ts +++ b/packages/orbit-components/cypress.config.ts @@ -3,6 +3,10 @@ import { devServer } from "@cypress/vite-dev-server"; export default defineConfig({ pageLoadTimeout: 120000, + defaultCommandTimeout: 120000, + videoCompression: false, + video: false, + screenshotOnRunFailure: false, e2e: { baseUrl: "http://localhost:3000", specPattern: "cypress/**/*.test.*", diff --git a/packages/orbit-components/cypress/integration/index.css b/packages/orbit-components/cypress/integration/index.css index 8510da3823..8209681b69 100644 --- a/packages/orbit-components/cypress/integration/index.css +++ b/packages/orbit-components/cypress/integration/index.css @@ -1 +1 @@ -@import "tailwindcss/base"; +@import "../../src/tailwind.css"; diff --git a/packages/orbit-components/cypress/integration/index.tsx b/packages/orbit-components/cypress/integration/index.tsx index 83278d47ea..b9f873113a 100644 --- a/packages/orbit-components/cypress/integration/index.tsx +++ b/packages/orbit-components/cypress/integration/index.tsx @@ -7,11 +7,13 @@ import { OrbitProvider, defaultTheme } from "@kiwicom/orbit-components"; import LockScrolling from "./pages/lock-scrolling"; import MediaQueries from "./pages/media-queries"; import ModalFooter from "./pages/modal-footer"; +import BoxMediaProps from "./pages/box-mediaquery-props"; const router = createRouter({ lockScrolling: "/lock-scrolling", mediaQueries: "/media-queries", modalFooter: "/modal-footer", + boxMediaProps: "/box-media-props", }); function PageNotFound() { @@ -52,6 +54,12 @@ function App() { ); + case "boxMediaProps": + return ( + + + + ); default: return ; } diff --git a/packages/orbit-components/cypress/integration/pages/box-media-query.test.ts b/packages/orbit-components/cypress/integration/pages/box-media-query.test.ts new file mode 100644 index 0000000000..c521b6f01e --- /dev/null +++ b/packages/orbit-components/cypress/integration/pages/box-media-query.test.ts @@ -0,0 +1,68 @@ +import { defaultTokens } from "@kiwicom/orbit-design-tokens"; +import color from "onecolor"; + +describe("Box media query", () => { + it("should have correct styles for medium mobile", () => { + cy.visit("/box-media-props"); + cy.viewport(defaultTokens.widthBreakpointMediumMobile, 600); + const element = cy.findByText("Box Content"); + element.should("have.css", "display", "flex"); + element.should("have.css", "flex-wrap", "wrap"); + element.should("have.css", "flex-direction", "row-reverse"); + element.should("have.css", "position", "fixed"); + element.should("have.css", "min-width", "42px"); + element.should("not.have.css", "text-align", "center"); // Assertion of next media query style + }); + it("should have correct styles for large mobile", () => { + cy.visit("/box-media-props"); + cy.viewport(defaultTokens.widthBreakpointLargeMobile, 600); + const element = cy.findByText("Box Content"); + element.should("have.css", "text-align", "center"); + element.should("have.css", "border-radius", defaultTokens.borderRadiusLarge); + element.should("have.css", "overflow", "scroll"); + element.should("have.css", "flex-shrink", "0"); + element.should( + "have.css", + "color", + color(defaultTokens.paletteOrangeDark).css().replaceAll(",", ", "), + ); + element.should("not.have.css", "flex-grow", "1"); // Assertion of next media query style + }); + it("should have correct styles for tablet", () => { + cy.visit("/box-media-props"); + cy.viewport(defaultTokens.widthBreakpointTablet, 600); + const element = cy.findByText("Box Content"); + element.should("have.css", "flex-grow", "1"); + element.should("have.css", "z-index", "42"); + element.should("have.css", "width", "100px"); + element.should("have.css", "justify-content", "space-between"); + element.should("not.have.css", "align-items", "flex-end"); // Assertion of next media query style + }); + it("should have correct styles for desktop", () => { + cy.visit("/box-media-props"); + cy.viewport(defaultTokens.widthBreakpointDesktop, 600); + const element = cy.findByText("Box Content"); + element.should("not.have.css", "max-height", "24px"); // Assertion of next media query style + element.should("have.css", "height", "10px"); + element.should("have.css", "top", "10px"); + element.should("have.css", "left", "5px"); + element.should("have.css", "right", "0px"); + element.should("have.css", "bottom", "-1px"); + }); + it("should have correct styles for large desktop", () => { + cy.visit("/box-media-props"); + cy.viewport(defaultTokens.widthBreakpointLargeDesktop, 600); + const element = cy.findByText("Box Content"); + element.should( + "have.css", + "background-color", + color(defaultTokens.paletteRedLight).css().replaceAll(",", ", "), + ); + element.should("have.css", "padding", defaultTokens.spaceLarge); + element.should("have.css", "margin-top", defaultTokens.spaceSmall); + element.should("have.css", "margin-left", "0px"); + element.should("have.css", "margin-right", defaultTokens.spaceXSmall); + element.should("have.css", "align-items", "flex-end"); + element.should("have.css", "max-height", "24px"); + }); +}); diff --git a/packages/orbit-components/cypress/integration/pages/box-mediaquery-props.tsx b/packages/orbit-components/cypress/integration/pages/box-mediaquery-props.tsx new file mode 100644 index 0000000000..efc0593009 --- /dev/null +++ b/packages/orbit-components/cypress/integration/pages/box-mediaquery-props.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { Box } from "@kiwicom/orbit-components"; + +export default function BoxMediaProps() { + return ( + + Box Content + + ); +} diff --git a/packages/orbit-components/package.json b/packages/orbit-components/package.json index 727e6b987e..8c0da714f8 100644 --- a/packages/orbit-components/package.json +++ b/packages/orbit-components/package.json @@ -126,6 +126,7 @@ "loki": "^0.30.3", "monstra": "^0.9.2", "nanostores": "^0.5.12", + "onecolor": "^4.0.0", "ora": "^6.1.0", "react-element-to-jsx-string": "^14.3.2", "react-window": "^1.8.6", diff --git a/packages/orbit-components/src/Box/Box.stories.tsx b/packages/orbit-components/src/Box/Box.stories.tsx index e7b6440a76..3126bec917 100644 --- a/packages/orbit-components/src/Box/Box.stories.tsx +++ b/packages/orbit-components/src/Box/Box.stories.tsx @@ -2,7 +2,6 @@ import * as React from "react"; import { text, select, number } from "@storybook/addon-knobs"; import RenderInRtl from "../utils/rtl/RenderInRtl"; -import { WIDTH_AND_HEIGHT } from "./consts"; import type { SpacingToken, ColorTokens } from "./types"; import Box from "."; @@ -373,10 +372,10 @@ export const Playground = () => { const textAlign = select("text-align", Object.values(TEXT_ALIGN), TEXT_ALIGN.LEFT); const justify = select("justify", Object.values(JUSTIFY), JUSTIFY.CENTER); const direction = select("direction", Object.values(DIRECTION), DIRECTION.ROW); - const width = text("width", WIDTH_AND_HEIGHT.FULL); + const width = text("width", "full"); const minWidth = text("min-width", ""); const maxWidth = text("max-width", "300px"); - const height = text("height", WIDTH_AND_HEIGHT.AUTO); + const height = text("height", "auto"); const maxHeight = text("max-height", "100px"); const elevation = select("elevation", Object.values(ELEVATION), ELEVATION.ACTION); const borderRadius = select("border-radius", Object.values(BORDER_RADIUS), BORDER_RADIUS.NORMAL); diff --git a/packages/orbit-components/src/Box/__tests__/index.test.tsx b/packages/orbit-components/src/Box/__tests__/index.test.tsx index def809d598..91bd960dad 100644 --- a/packages/orbit-components/src/Box/__tests__/index.test.tsx +++ b/packages/orbit-components/src/Box/__tests__/index.test.tsx @@ -1,106 +1,91 @@ import * as React from "react"; -import { convertHexToRgba } from "@kiwicom/orbit-design-tokens"; import { screen, render } from "../../test-utils"; import { getJustify, getAlign } from "../../utils/layout"; import theme from "../../defaultTheme"; +import type { Props } from "../types"; import { TOKENS } from "../../utils/layout/consts"; +import { ALIGN } from "../../common/tailwind/alignItems"; +import { DISPLAY } from "../../common/tailwind/display"; +import { JUSTIFY } from "../../common/tailwind/justify"; +import { DIRECTION as FLEX_DIRECTIONS } from "../../common/tailwind/direction"; +import { TEXT_ALIGN } from "../../common/tailwind/textAlign"; +import type { BORDER_RADIUS as BORDER_RADIUS_KEYS } from "../helpers/tailwindClasses"; +import { POSITION as POSITIONS, SHADOWS as ELEVATION, OVERFLOW } from "../helpers/tailwindClasses"; import Box from ".."; const dataTest = "test"; -enum DIRECTIONS { - ROW = "row", - COLUMN = "column", - "ROW-REVERSE" = "row-reverse", - "COLUMN-REVERSE" = "column-reverse", -} - -enum ALIGN { - START = "start", - END = "end", - CENTER = "center", - STRETCH = "stretch", -} - -enum POSITIONS { - ABSOLUTE = "absolute", - RELATIVE = "relative", - FIXED = "fixed", -} - -enum JUSTIFY { - CENTER = "center", - START = "start", - END = "end", - BETWEEN = "between", - AROUND = "around", -} - -enum TEXT_ALIGN { - LEFT = "left", - RIGHT = "right", - CENTER = "center", -} - -enum ELEVATION { - ACTION = "action", - FIXED = "fixed", - RAISED = "raised", - OVERLAY = "overlay", - FIXEDREVERSE = "fixedReverse", -} +const BORDER_RADIUS: { [K in BORDER_RADIUS_KEYS]: string } = { + small: theme.orbit.borderRadiusSmall, + normal: theme.orbit.borderRadiusNormal, + large: theme.orbit.borderRadiusLarge, + circle: theme.orbit.borderRadiusCircle, +}; describe("#Box", () => { it("should have basic props", () => { render( kek , ); const el = screen.getByTestId(dataTest); - const getOmittedHex = (hex: string) => - convertHexToRgba(hex, NaN).replace(", NaN", "").replace("rgba", "rgb"); expect(el).toBeInTheDocument(); - expect(el).toHaveStyle({ color: getOmittedHex(theme.orbit.paletteBlueDark) }); - expect(el).toHaveStyle({ background: getOmittedHex(theme.orbit.paletteCloudLight) }); + expect(el.tagName).toBe("DIV"); + expect(el).toHaveStyle({ "box-sizing": "border-box" }); + expect(el).toHaveStyle({ "font-family": theme.orbit.fontFamily }); expect(el).toHaveStyle({ padding: TOKENS(theme).medium }); expect(el).toHaveStyle({ margin: TOKENS(theme).medium }); - expect(el).toHaveStyle({ display: "block" }); - expect(el).toHaveStyle({ minWidth: "100px" }); - expect(el).toHaveStyle({ maxWidth: "300px" }); - expect(el).toHaveStyle({ maxHeight: "100px" }); + expect(el).toHaveStyle({ "--box-width": "100%", width: "var(--box-width)" }); + expect(el).toHaveStyle({ "--box-min-width": "100px", "min-width": "var(--box-min-width)" }); + expect(el).toHaveStyle({ "--box-max-width": "300px", "max-width": "var(--box-max-width)" }); + expect(el).toHaveStyle({ "--box-height": "100%", height: "var(--box-height)" }); + expect(el).toHaveStyle({ "--box-max-height": "100px", "max-height": "var(--box-max-height)" }); }); - it("should have display flex", () => { + it("should render according to the passed as prop 'as'", () => { render( - + kek , ); - expect(screen.getByTestId(dataTest)).toHaveStyle({ display: "flex" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ flexDirection: "row" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ flexShrink: "0" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ flexGrow: "0" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ flexWrap: "nowrap" }); + expect(screen.getByTestId(dataTest).tagName).toBe("SPAN"); }); - it.each(Object.values(DIRECTIONS))("should have directions", direction => { + it("should have display flex properties", () => { render( - + + kek + , + ); + + expect(screen.getByTestId(dataTest)).toHaveStyle({ "flex-wrap": "nowrap" }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-shrink": "0", + "flex-shrink": "var(--box-shrink)", + }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-grow": "0", + "flex-grow": "var(--box-grow)", + }); + }); + + it.each(Object.values(FLEX_DIRECTIONS))("should have directions", direction => { + render( + kek , ); @@ -110,6 +95,18 @@ describe("#Box", () => { }); }); + it.each(Object.values(DISPLAY))("should have display", display => { + render( + + kek + , + ); + + expect(screen.getByTestId(`${dataTest}-${display}`)).toHaveStyle({ + display, + }); + }); + it.each(Object.values(POSITIONS))("should have positions", position => { render( @@ -122,7 +119,7 @@ describe("#Box", () => { it.each(Object.keys(JUSTIFY))("should have justify-content", key => { render( - + kek , ); @@ -134,7 +131,7 @@ describe("#Box", () => { it.each(Object.keys(ALIGN))("should have align-items", key => { render( - + kek , ); @@ -156,6 +153,30 @@ describe("#Box", () => { }); }); + it.each(Object.values(OVERFLOW))("should have overflow", overflow => { + render( + + kek + , + ); + + expect(screen.getByTestId(`${dataTest}-${overflow}`)).toHaveStyle({ + overflow, + }); + }); + + it.each(Object.keys(BORDER_RADIUS))("should have border-radius", radius => { + render( + + kek + , + ); + + expect(screen.getByTestId(`${dataTest}-${radius}`)).toHaveStyle({ + "border-radius": BORDER_RADIUS[radius], + }); + }); + it("should have ref", () => { const ref = React.createRef(); @@ -175,10 +196,22 @@ describe("#Box", () => { , ); - expect(screen.getByTestId(dataTest)).toHaveStyle({ top: "10px" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ bottom: "0px" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ left: "5px" }); - expect(screen.getByTestId(dataTest)).toHaveStyle({ right: "0px" }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-top": "10px", + top: "var(--box-top)", + }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-bottom": "0", + bottom: "var(--box-bottom)", + }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-left": "5px", + left: "var(--box-left)", + }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "--box-right": "0", + right: "var(--box-right)", + }); }); it("should have z-index", () => { @@ -188,51 +221,57 @@ describe("#Box", () => { , ); - expect(screen.getByTestId(dataTest)).toHaveStyle({ zIndex: 3 }); + expect(screen.getByTestId(dataTest)).toHaveStyle({ + "z-index": "var(--box-z-index)", + "--box-z-index": "3", + }); }); it("should have padding and margin object props", () => { render( kek , ); expect(screen.getByTestId("kek")).toHaveStyle({ - paddingTop: "8px", - paddingLeft: "4px", - paddingRight: "16px", - paddingBottom: "0", - marginTop: "8px", - marginLeft: "4px", - marginRight: "16px", - marginBottom: "0", + padding: "40px 24px 52px 4px", + margin: "8px 16px 0 2px", + }); + }); + + it("should have padding and margin string props", () => { + render( + + kek + , + ); + + expect(screen.getByTestId("kek")).toHaveStyle({ + padding: "32px", + margin: "12px", }); }); it("should have elevation", () => { const test = Object.keys(ELEVATION).map((key, idx) => ( - + kek )); const testEl = (idx: number) => render(test[idx]).getByTestId(`${dataTest}-${idx}`); - const trimSpaces = val => val.replace(/, /g, ","); - - expect(testEl(0)).toHaveStyle({ boxShadow: trimSpaces(theme.orbit.boxShadowAction) }); - expect(testEl(1)).toHaveStyle({ boxShadow: trimSpaces(theme.orbit.boxShadowFixed) }); - expect(testEl(2)).toHaveStyle({ boxShadow: trimSpaces(theme.orbit.boxShadowRaised) }); - expect(testEl(3)).toHaveStyle({ boxShadow: trimSpaces(theme.orbit.boxShadowOverlay) }); - }); - - it("should have display list-item", () => { - render(); - expect(screen.getByTestId("box")).toHaveStyle({ display: "list-item" }); + expect(testEl(0)).toHaveStyle({ + "--tw-shadow": theme.orbit.boxShadowAction, + }); + expect(testEl(1)).toHaveStyle({ "--tw-shadow": theme.orbit.boxShadowFixed }); + expect(testEl(2)).toHaveStyle({ "--tw-shadow": theme.orbit.boxShadowRaised }); + expect(testEl(3)).toHaveStyle({ "--tw-shadow": theme.orbit.boxShadowOverlay }); + expect(testEl(4)).toHaveStyle({ "--tw-shadow": theme.orbit.boxShadowFixedReverse }); }); }); diff --git a/packages/orbit-components/src/Box/consts.ts b/packages/orbit-components/src/Box/consts.ts deleted file mode 100644 index 7802f42138..0000000000 --- a/packages/orbit-components/src/Box/consts.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum WIDTH_AND_HEIGHT { - FULL = "full", - AUTO = "auto", -} diff --git a/packages/orbit-components/src/Box/helpers/getAlignItems.ts b/packages/orbit-components/src/Box/helpers/getAlignItems.ts new file mode 100644 index 0000000000..d6e5ac6f7e --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getAlignItems.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { alignItemsClasses } from "../../common/tailwind/alignItems"; + +const getAlignItemsClass = (align: Props["align"], viewport?: QUERIES) => { + if (!align) return null; + + return viewport ? alignItemsClasses[viewport][align] : alignItemsClasses[align]; +}; + +export default getAlignItemsClass; diff --git a/packages/orbit-components/src/Box/helpers/getBackground.ts b/packages/orbit-components/src/Box/helpers/getBackground.ts new file mode 100644 index 0000000000..37c14ce13a --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getBackground.ts @@ -0,0 +1,13 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { backgroundColorClasses } from "../../common/tailwind/backgroundColor"; + +const getBackgroundClass = (background: Props["background"], viewport?: QUERIES) => { + if (!background) return null; + + return viewport + ? backgroundColorClasses[viewport][background] + : backgroundColorClasses[background]; +}; + +export default getBackgroundClass; diff --git a/packages/orbit-components/src/Box/helpers/getBorderRadius.ts b/packages/orbit-components/src/Box/helpers/getBorderRadius.ts new file mode 100644 index 0000000000..9c1db6a730 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getBorderRadius.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { borderRadiusClasses } from "./tailwindClasses"; + +const getBorderRadiusClass = (borderRadius: Props["borderRadius"], viewport?: QUERIES) => { + if (!borderRadius) return null; + + return viewport ? borderRadiusClasses[viewport][borderRadius] : borderRadiusClasses[borderRadius]; +}; + +export default getBorderRadiusClass; diff --git a/packages/orbit-components/src/Box/helpers/getColor.ts b/packages/orbit-components/src/Box/helpers/getColor.ts new file mode 100644 index 0000000000..0ea9f8dda3 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getColor.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { colorClasses } from "../../common/tailwind/color"; + +const getColorClass = (color: Props["color"], viewport?: QUERIES) => { + if (!color) return null; + + return viewport ? colorClasses[viewport][color] : colorClasses[color]; +}; + +export default getColorClass; diff --git a/packages/orbit-components/src/Box/helpers/getDirection.ts b/packages/orbit-components/src/Box/helpers/getDirection.ts new file mode 100644 index 0000000000..f04ce672de --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getDirection.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { directionClasses } from "../../common/tailwind/direction"; + +const getDirectionClass = (direction: Props["direction"], viewport?: QUERIES) => { + if (!direction) return null; + + return viewport ? directionClasses[viewport][direction] : directionClasses[direction]; +}; + +export default getDirectionClass; diff --git a/packages/orbit-components/src/Box/helpers/getDisplay.ts b/packages/orbit-components/src/Box/helpers/getDisplay.ts new file mode 100644 index 0000000000..41e5224688 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getDisplay.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { displayClasses } from "../../common/tailwind/display"; + +const getDisplayClass = (display: Props["display"], viewport?: QUERIES) => { + if (!display) return null; + + return viewport ? displayClasses[viewport][display] : displayClasses[display]; +}; + +export default getDisplayClass; diff --git a/packages/orbit-components/src/Box/helpers/getElevation.ts b/packages/orbit-components/src/Box/helpers/getElevation.ts new file mode 100644 index 0000000000..f068bf0dc1 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getElevation.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { shadowClasses } from "./tailwindClasses"; + +const getElevationClass = (elevation: Props["elevation"], viewport?: QUERIES) => { + if (!elevation) return null; + + return viewport ? shadowClasses[viewport][elevation] : shadowClasses[elevation]; +}; + +export default getElevationClass; diff --git a/packages/orbit-components/src/Box/helpers/getJustify.ts b/packages/orbit-components/src/Box/helpers/getJustify.ts new file mode 100644 index 0000000000..05d6c60f3a --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getJustify.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { justifyClasses } from "../../common/tailwind/justify"; + +const getJustifyClass = (justify: Props["justify"], viewport?: QUERIES) => { + if (!justify) return null; + + return viewport ? justifyClasses[viewport][justify] : justifyClasses[justify]; +}; + +export default getJustifyClass; diff --git a/packages/orbit-components/src/Box/helpers/getMargin.ts b/packages/orbit-components/src/Box/helpers/getMargin.ts new file mode 100644 index 0000000000..79f8d3d704 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getMargin.ts @@ -0,0 +1,29 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { + marginBottomClasses, + marginClasses, + marginLeftClasses, + marginRightClasses, + marginTopClasses, +} from "../../common/tailwind/margin"; + +const getMarginClass = (margin: Props["margin"], viewport?: QUERIES) => { + if (!margin) return null; + + if (typeof margin === "object") { + const { top, bottom, left, right } = margin; + + return [ + top != null && (viewport ? marginTopClasses[viewport][top] : marginTopClasses[top]), + bottom != null && + (viewport ? marginBottomClasses[viewport][bottom] : marginBottomClasses[bottom]), + left != null && (viewport ? marginLeftClasses[viewport][left] : marginLeftClasses[left]), + right != null && (viewport ? marginRightClasses[viewport][right] : marginRightClasses[right]), + ]; + } + + return viewport ? marginClasses[viewport][margin] : marginClasses[margin]; +}; + +export default getMarginClass; diff --git a/packages/orbit-components/src/Box/helpers/getOverflow.ts b/packages/orbit-components/src/Box/helpers/getOverflow.ts new file mode 100644 index 0000000000..e094644f5a --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getOverflow.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { overflowClasses } from "./tailwindClasses"; + +const getOverflowClass = (overflow: Props["overflow"], viewport?: QUERIES) => { + if (!overflow) return null; + + return viewport ? overflowClasses[viewport][overflow] : overflowClasses[overflow]; +}; + +export default getOverflowClass; diff --git a/packages/orbit-components/src/Box/helpers/getPadding.ts b/packages/orbit-components/src/Box/helpers/getPadding.ts new file mode 100644 index 0000000000..6dab365d41 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getPadding.ts @@ -0,0 +1,30 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { + paddingBottomClasses, + paddingClasses, + paddingLeftClasses, + paddingRightClasses, + paddingTopClasses, +} from "../../common/tailwind/padding"; + +const getPaddingClass = (padding: Props["padding"], viewport?: QUERIES) => { + if (!padding) return null; + + if (typeof padding === "object") { + const { top, bottom, left, right } = padding; + + return [ + top != null && (viewport ? paddingTopClasses[viewport][top] : paddingTopClasses[top]), + bottom != null && + (viewport ? paddingBottomClasses[viewport][bottom] : paddingBottomClasses[bottom]), + left != null && (viewport ? paddingLeftClasses[viewport][left] : paddingLeftClasses[left]), + right != null && + (viewport ? paddingRightClasses[viewport][right] : paddingRightClasses[right]), + ]; + } + + return viewport ? paddingClasses[viewport][padding] : paddingClasses[padding]; +}; + +export default getPaddingClass; diff --git a/packages/orbit-components/src/Box/helpers/getPosition.ts b/packages/orbit-components/src/Box/helpers/getPosition.ts new file mode 100644 index 0000000000..b046004a73 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getPosition.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { positionClasses } from "./tailwindClasses"; + +const getPositionClass = (position: Props["position"], viewport?: QUERIES) => { + if (!position) return null; + + return viewport ? positionClasses[viewport][position] : positionClasses[position]; +}; + +export default getPositionClass; diff --git a/packages/orbit-components/src/Box/helpers/getTextAlign.ts b/packages/orbit-components/src/Box/helpers/getTextAlign.ts new file mode 100644 index 0000000000..08b16a6674 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getTextAlign.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { textAlignClasses } from "../../common/tailwind/textAlign"; + +const getTextAlignClass = (textAlign: Props["textAlign"], viewport?: QUERIES) => { + if (!textAlign) return null; + + return viewport ? textAlignClasses[viewport][textAlign] : textAlignClasses[textAlign]; +}; + +export default getTextAlignClass; diff --git a/packages/orbit-components/src/Box/helpers/getWrap.ts b/packages/orbit-components/src/Box/helpers/getWrap.ts new file mode 100644 index 0000000000..9a0960b32f --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/getWrap.ts @@ -0,0 +1,11 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import { wrapClasses } from "../../common/tailwind/wrap"; + +const getWrapClass = (wrap: Props["wrap"], viewport?: QUERIES) => { + if (!wrap) return null; + + return viewport ? wrapClasses[viewport][wrap] : wrapClasses[wrap]; +}; + +export default getWrapClass; diff --git a/packages/orbit-components/src/Box/helpers/index.ts b/packages/orbit-components/src/Box/helpers/index.ts new file mode 100644 index 0000000000..b7731261c3 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/index.ts @@ -0,0 +1,54 @@ +import type { Props } from "../types"; +import type { QUERIES } from "../../utils/mediaQuery/consts"; +import getDisplayClass from "./getDisplay"; +import getWrapClass from "./getWrap"; +import getDirectionClass from "./getDirection"; +import getPositionClass from "./getPosition"; +import getAlignItemsClass from "./getAlignItems"; +import getJustifyClass from "./getJustify"; +import getTextAlignClass from "./getTextAlign"; +import getElevationClass from "./getElevation"; +import getBorderRadiusClass from "./getBorderRadius"; +import getOverflowClass from "./getOverflow"; +import getColorClass from "./getColor"; +import getBackgroundClass from "./getBackground"; +import getPaddingClass from "./getPadding"; +import getMarginClass from "./getMargin"; + +const getTailwindClasses = (props: Props, viewport?: QUERIES) => { + const { + display, + wrap, + direction, + position, + align, + justify, + textAlign, + elevation, + borderRadius, + overflow, + color, + background, + padding, + margin, + } = props; + + return [ + display && getDisplayClass(display, viewport), + wrap && getWrapClass(wrap, viewport), + direction && getDirectionClass(direction, viewport), + position && getPositionClass(position, viewport), + align && getAlignItemsClass(align, viewport), + justify && getJustifyClass(justify, viewport), + textAlign && getTextAlignClass(textAlign, viewport), + elevation && getElevationClass(elevation, viewport), + borderRadius && getBorderRadiusClass(borderRadius, viewport), + overflow && getOverflowClass(overflow, viewport), + color && getColorClass(color, viewport), + background && getBackgroundClass(background, viewport), + padding && getPaddingClass(padding, viewport), + margin && getMarginClass(margin, viewport), + ]; +}; + +export default getTailwindClasses; diff --git a/packages/orbit-components/src/Box/helpers/tailwindClasses.ts b/packages/orbit-components/src/Box/helpers/tailwindClasses.ts new file mode 100644 index 0000000000..bb479865c4 --- /dev/null +++ b/packages/orbit-components/src/Box/helpers/tailwindClasses.ts @@ -0,0 +1,192 @@ +import { QUERIES } from "../../utils/mediaQuery/consts"; + +export enum POSITION { + ABSOLUTE = "absolute", + RELATIVE = "relative", + FIXED = "fixed", +} + +export const positionClasses: { + [K in QUERIES | POSITION]: K extends QUERIES ? Record : string; +} = { + [POSITION.ABSOLUTE]: "absolute", + [POSITION.RELATIVE]: "relative", + [POSITION.FIXED]: "fixed", + [QUERIES.LARGEDESKTOP]: { + [POSITION.ABSOLUTE]: "ld:absolute", + [POSITION.RELATIVE]: "ld:relative", + [POSITION.FIXED]: "ld:fixed", + }, + [QUERIES.DESKTOP]: { + [POSITION.ABSOLUTE]: "de:absolute", + [POSITION.RELATIVE]: "de:relative", + [POSITION.FIXED]: "de:fixed", + }, + [QUERIES.TABLET]: { + [POSITION.ABSOLUTE]: "tb:absolute", + [POSITION.RELATIVE]: "tb:relative", + [POSITION.FIXED]: "tb:fixed", + }, + [QUERIES.LARGEMOBILE]: { + [POSITION.ABSOLUTE]: "lm:absolute", + [POSITION.RELATIVE]: "lm:relative", + [POSITION.FIXED]: "lm:fixed", + }, + [QUERIES.MEDIUMMOBILE]: { + [POSITION.ABSOLUTE]: "mm:absolute", + [POSITION.RELATIVE]: "mm:relative", + [POSITION.FIXED]: "mm:fixed", + }, +}; + +export enum SHADOWS { + ACTION = "action", + FIXED = "fixed", + RAISED = "raised", + OVERLAY = "overlay", + FIXED_REVERSE = "fixedReverse", + RAISED_REVERSE = "raisedReverse", +} + +export const shadowClasses: { + [K in QUERIES | SHADOWS]: K extends QUERIES ? Record : string; +} = { + [SHADOWS.ACTION]: "shadow-action", + [SHADOWS.FIXED]: "shadow-fixed", + [SHADOWS.RAISED]: "shadow-raised", + [SHADOWS.OVERLAY]: "shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "shadow-raised-reverse", + [QUERIES.LARGEDESKTOP]: { + [SHADOWS.ACTION]: "ld:shadow-action", + [SHADOWS.FIXED]: "ld:shadow-fixed", + [SHADOWS.RAISED]: "ld:shadow-raised", + [SHADOWS.OVERLAY]: "ld:shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "ld:shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "ld:shadow-raised-reverse", + }, + [QUERIES.DESKTOP]: { + [SHADOWS.ACTION]: "de:shadow-action", + [SHADOWS.FIXED]: "de:shadow-fixed", + [SHADOWS.RAISED]: "de:shadow-raised", + [SHADOWS.OVERLAY]: "de:shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "de:shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "de:shadow-raised-reverse", + }, + [QUERIES.TABLET]: { + [SHADOWS.ACTION]: "tb:shadow-action", + [SHADOWS.FIXED]: "tb:shadow-fixed", + [SHADOWS.RAISED]: "tb:shadow-raised", + [SHADOWS.OVERLAY]: "tb:shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "tb:shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "tb:shadow-raised-reverse", + }, + [QUERIES.LARGEMOBILE]: { + [SHADOWS.ACTION]: "lm:shadow-action", + [SHADOWS.FIXED]: "lm:shadow-fixed", + [SHADOWS.RAISED]: "lm:shadow-raised", + [SHADOWS.OVERLAY]: "lm:shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "lm:shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "lm:shadow-raised-reverse", + }, + [QUERIES.MEDIUMMOBILE]: { + [SHADOWS.ACTION]: "mm:shadow-action", + [SHADOWS.FIXED]: "mm:shadow-fixed", + [SHADOWS.RAISED]: "mm:shadow-raised", + [SHADOWS.OVERLAY]: "mm:shadow-overlay", + [SHADOWS.FIXED_REVERSE]: "mm:shadow-fixed-reverse", + [SHADOWS.RAISED_REVERSE]: "mm:shadow-raised-reverse", + }, +}; + +export enum BORDER_RADIUS { + SMALL = "small", + NORMAL = "normal", + LARGE = "large", + CIRCLE = "circle", +} + +export const borderRadiusClasses: { + [K in QUERIES | BORDER_RADIUS]: K extends QUERIES ? Record : string; +} = { + [BORDER_RADIUS.SMALL]: "rounded-small", + [BORDER_RADIUS.NORMAL]: "rounded-normal", + [BORDER_RADIUS.LARGE]: "rounded-large", + [BORDER_RADIUS.CIRCLE]: "rounded-circle", + [QUERIES.LARGEDESKTOP]: { + [BORDER_RADIUS.SMALL]: "ld:rounded-small", + [BORDER_RADIUS.NORMAL]: "ld:rounded-normal", + [BORDER_RADIUS.LARGE]: "ld:rounded-large", + [BORDER_RADIUS.CIRCLE]: "ld:rounded-circle", + }, + [QUERIES.DESKTOP]: { + [BORDER_RADIUS.SMALL]: "de:rounded-small", + [BORDER_RADIUS.NORMAL]: "de:rounded-normal", + [BORDER_RADIUS.LARGE]: "de:rounded-large", + [BORDER_RADIUS.CIRCLE]: "de:rounded-circle", + }, + [QUERIES.TABLET]: { + [BORDER_RADIUS.SMALL]: "tb:rounded-small", + [BORDER_RADIUS.NORMAL]: "tb:rounded-normal", + [BORDER_RADIUS.LARGE]: "tb:rounded-large", + [BORDER_RADIUS.CIRCLE]: "tb:rounded-circle", + }, + [QUERIES.LARGEMOBILE]: { + [BORDER_RADIUS.SMALL]: "lm:rounded-small", + [BORDER_RADIUS.NORMAL]: "lm:rounded-normal", + [BORDER_RADIUS.LARGE]: "lm:rounded-large", + [BORDER_RADIUS.CIRCLE]: "lm:rounded-circle", + }, + [QUERIES.MEDIUMMOBILE]: { + [BORDER_RADIUS.SMALL]: "mm:rounded-small", + [BORDER_RADIUS.NORMAL]: "mm:rounded-normal", + [BORDER_RADIUS.LARGE]: "mm:rounded-large", + [BORDER_RADIUS.CIRCLE]: "mm:rounded-circle", + }, +}; + +export enum OVERFLOW { + AUTO = "auto", + HIDDEN = "hidden", + SCROLL = "scroll", + VISIBLE = "visible", +} + +export const overflowClasses: { + [K in QUERIES | OVERFLOW]: K extends QUERIES ? Record : string; +} = { + [OVERFLOW.AUTO]: "overflow-auto", + [OVERFLOW.HIDDEN]: "overflow-hidden", + [OVERFLOW.SCROLL]: "overflow-scroll", + [OVERFLOW.VISIBLE]: "overflow-visible", + [QUERIES.LARGEDESKTOP]: { + [OVERFLOW.AUTO]: "ld:overflow-auto", + [OVERFLOW.HIDDEN]: "ld:overflow-hidden", + [OVERFLOW.SCROLL]: "ld:overflow-scroll", + [OVERFLOW.VISIBLE]: "ld:overflow-visible", + }, + [QUERIES.DESKTOP]: { + [OVERFLOW.AUTO]: "de:overflow-auto", + [OVERFLOW.HIDDEN]: "de:overflow-hidden", + [OVERFLOW.SCROLL]: "de:overflow-scroll", + [OVERFLOW.VISIBLE]: "de:overflow-visible", + }, + [QUERIES.TABLET]: { + [OVERFLOW.AUTO]: "tb:overflow-auto", + [OVERFLOW.HIDDEN]: "tb:overflow-hidden", + [OVERFLOW.SCROLL]: "tb:overflow-scroll", + [OVERFLOW.VISIBLE]: "tb:overflow-visible", + }, + [QUERIES.LARGEMOBILE]: { + [OVERFLOW.AUTO]: "lm:overflow-auto", + [OVERFLOW.HIDDEN]: "lm:overflow-hidden", + [OVERFLOW.SCROLL]: "lm:overflow-scroll", + [OVERFLOW.VISIBLE]: "lm:overflow-visible", + }, + [QUERIES.MEDIUMMOBILE]: { + [OVERFLOW.AUTO]: "mm:overflow-auto", + [OVERFLOW.HIDDEN]: "mm:overflow-hidden", + [OVERFLOW.SCROLL]: "mm:overflow-scroll", + [OVERFLOW.VISIBLE]: "mm:overflow-visible", + }, +}; diff --git a/packages/orbit-components/src/Box/index.tsx b/packages/orbit-components/src/Box/index.tsx index 8e7989338c..e2f2674585 100644 --- a/packages/orbit-components/src/Box/index.tsx +++ b/packages/orbit-components/src/Box/index.tsx @@ -1,44 +1,16 @@ "use client"; import * as React from "react"; -import styled, { css } from "styled-components"; +import cx from "clsx"; -import defaultTheme from "../defaultTheme"; -import media from "../utils/mediaQuery"; -import { DEVICES as DEVICES_CONSTS } from "../utils/mediaQuery/consts"; -import normalize from "./normalize"; +import { QUERIES } from "../utils/mediaQuery/consts"; import type { Props } from "./types"; - -const StyledBox = styled( - ({ className, asComponent: Element, children, dataTest, id, forwardRef }) => ( - - {children} - - ), -)` - font-family: ${({ theme }) => theme.orbit.fontFamily}; - box-sizing: border-box; - ${({ viewports }) => { - return Object.keys(viewports).map(query => { - const value = viewports[query]; - if (query !== Object.values(DEVICES_CONSTS)[0] && typeof value !== "undefined") { - return media[query](css` - ${normalize(value)} - `); - } - return normalize(value); - }); - }} -`; - -StyledBox.defaultProps = { - theme: defaultTheme, -}; +import getTailwindClasses from "./helpers"; const Box = React.forwardRef( ( { - as = "div", + as: Component = "div", id, mediumMobile, largeMobile, @@ -48,23 +20,237 @@ const Box = React.forwardRef( children, dataTest, className, - ...smallMobile + display, + wrap, + direction, + position, + align, + justify, + textAlign, + elevation, + borderRadius, + overflow, + shrink, + grow, + zIndex, + width, + minWidth, + maxWidth, + height, + maxHeight, + top, + right, + bottom, + left, + color, + background, + padding, + margin, }, ref, ) => { - const viewports = { smallMobile, mediumMobile, largeMobile, tablet, desktop, largeDesktop }; + const twProps = { + display, + wrap, + direction, + position, + align, + justify, + textAlign, + elevation, + borderRadius, + overflow, + color, + background, + padding, + margin, + }; + + const viewportClasses = React.useMemo(() => { + const viewportSpecs = { + mediumMobile, + largeMobile, + tablet, + desktop, + largeDesktop, + }; + + return Object.values(QUERIES).map(viewport => { + const viewportProps = viewportSpecs[viewport]; + + if (viewportProps == null) return null; + + return getTailwindClasses(viewportProps, viewport); + }); + }, [mediumMobile, largeMobile, tablet, desktop, largeDesktop]); + + const vars = { + "--box-shrink": shrink, + "--ld-box-shrink": largeDesktop?.shrink, + "--de-box-shrink": desktop?.shrink, + "--tb-box-shrink": tablet?.shrink, + "--lm-box-shrink": largeMobile?.shrink, + "--mm-box-shrink": mediumMobile?.shrink, + "--box-grow": grow, + "--ld-box-grow": largeDesktop?.grow, + "--de-box-grow": desktop?.grow, + "--tb-box-grow": tablet?.grow, + "--lm-box-grow": largeMobile?.grow, + "--mm-box-grow": mediumMobile?.grow, + "--box-z-index": zIndex, + "--ld-box-z-index": largeDesktop?.zIndex, + "--de-box-z-index": desktop?.zIndex, + "--tb-box-z-index": tablet?.zIndex, + "--lm-box-z-index": largeMobile?.zIndex, + "--mm-box-z-index": mediumMobile?.zIndex, + "--box-width": width, + "--ld-box-width": largeDesktop?.width, + "--de-box-width": desktop?.width, + "--tb-box-width": tablet?.width, + "--lm-box-width": largeMobile?.width, + "--mm-box-width": mediumMobile?.width, + "--box-min-width": minWidth, + "--ld-box-min-width": largeDesktop?.minWidth, + "--de-box-min-width": desktop?.minWidth, + "--tb-box-min-width": tablet?.minWidth, + "--lm-box-min-width": largeMobile?.minWidth, + "--mm-box-min-width": mediumMobile?.minWidth, + "--box-max-width": maxWidth, + "--ld-box-max-width": largeDesktop?.maxWidth, + "--de-box-max-width": desktop?.maxWidth, + "--tb-box-max-width": tablet?.maxWidth, + "--lm-box-max-width": largeMobile?.maxWidth, + "--mm-box-max-width": mediumMobile?.maxWidth, + "--box-height": height, + "--ld-box-height": largeDesktop?.height, + "--de-box-height": desktop?.height, + "--tb-box-height": tablet?.height, + "--lm-box-height": largeMobile?.height, + "--mm-box-height": mediumMobile?.height, + "--box-max-height": maxHeight, + "--ld-box-max-height": largeDesktop?.maxHeight, + "--de-box-max-height": desktop?.maxHeight, + "--tb-box-max-height": tablet?.maxHeight, + "--lm-box-max-height": largeMobile?.maxHeight, + "--mm-box-max-height": mediumMobile?.maxHeight, + "--box-top": top, + "--ld-box-top": largeDesktop?.top, + "--de-box-top": desktop?.top, + "--tb-box-top": tablet?.top, + "--lm-box-top": largeMobile?.top, + "--mm-box-top": mediumMobile?.top, + "--box-right": right, + "--ld-box-right": largeDesktop?.right, + "--de-box-right": desktop?.right, + "--tb-box-right": tablet?.right, + "--lm-box-right": largeMobile?.right, + "--mm-box-right": mediumMobile?.right, + "--box-bottom": bottom, + "--ld-box-bottom": largeDesktop?.bottom, + "--de-box-bottom": desktop?.bottom, + "--tb-box-bottom": tablet?.bottom, + "--lm-box-bottom": largeMobile?.bottom, + "--mm-box-bottom": mediumMobile?.bottom, + "--box-left": left, + "--ld-box-left": largeDesktop?.left, + "--de-box-left": desktop?.left, + "--tb-box-left": tablet?.left, + "--lm-box-left": largeMobile?.left, + "--mm-box-left": mediumMobile?.left, + }; + + const varClasses = [ + vars["--box-shrink"] != null && "shrink-[var(--box-shrink)]", + vars["--ld-box-shrink"] != null && "ld:shrink-[var(--ld-box-shrink)]", + vars["--de-box-shrink"] != null && "de:shrink-[var(--de-box-shrink)]", + vars["--tb-box-shrink"] != null && "tb:shrink-[var(--tb-box-shrink)]", + vars["--lm-box-shrink"] != null && "lm:shrink-[var(--lm-box-shrink)]", + vars["--mm-box-shrink"] != null && "mm:shrink-[var(--mm-box-shrink)]", + vars["--box-grow"] != null && "grow-[var(--box-grow)]", + vars["--ld-box-grow"] != null && "ld:grow-[var(--ld-box-grow)]", + vars["--de-box-grow"] != null && "de:grow-[var(--de-box-grow)]", + vars["--tb-box-grow"] != null && "tb:grow-[var(--tb-box-grow)]", + vars["--lm-box-grow"] != null && "lm:grow-[var(--lm-box-grow)]", + vars["--mm-box-grow"] != null && "mm:grow-[var(--mm-box-grow)]", + vars["--box-z-index"] != null && "z-[var(--box-z-index)]", + vars["--ld-box-z-index"] != null && "ld:z-[var(--ld-box-z-index)]", + vars["--de-box-z-index"] != null && "de:z-[var(--de-box-z-index)]", + vars["--tb-box-z-index"] != null && "tb:z-[var(--tb-box-z-index)]", + vars["--lm-box-z-index"] != null && "lm:z-[var(--lm-box-z-index)]", + vars["--mm-box-z-index"] != null && "mm:z-[var(--mm-box-z-index)]", + vars["--box-width"] != null && "w-[var(--box-width)]", + vars["--ld-box-width"] != null && "ld:w-[var(--ld-box-width)]", + vars["--de-box-width"] != null && "de:w-[var(--de-box-width)]", + vars["--tb-box-width"] != null && "tb:w-[var(--tb-box-width)]", + vars["--lm-box-width"] != null && "lm:w-[var(--lm-box-width)]", + vars["--mm-box-width"] != null && "mm:w-[var(--mm-box-width)]", + vars["--box-min-width"] != null && "min-w-[var(--box-min-width)]", + vars["--ld-box-min-width"] != null && "ld:min-w-[var(--ld-box-min-width)]", + vars["--de-box-min-width"] != null && "de:min-w-[var(--de-box-min-width)]", + vars["--tb-box-min-width"] != null && "tb:min-w-[var(--tb-box-min-width)]", + vars["--lm-box-min-width"] != null && "lm:min-w-[var(--lm-box-min-width)]", + vars["--mm-box-min-width"] != null && "mm:min-w-[var(--mm-box-min-width)]", + vars["--box-max-width"] != null && "max-w-[var(--box-max-width)]", + vars["--ld-box-max-width"] != null && "ld:max-w-[var(--ld-box-max-width)]", + vars["--de-box-max-width"] != null && "de:max-w-[var(--de-box-max-width)]", + vars["--tb-box-max-width"] != null && "tb:max-w-[var(--tb-box-max-width)]", + vars["--lm-box-max-width"] != null && "lm:max-w-[var(--lm-box-max-width)]", + vars["--mm-box-max-width"] != null && "mm:max-w-[var(--mm-box-max-width)]", + vars["--box-height"] != null && "h-[var(--box-height)]", + vars["--ld-box-height"] != null && "ld:h-[var(--ld-box-height)]", + vars["--de-box-height"] != null && "de:h-[var(--de-box-height)]", + vars["--tb-box-height"] != null && "tb:h-[var(--tb-box-height)]", + vars["--lm-box-height"] != null && "lm:h-[var(--lm-box-height)]", + vars["--mm-box-height"] != null && "mm:h-[var(--mm-box-height)]", + vars["--box-max-height"] != null && "max-h-[var(--box-max-height)]", + vars["--ld-box-max-height"] != null && "ld:max-h-[var(--ld-box-max-height)]", + vars["--de-box-max-height"] != null && "de:max-h-[var(--de-box-max-height)]", + vars["--tb-box-max-height"] != null && "tb:max-h-[var(--tb-box-max-height)]", + vars["--lm-box-max-height"] != null && "lm:max-h-[var(--lm-box-max-height)]", + vars["--mm-box-max-height"] != null && "mm:max-h-[var(--mm-box-max-height)]", + vars["--box-top"] != null && "top-[var(--box-top)]", + vars["--ld-box-top"] != null && "ld:top-[var(--ld-box-top)]", + vars["--de-box-top"] != null && "de:top-[var(--de-box-top)]", + vars["--tb-box-top"] != null && "tb:top-[var(--tb-box-top)]", + vars["--lm-box-top"] != null && "lm:top-[var(--lm-box-top)]", + vars["--mm-box-top"] != null && "mm:top-[var(--mm-box-top)]", + vars["--box-right"] != null && "right-[var(--box-right)]", + vars["--ld-box-right"] != null && "ld:right-[var(--ld-box-right)]", + vars["--de-box-right"] != null && "de:right-[var(--de-box-right)]", + vars["--tb-box-right"] != null && "tb:right-[var(--tb-box-right)]", + vars["--lm-box-right"] != null && "lm:right-[var(--lm-box-right)]", + vars["--mm-box-right"] != null && "mm:right-[var(--mm-box-right)]", + vars["--box-bottom"] != null && "bottom-[var(--box-bottom)]", + vars["--ld-box-bottom"] != null && "ld:bottom-[var(--ld-box-bottom)]", + vars["--de-box-bottom"] != null && "de:bottom-[var(--de-box-bottom)]", + vars["--tb-box-bottom"] != null && "tb:bottom-[var(--tb-box-bottom)]", + vars["--lm-box-bottom"] != null && "lm:bottom-[var(--lm-box-bottom)]", + vars["--mm-box-bottom"] != null && "mm:bottom-[var(--mm-box-bottom)]", + vars["--box-left"] != null && "left-[var(--box-left)]", + vars["--ld-box-left"] != null && "ld:left-[var(--ld-box-left)]", + vars["--de-box-left"] != null && "de:left-[var(--de-box-left)]", + vars["--tb-box-left"] != null && "tb:left-[var(--tb-box-left)]", + vars["--lm-box-left"] != null && "lm:left-[var(--lm-box-left)]", + vars["--mm-box-left"] != null && "mm:left-[var(--mm-box-left)]", + ]; return ( - {children} - + ); }, ); diff --git a/packages/orbit-components/src/Box/normalize.ts b/packages/orbit-components/src/Box/normalize.ts deleted file mode 100644 index 44784b7053..0000000000 --- a/packages/orbit-components/src/Box/normalize.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { WIDTH_AND_HEIGHT } from "./consts"; -import { TOKENS } from "../utils/layout/consts"; -import type { ThemeProps, Theme } from "../defaultTheme"; -import { firstToUpper } from "../utils/common"; -import { getJustify, getAlign, formatCSS, getDirection, isDefined } from "../utils/layout"; -import type { MediaQueryObject, Elevation, SpacingToken, SpacingObject } from "./types"; - -const normalizeSpacing = ( - el: SpacingToken | SpacingObject, - property: string, - theme: Theme, -): string[] => { - if (typeof el === "object") { - return Object.keys(el).map(key => { - const val = el[key]; - if (val === "none") return formatCSS(`${property}-${key}`, "0"); - return formatCSS(`${property}-${key}`, TOKENS(theme)[val]); - }); - } - - if (el !== "none") { - return [formatCSS(property, TOKENS(theme)[el])]; - } - - return []; -}; - -const normalizeToken = (token, property, prefix, theme: Theme): string => - formatCSS(property, theme.orbit[prefix + firstToUpper(token)]); - -const normalizeSize = (val: string, property: string): string => { - if (val === WIDTH_AND_HEIGHT.FULL) { - return formatCSS(property, "100%"); - } - - return formatCSS(property, val); -}; - -const normalizeElevation = (val: Elevation, theme: Theme): string => { - return formatCSS("box-shadow", theme.orbit[`boxShadow${firstToUpper(val)}`]); -}; - -const norm = ({ val, key, theme }): string | void => { - if (!isDefined(val) || !isDefined(key)) return undefined; - - const all = { - padding: normalizeSpacing(val, key, theme), - margin: normalizeSpacing(val, key, theme), - color: key === "color" && normalizeToken(val, key, "palette", theme), - background: key === "background" && normalizeToken(val, key, "palette", theme), - height: normalizeSize(val, key), - width: normalizeSize(val, key), - borderRadius: - key === "borderRadius" && normalizeToken(val, "border-radius", "borderRadius", theme), - elevation: key === "elevation" && normalizeElevation(val, theme), - justify: formatCSS("justify-content", getJustify(val)), - align: formatCSS("align-items", getAlign(val)), - direction: formatCSS("flex-direction", getDirection(val)), - grow: formatCSS("flex-grow", val), - shrink: formatCSS("flex-shrink", val), - wrap: formatCSS("flex-wrap", val), - textAlign: formatCSS("text-align", val), - minWidth: formatCSS("min-width", val), - maxWidth: formatCSS("max-width", val), - maxHeight: formatCSS("max-height", val), - zIndex: formatCSS("z-index", val), - }; - - if (!all[key]) return formatCSS(key, val); - - return all[key]; -}; - -const normalize = - (mqObject: MediaQueryObject) => - ({ theme }: ThemeProps): string[] | null => { - if (!mqObject) return null; - - return Object.keys(mqObject).reduce((acc, prop) => { - const val = mqObject[prop]; - const accFn = additional => [...acc, ...additional]; - return accFn([norm({ val, key: prop, theme })]); - }, []); - }; - -export default normalize; diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/getBasis.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/getBasis.test.ts deleted file mode 100644 index 069b378cfd..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/getBasis.test.ts +++ /dev/null @@ -1,8 +0,0 @@ -import getBasis from "../getBasis"; -import theme from "../../../defaultTheme"; - -describe("#getBasis", () => { - it("should set basis", () => { - expect(getBasis("200px")({ theme })).toBe("200px"); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/getDisplay.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/getDisplay.test.ts deleted file mode 100644 index 8290c26082..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/getDisplay.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import getDisplay from "../getDisplay"; - -describe("#getDisplay", () => { - it("should return inline-flex", () => { - expect(getDisplay(true)).toBe("inline-flex"); - }); - - it("should return flex", () => { - expect(getDisplay(false)).toBe("flex"); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/getProperty.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/getProperty.test.ts deleted file mode 100644 index 295f0b69e6..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/getProperty.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import getProperty from "../getProperty"; -import theme from "../../../defaultTheme"; -import type { Devices } from "../../../utils/mediaQuery/types"; - -const params = { - index: 0, - devices: ["smallMobile"] as Devices[], -}; - -const props = { - children: " kek", - smallMobile: { - spacing: "XXSmall", - direction: "column", - }, - theme, -}; - -describe("#getProperty", () => { - it("should get property spacing", () => { - expect(getProperty("spacing", params, props)).toBe("XXSmall"); - }); - - it("should get property direction", () => { - expect(getProperty("direction", params, props)).toBe("column"); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/getSpacing.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/getSpacing.test.ts deleted file mode 100644 index 6b259072c7..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/getSpacing.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import getSpacing from "../getSpacing"; -import theme from "../../../defaultTheme"; - -describe("#getSpacing", () => { - it("should return spacings", () => { - expect(getSpacing(theme)).toEqual({ - none: "", - XXXSmall: "2px", - XXSmall: "4px", - XSmall: "8px", - small: "12px", - medium: "16px", - large: "24px", - XLarge: "32px", - XXLarge: "40px", - XXXLarge: "52px", - }); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/getWidth.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/getWidth.test.ts deleted file mode 100644 index eef16cdf57..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/getWidth.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import getWidth from "../getWidth"; - -describe("#getWidth", () => { - it("should return false", () => { - expect(getWidth(true)).toBe(""); - }); - - it("should return 100%", () => { - // inline props is set to false - expect(getWidth(false)).toBe("100%"); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/__tests__/shouldUseFlex.test.ts b/packages/orbit-components/src/Stack/helpers/__tests__/shouldUseFlex.test.ts deleted file mode 100644 index 0d0fc6b7e5..0000000000 --- a/packages/orbit-components/src/Stack/helpers/__tests__/shouldUseFlex.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import shouldUseFlex from "../shouldUseFlex"; - -describe("#shouldUseFlex", () => { - it("should return true", () => { - const props = { - children: "kek", - wrap: true, - }; - - expect(shouldUseFlex(props)).toBe(true); - }); - - it("should return false", () => { - const props = { - children: "kek", - }; - - expect(shouldUseFlex(props)).toBe(false); - }); -}); diff --git a/packages/orbit-components/src/Stack/helpers/getBasis.ts b/packages/orbit-components/src/Stack/helpers/getBasis.ts deleted file mode 100644 index ccd8ea2dbe..0000000000 --- a/packages/orbit-components/src/Stack/helpers/getBasis.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Basis } from "../types"; -import type { Theme } from "../../defaultTheme"; - -const getBasis = - (basis: Basis) => - ({ theme }: { theme: Theme }): Basis => { - if (typeof basis === "undefined") return ""; - if (typeof basis === "function") return basis(theme); - - return basis; - }; - -export default getBasis; diff --git a/packages/orbit-components/src/Stack/helpers/getDisplay.ts b/packages/orbit-components/src/Stack/helpers/getDisplay.ts deleted file mode 100644 index 202bea0e01..0000000000 --- a/packages/orbit-components/src/Stack/helpers/getDisplay.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { isDefined } from "../../utils/layout"; - -const getDisplay = (inline: boolean): "inline-flex" | "flex" | false => - isDefined(inline) && (inline ? "inline-flex" : "flex"); - -export default getDisplay; diff --git a/packages/orbit-components/src/Stack/helpers/getGap.ts b/packages/orbit-components/src/Stack/helpers/getGap.ts deleted file mode 100644 index ae626615a3..0000000000 --- a/packages/orbit-components/src/Stack/helpers/getGap.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { FlattenInterpolation, ThemeProps } from "styled-components"; -import { css } from "styled-components"; - -import getSpacing from "./getSpacing"; -import getProperty from "./getProperty"; -import { rtlSpacing } from "../../utils/rtl"; -import { DIRECTIONS } from "../../utils/layout/consts"; -import type { Direction, Spacing, Props } from "../types"; -import type defaultTheme from "../../defaultTheme"; -import type { Devices } from "../../utils/mediaQuery/types"; - -interface PropsWithTheme extends Props { - theme: typeof defaultTheme; -} - -const getDirectionSpacingTemplate = (direction: Direction | Spacing): string => { - switch (direction) { - case DIRECTIONS.ROW: - return "0 __spacing__ 0 0"; - case DIRECTIONS.COLUMNREVERSE: - return "__spacing__ 0 0 0"; - case DIRECTIONS.ROWREVERSE: - return "0 0 0 __spacing__"; - default: - return "0 0 __spacing__ 0"; - } -}; - -const getGap = - ({ index, devices }: { index: number; devices: Devices[] }) => - (props: PropsWithTheme): FlattenInterpolation> | null => { - const spacing = getProperty("spacing", { index, devices }, props); - const direction = getProperty("direction", { index, devices }, props) as Direction; - const gap = spacing && direction && getSpacing(props.theme)[spacing]; - - const margin = - spacing && - direction && - String(getDirectionSpacingTemplate(direction)).replace( - "__spacing__", - getSpacing(props.theme)[spacing], - ); - - // workaround to make it work on Safari iOS < 14.1 - // TODO: remove that after dropping support for iOS < 14.1 - if (props.flex) { - return css` - gap: ${gap}; - @supports (-webkit-touch-callout: none) and (not (translate: none)) { - & > *:not(:last-child) { - margin: ${margin && rtlSpacing(margin)} !important; - } - } - `; - } - - return css` - & > * { - margin: ${margin && rtlSpacing(margin)}!important; - &:last-child { - margin: 0 !important; - } - } - `; - }; - -export default getGap; diff --git a/packages/orbit-components/src/Stack/helpers/getViewportFlexStyles.ts b/packages/orbit-components/src/Stack/helpers/getViewportFlexStyles.ts deleted file mode 100644 index 0dbb77f4b0..0000000000 --- a/packages/orbit-components/src/Stack/helpers/getViewportFlexStyles.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { FlattenInterpolation } from "styled-components"; -import { css } from "styled-components"; - -import { - getJustify, - getAlign, - getDirection, - getWrap, - getGrow, - getShrink, -} from "../../utils/layout"; -import getWidth from "./getWidth"; -import getDisplay from "./getDisplay"; -import getBasis from "./getBasis"; -import getSpacingToken from "../../common/getSpacingToken"; -import type { Devices } from "../../utils/mediaQuery/types"; -import type { Props } from "../types"; -import type { Theme } from "../../defaultTheme"; - -interface StyledProps extends Props { - theme: Theme; -} - -const getViewportFlexStyles = - (viewport: Devices) => - (props: StyledProps): FlattenInterpolation => { - const { flex, theme } = props; - const { inline, direction, wrap, grow, shrink, basis, justify, align, spaceAfter } = - props[viewport]; - - const flexStyles = - flex && - css` - display: ${getDisplay(inline)}; - flex-direction: ${getDirection(direction)}; - flex-wrap: ${getWrap(wrap)}; - flex-grow: ${getGrow(grow)}; - flex-shrink: ${getShrink(shrink)}; - flex-basis: ${getBasis(basis)({ theme })}; - justify-content: ${getJustify(justify)}; - align-content: ${getAlign(align)}; - align-items: ${getAlign(align)}; - `; - - return css` - ${flexStyles}; - width: ${getWidth(inline)}; - margin-bottom: ${getSpacingToken({ spaceAfter, theme })}; - `; - }; - -export default getViewportFlexStyles; diff --git a/packages/orbit-components/src/Stack/helpers/getWidth.ts b/packages/orbit-components/src/Stack/helpers/getWidth.ts deleted file mode 100644 index 58eddb34f4..0000000000 --- a/packages/orbit-components/src/Stack/helpers/getWidth.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { isDefined } from "../../utils/layout"; - -const getWidth = (inline: boolean): string => (isDefined(inline) && !inline ? "100%" : ""); - -export default getWidth; diff --git a/packages/orbit-components/src/Stack/helpers/isMobileViewport.ts b/packages/orbit-components/src/Stack/helpers/isMobileViewport.ts deleted file mode 100644 index 91464f1063..0000000000 --- a/packages/orbit-components/src/Stack/helpers/isMobileViewport.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Devices } from "../../utils/mediaQuery/types"; - -const isMobileViewport = (viewport: Devices): boolean => - viewport === "smallMobile" || viewport === "mediumMobile" || viewport === "largeMobile"; - -export default isMobileViewport; diff --git a/packages/orbit-components/src/Stack/helpers/shouldUseFlex.ts b/packages/orbit-components/src/Stack/helpers/shouldUseFlex.ts deleted file mode 100644 index 2e300db1cc..0000000000 --- a/packages/orbit-components/src/Stack/helpers/shouldUseFlex.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Props } from "../types"; - -const shouldUseFlex = (props: Props): boolean => - props.flex || - Object.keys(props) - .map( - item => - !( - item === "children" || - item === "spaceAfter" || - item === "spacing" || - item === "dataTest" - ), - ) - .indexOf(true) !== -1; - -export default shouldUseFlex; diff --git a/packages/orbit-components/src/common/tailwind/alignContent.ts b/packages/orbit-components/src/common/tailwind/alignContent.ts new file mode 100644 index 0000000000..8a3cdd8658 --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/alignContent.ts @@ -0,0 +1,64 @@ +import type { Devices } from "../../utils/mediaQuery/types"; +import { QUERIES } from "../../utils/mediaQuery/consts"; + +enum ALIGN_CONTENT { + START = "start", + CENTER = "center", + END = "end", + BASELINE = "baseline", + STRETCH = "stretch", +} + +export const alignContentClasses = { + [ALIGN_CONTENT.START]: "content-start", + [ALIGN_CONTENT.END]: "content-end", + [ALIGN_CONTENT.CENTER]: "content-center", + [ALIGN_CONTENT.BASELINE]: "content-baseline", + [ALIGN_CONTENT.STRETCH]: "content-stretch", + [QUERIES.MEDIUMMOBILE]: { + [ALIGN_CONTENT.START]: "mm:content-start", + [ALIGN_CONTENT.END]: "mm:content-end", + [ALIGN_CONTENT.CENTER]: "mm:content-center", + [ALIGN_CONTENT.BASELINE]: "mm:content-baseline", + [ALIGN_CONTENT.STRETCH]: "mm:content-stretch", + }, + [QUERIES.LARGEMOBILE]: { + [ALIGN_CONTENT.START]: "lm:content-start", + [ALIGN_CONTENT.END]: "lm:content-end", + [ALIGN_CONTENT.CENTER]: "lm:content-center", + [ALIGN_CONTENT.BASELINE]: "lm:content-baseline", + [ALIGN_CONTENT.STRETCH]: "lm:content-stretch", + }, + [QUERIES.TABLET]: { + [ALIGN_CONTENT.START]: "tb:content-start", + [ALIGN_CONTENT.END]: "tb:content-end", + [ALIGN_CONTENT.CENTER]: "tb:content-center", + [ALIGN_CONTENT.BASELINE]: "tb:content-baseline", + [ALIGN_CONTENT.STRETCH]: "tb:content-stretch", + }, + [QUERIES.DESKTOP]: { + [ALIGN_CONTENT.START]: "de:content-start", + [ALIGN_CONTENT.END]: "de:content-end", + [ALIGN_CONTENT.CENTER]: "de:content-center", + [ALIGN_CONTENT.BASELINE]: "de:content-baseline", + [ALIGN_CONTENT.STRETCH]: "de:content-stretch", + }, + [QUERIES.LARGEDESKTOP]: { + [ALIGN_CONTENT.START]: "ld:content-start", + [ALIGN_CONTENT.END]: "ld:content-end", + [ALIGN_CONTENT.CENTER]: "ld:content-center", + [ALIGN_CONTENT.BASELINE]: "ld:content-baseline", + [ALIGN_CONTENT.STRETCH]: "ld:content-stretch", + }, +}; + +const getAlignContentClasses = ( + align: Lowercase, + viewport?: Devices, +) => { + const root = viewport ? alignContentClasses[viewport] : alignContentClasses; + + return root[align]; +}; + +export default getAlignContentClasses; diff --git a/packages/orbit-components/src/common/tailwind/align.ts b/packages/orbit-components/src/common/tailwind/alignItems.ts similarity index 77% rename from packages/orbit-components/src/common/tailwind/align.ts rename to packages/orbit-components/src/common/tailwind/alignItems.ts index 32c1e3afdf..a82b7b5f63 100644 --- a/packages/orbit-components/src/common/tailwind/align.ts +++ b/packages/orbit-components/src/common/tailwind/alignItems.ts @@ -1,13 +1,15 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Align } from "../../Stack/types"; +import type { Devices } from "../../utils/mediaQuery/types"; -enum ALIGN { +export enum ALIGN { START = "start", CENTER = "center", END = "end", STRETCH = "stretch", } -export const alignClasses: { +export const alignItemsClasses: { [K in QUERIES | ALIGN]: K extends QUERIES ? Record : string; } = { [ALIGN.START]: "items-start", @@ -45,3 +47,11 @@ export const alignClasses: { [ALIGN.STRETCH]: "mm:items-stretch", }, }; + +const getAlignItemsClasses = (align: Align, viewport?: Devices) => { + const root = viewport ? alignItemsClasses[viewport] : alignItemsClasses; + + return root[align]; +}; + +export default getAlignItemsClasses; diff --git a/packages/orbit-components/src/common/tailwind/direction.ts b/packages/orbit-components/src/common/tailwind/direction.ts index 24b9bf88dd..0e7e4e29dd 100644 --- a/packages/orbit-components/src/common/tailwind/direction.ts +++ b/packages/orbit-components/src/common/tailwind/direction.ts @@ -1,6 +1,8 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Devices } from "../../utils/mediaQuery/types"; +import type { Direction } from "../../Stack/types"; -enum DIRECTION { +export enum DIRECTION { ROW = "row", COLUMN = "column", ROW_REVERSE = "row-reverse", @@ -45,3 +47,11 @@ export const directionClasses: { [DIRECTION.COLUMN_REVERSE]: "mm:flex-col-reverse", }, }; + +const getDirectionToken = (direction: Direction, viewport?: Devices) => { + const root = viewport ? directionClasses[viewport] : directionClasses; + + return root[direction]; +}; + +export default getDirectionToken; diff --git a/packages/orbit-components/src/common/tailwind/display.ts b/packages/orbit-components/src/common/tailwind/display.ts index d483d34e9d..6ea2d40388 100644 --- a/packages/orbit-components/src/common/tailwind/display.ts +++ b/packages/orbit-components/src/common/tailwind/display.ts @@ -1,6 +1,7 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Devices } from "../../utils/mediaQuery/types"; -enum DISPLAY { +export enum DISPLAY { NONE = "none", FLEX = "flex", INLINE_FLEX = "inline-flex", @@ -66,3 +67,11 @@ export const displayClasses: { [DISPLAY.LIST_ITEM]: "mm:list-item", }, }; + +const getDisplayClasses = (inline: boolean, viewport?: Devices) => { + const root = viewport ? displayClasses[viewport] : displayClasses; + + return inline ? root.inline : root.flex; +}; + +export default getDisplayClasses; diff --git a/packages/orbit-components/src/common/tailwind/grow.ts b/packages/orbit-components/src/common/tailwind/grow.ts new file mode 100644 index 0000000000..88d228b84a --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/grow.ts @@ -0,0 +1,25 @@ +import type { Devices } from "../../utils/mediaQuery/types"; +import { QUERIES } from "../../utils/mediaQuery/consts"; + +enum GROW { + true = "grow", + false = "grow-0", +} + +export const growClasses = { + [GROW.false]: "grow-0", + [GROW.true]: "grow", + [QUERIES.MEDIUMMOBILE]: { [GROW.false]: "mm:grow-0", [GROW.true]: "mm:grow" }, + [QUERIES.LARGEMOBILE]: { [GROW.false]: "lm:grow-0", [GROW.true]: "lm:grow" }, + [QUERIES.TABLET]: { [GROW.false]: "tb:grow-0", [GROW.true]: "tb:grow" }, + [QUERIES.DESKTOP]: { [GROW.false]: "de:grow-0", [GROW.true]: "de:grow" }, + [QUERIES.LARGEDESKTOP]: { [GROW.false]: "ld:grow-0", [GROW.true]: "ld:grow" }, +}; + +const getGrowClasses = (grow: boolean, viewport?: Devices) => { + const root = viewport ? growClasses[viewport] : growClasses; + + return grow ? root.grow1 : root.grow0; +}; + +export default getGrowClasses; diff --git a/packages/orbit-components/src/common/tailwind/index.ts b/packages/orbit-components/src/common/tailwind/index.ts new file mode 100644 index 0000000000..31b1d3c853 --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/index.ts @@ -0,0 +1,44 @@ +import getAlignItemsClasses, { alignItemsClasses } from "./alignItems"; +import getAlignContentClasses, { alignContentClasses } from "./alignContent"; +import { backgroundColorClasses } from "./backgroundColor"; +import { colorClasses } from "./color"; +import getDisplayClasses, { displayClasses } from "./display"; +import getDirectionClasses, { directionClasses } from "./direction"; +import getJustifyClasses, { justifyClasses } from "./justify"; +import { marginClasses } from "./margin"; +import { paddingClasses } from "./padding"; +import { textAlignClasses } from "./textAlign"; +import getWrapClasses, { wrapClasses } from "./wrap"; +import getShrinkClasses, { shrinkClasses } from "./shrink"; +import getSpacingClasses, { horizontalTokens, verticalTokens } from "./spacing"; +import getSpaceAfterClasses, { spaceAfterClasses } from "./spaceAfter"; +import getGrowClasses, { growClasses } from "./grow"; + +export { + getSpacingClasses, + getSpaceAfterClasses, + getAlignContentClasses, + getShrinkClasses, + getJustifyClasses, + getDisplayClasses, + getDirectionClasses, + getWrapClasses, + getAlignItemsClasses, + getGrowClasses, + horizontalTokens, + verticalTokens, + growClasses, + alignContentClasses, + alignItemsClasses, + directionClasses, + shrinkClasses, + backgroundColorClasses, + colorClasses, + displayClasses, + justifyClasses, + marginClasses, + paddingClasses, + spaceAfterClasses, + wrapClasses, + textAlignClasses, +}; diff --git a/packages/orbit-components/src/common/tailwind/justify.ts b/packages/orbit-components/src/common/tailwind/justify.ts index 00e05b2ab6..71339518ae 100644 --- a/packages/orbit-components/src/common/tailwind/justify.ts +++ b/packages/orbit-components/src/common/tailwind/justify.ts @@ -1,6 +1,8 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Justify } from "../../Stack/types"; +import type { Devices } from "../../utils/mediaQuery/types"; -enum JUSTIFY { +export enum JUSTIFY { START = "start", CENTER = "center", END = "end", @@ -52,3 +54,11 @@ export const justifyClasses: { [JUSTIFY.AROUND]: "mm:justify-around", }, }; + +export const getJustifyClasses = (justify: Justify, viewport?: Devices) => { + const root = viewport ? justifyClasses[viewport] : justifyClasses; + + return root[justify]; +}; + +export default getJustifyClasses; diff --git a/packages/orbit-components/src/common/tailwind/shrink.ts b/packages/orbit-components/src/common/tailwind/shrink.ts new file mode 100644 index 0000000000..b8c1a933f4 --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/shrink.ts @@ -0,0 +1,27 @@ +import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Devices } from "../../utils/mediaQuery/types"; + +enum SHRINK { + shrink = "shrink", + shrink0 = "shrink-0", +} + +export const shrinkClasses: { + [C in QUERIES | SHRINK]: C extends QUERIES ? Record : string; +} = { + [SHRINK.shrink0]: "shrink-0", + [SHRINK.shrink]: "shrink", + [QUERIES.MEDIUMMOBILE]: { [SHRINK.shrink0]: "mm:shrink-0", [SHRINK.shrink]: "mm:shrink" }, + [QUERIES.LARGEMOBILE]: { [SHRINK.shrink0]: "lm:shrink-0", [SHRINK.shrink]: "lm:shrink" }, + [QUERIES.TABLET]: { [SHRINK.shrink0]: "tb:shrink-0", [SHRINK.shrink]: "tb:shrink" }, + [QUERIES.DESKTOP]: { [SHRINK.shrink0]: "de:shrink-0", [SHRINK.shrink]: "de:shrink" }, + [QUERIES.LARGEDESKTOP]: { [SHRINK.shrink0]: "ld:shrink-0", [SHRINK.shrink]: "ld:shrink" }, +}; + +export const getShrinkToken = (shrink: boolean, viewport?: Devices) => { + const root = viewport ? shrinkClasses[viewport] : shrinkClasses; + + return shrink ? root.shrink1 : root.shrink0; +}; + +export default getShrinkToken; diff --git a/packages/orbit-components/src/common/tailwind/spaceAfter.ts b/packages/orbit-components/src/common/tailwind/spaceAfter.ts index 533e8efa8f..c0fc37fa5d 100644 --- a/packages/orbit-components/src/common/tailwind/spaceAfter.ts +++ b/packages/orbit-components/src/common/tailwind/spaceAfter.ts @@ -1,5 +1,7 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; import { SPACINGS_AFTER } from "../getSpacingToken"; +import type { SpaceAfterSizes as SpaceAfter } from "../types"; +import type { Devices } from "../../utils/mediaQuery/types"; export const spaceAfterClasses: { [K in QUERIES | SPACINGS_AFTER]: K extends QUERIES ? Record : string; @@ -57,3 +59,9 @@ export const spaceAfterClasses: { [SPACINGS_AFTER.LARGEST]: "ld:mb-xl", }, }; + +const getSpaceAfterClasses = (spaceAfter: SpaceAfter, Viewport?: Devices) => { + return Viewport ? spaceAfterClasses[Viewport][spaceAfter] : spaceAfterClasses[spaceAfter]; +}; + +export default getSpaceAfterClasses; diff --git a/packages/orbit-components/src/common/tailwind/spacing.ts b/packages/orbit-components/src/common/tailwind/spacing.ts new file mode 100644 index 0000000000..41ed68603c --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/spacing.ts @@ -0,0 +1,203 @@ +import cx from "clsx"; + +import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Devices } from "../../utils/mediaQuery/types"; +import type { Direction, Spacing } from "../../Stack/types"; + +enum SPACINGS { + none = "none", + XXXSmall = "XXXSmall", + XXSmall = "XXSmall", + XSmall = "XSmall", + reverse = "reverse", + small = "small", + medium = "medium", + large = "large", + XLarge = "XLarge", + XXLarge = "XXLarge", + XXXLarge = "XXXLarge", +} + +export const horizontalTokens: { + [K in QUERIES | SPACINGS]: K extends QUERIES ? Record : string; +} = { + [SPACINGS.none]: "space-x-none", + [SPACINGS.reverse]: "space-x-reverse", + [SPACINGS.XXXSmall]: "space-x-xxxs", + [SPACINGS.XXSmall]: "space-x-xxs", + [SPACINGS.XSmall]: "space-x-xs", + [SPACINGS.small]: "space-x-sm", + [SPACINGS.medium]: "space-x-md", + [SPACINGS.large]: "space-x-lg", + [SPACINGS.XLarge]: "space-x-xl", + [SPACINGS.XXLarge]: "space-x-xxl", + [SPACINGS.XXXLarge]: "space-x-xxxl", + [QUERIES.MEDIUMMOBILE]: { + [SPACINGS.none]: "mm:space-x-none", + [SPACINGS.reverse]: "mm:space-x-reverse", + [SPACINGS.XXXSmall]: "mm:space-x-xxxs", + [SPACINGS.XXSmall]: "mm:space-x-xxs", + [SPACINGS.XSmall]: "mm:space-x-xs", + [SPACINGS.small]: "mm:space-x-sm", + [SPACINGS.medium]: "mm:space-x-md", + [SPACINGS.large]: "mm:space-x-lg", + [SPACINGS.XLarge]: "mm:space-x-xl", + [SPACINGS.XXLarge]: "mm:space-x-xxl", + [SPACINGS.XXXLarge]: "mm:space-x-xxxl", + }, + [QUERIES.LARGEMOBILE]: { + [SPACINGS.none]: "lm:space-x-none", + [SPACINGS.reverse]: "lm:space-x-reverse", + [SPACINGS.XXXSmall]: "lm:space-x-xxxs", + [SPACINGS.XXSmall]: "lm:space-x-xxs", + [SPACINGS.XSmall]: "lm:space-x-xs", + [SPACINGS.small]: "lm:space-x-sm", + [SPACINGS.medium]: "lm:space-x-md", + [SPACINGS.large]: "lm:space-x-lg", + [SPACINGS.XLarge]: "lm:space-x-xl", + [SPACINGS.XXLarge]: "lm:space-x-xxl", + [SPACINGS.XXXLarge]: "lm:space-x-xxxl", + }, + [QUERIES.TABLET]: { + [SPACINGS.none]: "tb:space-x-none", + [SPACINGS.reverse]: "tb:space-x-reverse", + [SPACINGS.XXXSmall]: "tb:space-x-xxxs", + [SPACINGS.XXSmall]: "tb:space-x-xxs", + [SPACINGS.XSmall]: "tb:space-x-xs", + [SPACINGS.small]: "tb:space-x-sm", + [SPACINGS.medium]: "tb:space-x-md", + [SPACINGS.large]: "tb:space-x-lg", + [SPACINGS.XLarge]: "tb:space-x-xl", + [SPACINGS.XXLarge]: "tb:space-x-xxl", + [SPACINGS.XXXLarge]: "tb:space-x-xxxl", + }, + [QUERIES.DESKTOP]: { + [SPACINGS.none]: "de:space-x-none", + [SPACINGS.reverse]: "de:space-x-reverse", + [SPACINGS.XXXSmall]: "de:space-x-xxxs", + [SPACINGS.XXSmall]: "de:space-x-xxs", + [SPACINGS.XSmall]: "de:space-x-xs", + [SPACINGS.small]: "de:space-x-sm", + [SPACINGS.medium]: "de:space-x-md", + [SPACINGS.large]: "de:space-x-lg", + [SPACINGS.XLarge]: "de:space-x-xl", + [SPACINGS.XXLarge]: "de:space-x-xxl", + [SPACINGS.XXXLarge]: "de:space-x-xxxl", + }, + [QUERIES.LARGEDESKTOP]: { + [SPACINGS.none]: "ld:space-x-none", + [SPACINGS.reverse]: "ld:space-x-reverse", + [SPACINGS.XXXSmall]: "ld:space-x-xxxs", + [SPACINGS.XXSmall]: "ld:space-x-xxs", + [SPACINGS.XSmall]: "ld:space-x-xs", + [SPACINGS.small]: "ld:space-x-sm", + [SPACINGS.medium]: "ld:space-x-md", + [SPACINGS.large]: "ld:space-x-lg", + [SPACINGS.XLarge]: "ld:space-x-xl", + [SPACINGS.XXLarge]: "ld:space-x-xxl", + [SPACINGS.XXXLarge]: "ld:space-x-xxxl", + }, +}; + +export const verticalTokens = { + [SPACINGS.none]: "space-y-none", + [SPACINGS.reverse]: "space-y-reverse", + [SPACINGS.XXXSmall]: "space-y-xxxs", + [SPACINGS.XXSmall]: "space-y-xxs", + [SPACINGS.XSmall]: "space-y-xs", + [SPACINGS.small]: "space-y-sm", + [SPACINGS.medium]: "space-y-md", + [SPACINGS.large]: "space-y-lg", + [SPACINGS.XLarge]: "space-y-xl", + [SPACINGS.XXLarge]: "space-y-xxl", + [SPACINGS.XXXLarge]: "space-y-xxxl", + [QUERIES.MEDIUMMOBILE]: { + [SPACINGS.none]: "mm:space-y-none", + [SPACINGS.reverse]: "mm:space-y-reverse", + [SPACINGS.XXXSmall]: "mm:space-y-xxxs", + [SPACINGS.XXSmall]: "mm:space-y-xxs", + [SPACINGS.XSmall]: "mm:space-y-xs", + [SPACINGS.small]: "mm:space-y-sm", + [SPACINGS.medium]: "mm:space-y-md", + [SPACINGS.large]: "mm:space-y-lg", + [SPACINGS.XLarge]: "mm:space-y-xl", + [SPACINGS.XXLarge]: "mm:space-y-xxl", + [SPACINGS.XXXLarge]: "mm:space-y-xxxl", + }, + largeMobile: { + [SPACINGS.none]: "lm:space-y-none", + [SPACINGS.reverse]: "lm:space-y-reverse", + [SPACINGS.XXXSmall]: "lm:space-y-xxxs", + [SPACINGS.XXSmall]: "lm:space-y-xxs", + [SPACINGS.XSmall]: "lm:space-y-xs", + [SPACINGS.small]: "lm:space-y-sm", + [SPACINGS.medium]: "lm:space-y-md", + [SPACINGS.large]: "lm:space-y-lg", + [SPACINGS.XLarge]: "lm:space-y-xl", + [SPACINGS.XXLarge]: "lm:space-y-xxl", + [SPACINGS.XXXLarge]: "lm:space-y-xxxl", + }, + tablet: { + [SPACINGS.none]: "tb:space-y-none", + [SPACINGS.reverse]: "tb:space-y-reverse", + [SPACINGS.XXXSmall]: "tb:space-y-xxxs", + [SPACINGS.XXSmall]: "tb:space-y-xxs", + [SPACINGS.XSmall]: "tb:space-y-xs", + [SPACINGS.small]: "tb:space-y-sm", + [SPACINGS.medium]: "tb:space-y-md", + [SPACINGS.large]: "tb:space-y-lg", + [SPACINGS.XLarge]: "tb:space-y-xl", + [SPACINGS.XXLarge]: "tb:space-y-xxl", + [SPACINGS.XXXLarge]: "tb:space-y-xxxl", + }, + [QUERIES.DESKTOP]: { + [SPACINGS.none]: "de:space-y-none", + [SPACINGS.reverse]: "de:space-y-reverse", + [SPACINGS.XXXSmall]: "de:space-y-xxxs", + [SPACINGS.XXSmall]: "de:space-y-xxs", + [SPACINGS.XSmall]: "de:space-y-xs", + [SPACINGS.small]: "de:space-y-sm", + [SPACINGS.medium]: "de:space-y-md", + [SPACINGS.large]: "de:space-y-lg", + [SPACINGS.XLarge]: "de:space-y-xl", + [SPACINGS.XXLarge]: "de:space-y-xxl", + [SPACINGS.XXXLarge]: "de:space-y-xxxl", + }, + [QUERIES.LARGEDESKTOP]: { + [SPACINGS.none]: "ld:space-y-none", + [SPACINGS.reverse]: "ld:space-y-reverse", + [SPACINGS.XXXSmall]: "ld:space-y-xxxs", + [SPACINGS.XXSmall]: "ld:space-y-xxs", + [SPACINGS.XSmall]: "ld:space-y-xs", + [SPACINGS.small]: "ld:space-y-sm", + [SPACINGS.medium]: "ld:space-y-md", + [SPACINGS.large]: "ld:space-y-lg", + [SPACINGS.XLarge]: "ld:space-y-xl", + [SPACINGS.XXLarge]: "ld:space-y-xxl", + [SPACINGS.XXXLarge]: "ld:space-y-xxxl", + }, +}; + +const getSpacingClasses = (spacing: Spacing, direction: Direction, viewport?: Devices): string => { + if (spacing === "none") return ""; + const horizontalRoot = viewport ? horizontalTokens[viewport] : horizontalTokens; + const verticalRoot = viewport ? verticalTokens[viewport] : verticalTokens; + + const tokens = cx( + (direction === "row" || direction === "row-reverse") && [ + horizontalRoot[spacing], + verticalRoot.none, + "rtl:space-x-reverse", + ], + direction === "row-reverse" && horizontalRoot.reverse, + (direction === "column" || direction === "column-reverse") && [ + verticalRoot[spacing], + horizontalRoot.none, + ], + direction === "column-reverse" && verticalRoot.reverse, + ); + + return tokens; +}; + +export default getSpacingClasses; diff --git a/packages/orbit-components/src/common/tailwind/textAlign.ts b/packages/orbit-components/src/common/tailwind/textAlign.ts index 71d3551a7e..cb738e2ec5 100644 --- a/packages/orbit-components/src/common/tailwind/textAlign.ts +++ b/packages/orbit-components/src/common/tailwind/textAlign.ts @@ -1,6 +1,6 @@ import { QUERIES } from "../../utils/mediaQuery/consts"; -enum ALIGN { +export enum TEXT_ALIGN { START = "start", CENTER = "center", END = "end", @@ -10,52 +10,52 @@ enum ALIGN { } export const textAlignClasses: { - [K in QUERIES | ALIGN]: K extends QUERIES ? Record : string; + [K in QUERIES | TEXT_ALIGN]: K extends QUERIES ? Record : string; } = { - [ALIGN.START]: "text-start", - [ALIGN.CENTER]: "text-center", - [ALIGN.END]: "text-end", - [ALIGN.JUSTIFY]: "text-justify", - [ALIGN.LEFT]: "text-left", - [ALIGN.RIGHT]: "text-right", + [TEXT_ALIGN.START]: "text-start", + [TEXT_ALIGN.CENTER]: "text-center", + [TEXT_ALIGN.END]: "text-end", + [TEXT_ALIGN.JUSTIFY]: "text-justify", + [TEXT_ALIGN.LEFT]: "text-left", + [TEXT_ALIGN.RIGHT]: "text-right", [QUERIES.MEDIUMMOBILE]: { - [ALIGN.START]: "mm:text-start", - [ALIGN.CENTER]: "mm:text-center", - [ALIGN.END]: "mm:text-end", - [ALIGN.JUSTIFY]: "mm:text-justify", - [ALIGN.LEFT]: "mm:text-left", - [ALIGN.RIGHT]: "mm:text-right", + [TEXT_ALIGN.START]: "mm:text-start", + [TEXT_ALIGN.CENTER]: "mm:text-center", + [TEXT_ALIGN.END]: "mm:text-end", + [TEXT_ALIGN.JUSTIFY]: "mm:text-justify", + [TEXT_ALIGN.LEFT]: "mm:text-left", + [TEXT_ALIGN.RIGHT]: "mm:text-right", }, [QUERIES.LARGEMOBILE]: { - [ALIGN.START]: "lm:text-start", - [ALIGN.CENTER]: "lm:text-center", - [ALIGN.END]: "lm:text-end", - [ALIGN.JUSTIFY]: "lm:text-justify", - [ALIGN.LEFT]: "lm:text-left", - [ALIGN.RIGHT]: "lm:text-right", + [TEXT_ALIGN.START]: "lm:text-start", + [TEXT_ALIGN.CENTER]: "lm:text-center", + [TEXT_ALIGN.END]: "lm:text-end", + [TEXT_ALIGN.JUSTIFY]: "lm:text-justify", + [TEXT_ALIGN.LEFT]: "lm:text-left", + [TEXT_ALIGN.RIGHT]: "lm:text-right", }, [QUERIES.TABLET]: { - [ALIGN.START]: "tb:text-start", - [ALIGN.CENTER]: "tb:text-center", - [ALIGN.END]: "tb:text-end", - [ALIGN.JUSTIFY]: "tb:text-justify", - [ALIGN.LEFT]: "tb:text-left", - [ALIGN.RIGHT]: "tb:text-right", + [TEXT_ALIGN.START]: "tb:text-start", + [TEXT_ALIGN.CENTER]: "tb:text-center", + [TEXT_ALIGN.END]: "tb:text-end", + [TEXT_ALIGN.JUSTIFY]: "tb:text-justify", + [TEXT_ALIGN.LEFT]: "tb:text-left", + [TEXT_ALIGN.RIGHT]: "tb:text-right", }, [QUERIES.DESKTOP]: { - [ALIGN.START]: "de:text-start", - [ALIGN.CENTER]: "de:text-center", - [ALIGN.END]: "de:text-end", - [ALIGN.JUSTIFY]: "de:text-justify", - [ALIGN.LEFT]: "de:text-left", - [ALIGN.RIGHT]: "de:text-right", + [TEXT_ALIGN.START]: "de:text-start", + [TEXT_ALIGN.CENTER]: "de:text-center", + [TEXT_ALIGN.END]: "de:text-end", + [TEXT_ALIGN.JUSTIFY]: "de:text-justify", + [TEXT_ALIGN.LEFT]: "de:text-left", + [TEXT_ALIGN.RIGHT]: "de:text-right", }, [QUERIES.LARGEDESKTOP]: { - [ALIGN.START]: "ld:text-start", - [ALIGN.CENTER]: "ld:text-center", - [ALIGN.END]: "ld:text-end", - [ALIGN.JUSTIFY]: "ld:text-justify", - [ALIGN.LEFT]: "ld:text-left", - [ALIGN.RIGHT]: "ld:text-right", + [TEXT_ALIGN.START]: "ld:text-start", + [TEXT_ALIGN.CENTER]: "ld:text-center", + [TEXT_ALIGN.END]: "ld:text-end", + [TEXT_ALIGN.JUSTIFY]: "ld:text-justify", + [TEXT_ALIGN.LEFT]: "ld:text-left", + [TEXT_ALIGN.RIGHT]: "ld:text-right", }, }; diff --git a/packages/orbit-components/src/common/tailwind/wrap.ts b/packages/orbit-components/src/common/tailwind/wrap.ts new file mode 100644 index 0000000000..beb3de0368 --- /dev/null +++ b/packages/orbit-components/src/common/tailwind/wrap.ts @@ -0,0 +1,42 @@ +import { QUERIES } from "../../utils/mediaQuery/consts"; +import type { Devices } from "../../utils/mediaQuery/types"; + +enum WRAP { + WRAP = "wrap", + NO_WRAP = "nowrap", +} + +export const wrapClasses: { + [K in QUERIES | WRAP]: K extends QUERIES ? Record : string; +} = { + [WRAP.WRAP]: "flex-wrap", + [WRAP.NO_WRAP]: "flex-nowrap", + [QUERIES.LARGEDESKTOP]: { + [WRAP.WRAP]: "ld:flex-wrap", + [WRAP.NO_WRAP]: "ld:flex-nowrap", + }, + [QUERIES.DESKTOP]: { + [WRAP.WRAP]: "de:flex-wrap", + [WRAP.NO_WRAP]: "de:flex-nowrap", + }, + [QUERIES.TABLET]: { + [WRAP.WRAP]: "tb:flex-wrap", + [WRAP.NO_WRAP]: "tb:flex-nowrap", + }, + [QUERIES.LARGEMOBILE]: { + [WRAP.WRAP]: "lm:flex-wrap", + [WRAP.NO_WRAP]: "lm:flex-nowrap", + }, + [QUERIES.MEDIUMMOBILE]: { + [WRAP.WRAP]: "mm:flex-wrap", + [WRAP.NO_WRAP]: "mm:flex-nowrap", + }, +}; + +const getWrapClasses = (wrap: boolean, viewport?: Devices) => { + const root = viewport ? wrapClasses[viewport] : wrapClasses; + + return wrap ? root.wrap : root.nowrap; +}; + +export default getWrapClasses;