diff --git a/packages/orbit-components/cypress/integration/index.tsx b/packages/orbit-components/cypress/integration/index.tsx
index 0be043c4ce..479385547d 100644
--- a/packages/orbit-components/cypress/integration/index.tsx
+++ b/packages/orbit-components/cypress/integration/index.tsx
@@ -9,6 +9,7 @@ import MediaQueries from "./pages/media-queries";
import ModalFooter from "./pages/modal-footer";
import BoxMediaProps from "./pages/box-mediaquery-props";
import StackMediaProps from "./pages/stack-mediaquery-props";
+import TextStyles from "./pages/text-styles";
const router = createRouter({
lockScrolling: "/lock-scrolling",
@@ -16,6 +17,7 @@ const router = createRouter({
modalFooter: "/modal-footer",
boxMediaProps: "/box-media-props",
stackMediaProps: "/stack-media-props",
+ textStyles: "/text-styles",
});
function PageNotFound() {
@@ -68,6 +70,12 @@ function App() {
);
+ case "textStyles":
+ return (
+
+
+
+ );
default:
return ;
}
diff --git a/packages/orbit-components/cypress/integration/pages/text-styles.test.ts b/packages/orbit-components/cypress/integration/pages/text-styles.test.ts
new file mode 100644
index 0000000000..6f7ddeb005
--- /dev/null
+++ b/packages/orbit-components/cypress/integration/pages/text-styles.test.ts
@@ -0,0 +1,185 @@
+import { defaultFoundation } from "@kiwicom/orbit-design-tokens";
+import color from "onecolor";
+
+const rgbaRegex = /rgb\((.{1,3}),(.{1,3}),(.{1,3})\)/;
+const formatAlpha = (alpha: string) => (_, p1: string, p2: string, p3: string) =>
+ `rgba(${p1}, ${p2}, ${p3}, ${alpha})`;
+
+describe("Text colors", () => {
+ it("should have correct colors", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("Primary").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.ink.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Secondary").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.ink.normal).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Info").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.blue.normal).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Success").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.green.normal).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Warning").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.orange.normal).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Critical").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.red.normal).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("White").should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.white.normal).css().replaceAll(",", ", "),
+ );
+ });
+
+ it("should have correct background colors", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("Primary").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.ink.dark).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("Secondary").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.ink.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("Info").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.blue.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("Success").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.green.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("Warning").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.orange.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("Critical").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.red.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+
+ cy.findByText("White").should(
+ "have.css",
+ "background-color",
+ color(defaultFoundation.palette.white.normal).css().replace(rgbaRegex, formatAlpha("0.1")),
+ );
+ });
+});
+
+describe("Text with margins", () => {
+ it("should have correct margins from object", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("Object margin").should("have.css", "margin", "2px 4px 0px -1px");
+ });
+
+ it("should have correct margins from string", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("String margin").should("have.css", "margin", "0px 1px -2px 0px");
+ });
+});
+
+describe("Links inside Text", () => {
+ it("should have correct common styles", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("Primary")
+ .get("a")
+ .should("have.css", "font-weight", defaultFoundation.fontWeight.medium)
+ .should("have.css", "text-decoration-line", "underline");
+ });
+
+ it("should have correct colors", () => {
+ cy.visit("/text-styles");
+
+ cy.findByText("Primary")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.product.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Secondary")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.ink.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Info")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.blue.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Success")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.green.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Warning")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.orange.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("Critical")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.red.dark).css().replaceAll(",", ", "),
+ );
+
+ cy.findByText("White")
+ .find("a")
+ .should(
+ "have.css",
+ "color",
+ color(defaultFoundation.palette.white.normal).css().replaceAll(",", ", "),
+ );
+ });
+});
diff --git a/packages/orbit-components/cypress/integration/pages/text-styles.tsx b/packages/orbit-components/cypress/integration/pages/text-styles.tsx
new file mode 100644
index 0000000000..aae78e7eb6
--- /dev/null
+++ b/packages/orbit-components/cypress/integration/pages/text-styles.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import { Text } from "@kiwicom/orbit-components";
+
+export default function TextStyles() {
+ return (
+ <>
+
+ Primary link
+
+
+ Secondary link
+
+
+ Info link
+
+
+ Success link
+
+
+ Warning link
+
+
+ Critical link
+
+
+ White link
+
+ Object margin
+ String margin
+ >
+ );
+}
diff --git a/packages/orbit-components/src/Text/__tests__/index.test.tsx b/packages/orbit-components/src/Text/__tests__/index.test.tsx
index 9780e7ab87..6b6be421cf 100644
--- a/packages/orbit-components/src/Text/__tests__/index.test.tsx
+++ b/packages/orbit-components/src/Text/__tests__/index.test.tsx
@@ -1,59 +1,145 @@
import * as React from "react";
import { screen, render } from "../../test-utils";
+import theme from "../../defaultTheme";
+import { TEXT_ALIGN } from "../../common/tailwind/textAlign";
+import type { Props } from "../types";
+import type { SIZE_OPTIONS, WEIGHT_OPTIONS } from "../consts";
import Text from "..";
-import { SIZE_OPTIONS, TYPE_OPTIONS } from "../consts";
-import defaultTheme from "../../defaultTheme";
+
+const SIZE_STYLES: { [K in SIZE_OPTIONS]: Record<"font-size" | "line-height", string> } = {
+ small: {
+ "font-size": theme.orbit.fontSizeTextSmall,
+ "line-height": theme.orbit.lineHeightTextSmall,
+ },
+ normal: {
+ "font-size": theme.orbit.fontSizeTextNormal,
+ "line-height": theme.orbit.lineHeightTextNormal,
+ },
+ large: {
+ "font-size": theme.orbit.fontSizeTextLarge,
+ "line-height": theme.orbit.lineHeightTextLarge,
+ },
+ extraLarge: {
+ "font-size": theme.orbit.fontSizeTextExtraLarge,
+ "line-height": theme.orbit.lineHeightTextExtraLarge,
+ },
+};
+
+const WEIGHT_STYLES: { [K in WEIGHT_OPTIONS]: Record<"font-weight", string> } = {
+ normal: {
+ "font-weight": theme.orbit.fontWeightNormal,
+ },
+ bold: {
+ "font-weight": theme.orbit.fontWeightBold,
+ },
+ medium: {
+ "font-weight": theme.orbit.fontWeightMedium,
+ },
+};
describe("Text", () => {
- it("should have expected DOM output", () => {
- const dataTest = "test";
- const text = "Children text";
- const type = TYPE_OPTIONS.PRIMARY;
- const size = SIZE_OPTIONS.SMALL;
- const id = "id";
+ const dataTest = "test";
+ const text = "Children text";
+ const id = "id";
+ it("should have expected DOM output", () => {
render(
-
+
{text}
,
);
- expect(screen.getByTestId(dataTest)).toHaveAttribute("id", id);
- expect(screen.getByTestId(dataTest)).toBeInTheDocument();
+ const textElement = screen.getByTestId(dataTest);
+
+ expect(textElement.tagName).toBe("P");
+ expect(textElement).toHaveAttribute("id", id);
+ expect(textElement).toBeInTheDocument();
expect(screen.getByText(text)).toBeInTheDocument();
+ expect(textElement).toHaveStyle({
+ margin: 0,
+ "font-family": theme.orbit.fontFamily,
+ "font-size": theme.orbit.fontSizeTextNormal,
+ "line-height": theme.orbit.lineHeightTextNormal,
+ "text-align": "left",
+ });
+ });
+
+ it.each(Object.keys(SIZE_STYLES))("should have size %s", size => {
+ render(
+
+ {text}
+ ,
+ );
+
+ expect(screen.getByTestId(dataTest)).toHaveStyle(SIZE_STYLES[size]);
+ });
+
+ it.each(Object.keys(WEIGHT_STYLES))("should have weight %s", weight => {
+ render(
+
+ {text}
+ ,
+ );
+
+ expect(screen.getByTestId(dataTest)).toHaveStyle(WEIGHT_STYLES[weight]);
+ });
+
+ it.each(Object.values(TEXT_ALIGN))("should have align %s", align => {
+ render(
+
+ {text}
+ ,
+ );
+
expect(screen.getByTestId(dataTest)).toHaveStyle({
- fontSize: defaultTheme.orbit.fontSizeTextSmall,
- color: defaultTheme.orbit.colorTextPrimary,
- marginBottom: defaultTheme.orbit.spaceSmall,
+ "text-align": align,
});
});
- it("should have object margin", () => {
- const dataTest = "test";
+ it("should render according to the passed `as` prop", () => {
+ render(
+
+ {text}
+ ,
+ );
+
+ expect(screen.getByTestId(dataTest).tagName).toBe("DIV");
+ });
+ it("should render uppercase", () => {
render(
-
- Chuck Norris can divide by zero.
+
+ {text}
,
);
expect(screen.getByTestId(dataTest)).toHaveStyle({
- marginBottom: "0",
+ "text-transform": "uppercase",
});
});
- it("should have string margin", () => {
- const dataTest = "test";
+ it("should render italic", () => {
+ render(
+
+ {text}
+ ,
+ );
+
+ expect(screen.getByTestId(dataTest)).toHaveStyle({
+ "font-style": "italic",
+ });
+ });
+ it("should render strikethrough", () => {
render(
-
- Chuck Norris can divide by zero.
+
+ {text}
,
);
expect(screen.getByTestId(dataTest)).toHaveStyle({
- marginRight: "12px",
+ "text-decoration-line": "line-through",
});
});
});
diff --git a/packages/orbit-components/src/Text/deprecated/index.tsx b/packages/orbit-components/src/Text/deprecated/index.tsx
new file mode 100644
index 0000000000..ca27994401
--- /dev/null
+++ b/packages/orbit-components/src/Text/deprecated/index.tsx
@@ -0,0 +1,117 @@
+import * as React from "react";
+import styled, { css } from "styled-components";
+import { convertHexToRgba } from "@kiwicom/orbit-design-tokens";
+
+import type * as Common from "../../common/types";
+import type { Theme } from "../../defaultTheme";
+import defaultTheme from "../../defaultTheme";
+import { TYPE_OPTIONS, WEIGHT_OPTIONS, ELEMENT_OPTIONS, SIZE_OPTIONS } from "../consts";
+import { textAlign } from "../../utils/rtl";
+import { getLinkStyle } from "../../TextLink/deprecated";
+import { spacingUtility } from "../../utils/common";
+import type { Type, Weight } from "../types";
+
+const getTypeToken = ({ theme, type }: { theme: Theme; type: Type }): string => {
+ const typeTokens = {
+ [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextPrimary,
+ [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextSecondary,
+ [TYPE_OPTIONS.INFO]: theme.orbit.colorTextInfo,
+ [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextSuccess,
+ [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextWarning,
+ [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextCritical,
+ [TYPE_OPTIONS.WHITE]: theme.orbit.colorTextWhite,
+ };
+
+ return typeTokens[type];
+};
+
+const getWeightToken = ({ theme, weight }: { theme: Theme; weight: Weight }): string | null => {
+ const weightTokens = {
+ [WEIGHT_OPTIONS.NORMAL]: theme.orbit.fontWeightNormal,
+ [WEIGHT_OPTIONS.MEDIUM]: theme.orbit.fontWeightMedium,
+ [WEIGHT_OPTIONS.BOLD]: theme.orbit.fontWeightBold,
+ };
+
+ if (!weight) return null;
+
+ return weightTokens[weight];
+};
+
+const getSizeToken = ({ theme, size }: { theme: Theme; size: Common.Size }): string | null => {
+ const sizeTokens = {
+ [SIZE_OPTIONS.EXTRA_LARGE]: theme.orbit.fontSizeTextExtraLarge,
+ [SIZE_OPTIONS.LARGE]: theme.orbit.fontSizeTextLarge,
+ [SIZE_OPTIONS.NORMAL]: theme.orbit.fontSizeTextNormal,
+ [SIZE_OPTIONS.SMALL]: theme.orbit.fontSizeTextSmall,
+ };
+
+ if (!size) return null;
+
+ return sizeTokens[size];
+};
+
+const getLineHeightToken = ({
+ theme,
+ size,
+}: {
+ theme: Theme;
+ size?: Common.Size | null;
+}): string | null => {
+ const lineHeightTokens = {
+ [SIZE_OPTIONS.EXTRA_LARGE]: theme.orbit.lineHeightTextExtraLarge,
+ [SIZE_OPTIONS.LARGE]: theme.orbit.lineHeightTextLarge,
+ [SIZE_OPTIONS.NORMAL]: theme.orbit.lineHeightTextNormal,
+ [SIZE_OPTIONS.SMALL]: theme.orbit.lineHeightTextSmall,
+ };
+
+ if (!size) return null;
+
+ return lineHeightTokens[size];
+};
+
+/**
+ * @deprecated use .orbit-text selector instead
+ */
+export const StyledText = styled(
+ ({ element: TextElement = ELEMENT_OPTIONS.P, children, className, dataTest, id }) => (
+
+ {children}
+
+ ),
+)`
+ ${({
+ theme,
+ align,
+ uppercase,
+ size,
+ weight,
+ strikeThrough,
+ $type,
+ italic,
+ withBackground,
+ margin,
+ }) => css`
+ font-family: ${theme.orbit.fontFamily};
+ background: ${withBackground && convertHexToRgba(getTypeToken({ theme, type: $type }), 10)};
+ font-size: ${getSizeToken({ theme, size })};
+ font-weight: ${getWeightToken({ theme, weight })};
+ color: ${getTypeToken({ theme, type: $type })};
+ line-height: ${getLineHeightToken({ theme, size })};
+ text-align: ${textAlign(align)};
+ text-transform: ${uppercase && `uppercase`};
+ text-decoration: ${strikeThrough && `line-through`};
+ font-style: ${italic && `italic`};
+ margin: 0;
+ ${spacingUtility(margin)};
+
+ a:not(.orbit-text-link) {
+ ${getLinkStyle({ theme, $type })};
+ }
+ `}
+`;
+
+StyledText.defaultProps = {
+ theme: defaultTheme,
+};
+
+export default StyledText;
diff --git a/packages/orbit-components/src/Text/helpers/getMargin.ts b/packages/orbit-components/src/Text/helpers/getMargin.ts
new file mode 100644
index 0000000000..695c8605d9
--- /dev/null
+++ b/packages/orbit-components/src/Text/helpers/getMargin.ts
@@ -0,0 +1,37 @@
+import type { Props } from "../types";
+
+const getMarginValue = (margin: string | number): string =>
+ typeof margin === "number" ? `${margin}px` : margin;
+
+const getMargin = (margin: Props["margin"]): { vars: object; classes: string[] } => {
+ if (typeof margin === "number" || typeof margin === "string")
+ return {
+ vars: { "--text-margin": getMarginValue(margin) },
+ classes: ["m-[var(--text-margin)]"],
+ };
+
+ const { top, bottom, left, right } = margin || {};
+ const cssVar = {};
+ const marginClasses: string[] = ["m-0"];
+
+ if (top) {
+ marginClasses.push("mt-[var(--text-margin-top)]");
+ cssVar["--text-margin-top"] = getMarginValue(top);
+ }
+ if (bottom) {
+ marginClasses.push("mb-[var(--text-margin-bottom)]");
+ cssVar["--text-margin-bottom"] = getMarginValue(bottom);
+ }
+ if (left) {
+ marginClasses.push("ml-[var(--text-margin-left)]");
+ cssVar["--text-margin-left"] = getMarginValue(left);
+ }
+ if (right) {
+ marginClasses.push("mr-[var(--text-margin-right)]");
+ cssVar["--text-margin-right"] = getMarginValue(right);
+ }
+
+ return { vars: cssVar, classes: marginClasses };
+};
+
+export default getMargin;
diff --git a/packages/orbit-components/src/Text/helpers/twClasses.ts b/packages/orbit-components/src/Text/helpers/twClasses.ts
new file mode 100644
index 0000000000..185aeb7e7a
--- /dev/null
+++ b/packages/orbit-components/src/Text/helpers/twClasses.ts
@@ -0,0 +1,50 @@
+import { SIZE_OPTIONS, TYPE_OPTIONS, WEIGHT_OPTIONS } from "../consts";
+
+export const typeClasses: Record = {
+ [TYPE_OPTIONS.PRIMARY]:
+ "text-primary-foreground [&_a:not(.orbit-text-link)]:text-link-primary-foreground hover:[&_a:not(.orbit-text-link)]:text-link-primary-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-primary-foreground-active",
+ [TYPE_OPTIONS.SECONDARY]:
+ "text-secondary-foreground [&_a:not(.orbit-text-link)]:text-link-secondary-foreground hover:[&_a:not(.orbit-text-link)]:text-link-secondary-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-secondary-foreground-active",
+ [TYPE_OPTIONS.SUCCESS]:
+ "text-success-foreground [&_a:not(.orbit-text-link)]:text-link-success-foreground hover:[&_a:not(.orbit-text-link)]:text-link-success-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-success-foreground-active",
+ [TYPE_OPTIONS.INFO]:
+ "text-info-foreground [&_a:not(.orbit-text-link)]:text-link-info-foreground hover:[&_a:not(.orbit-text-link)]:text-link-info-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-info-foreground-active",
+ [TYPE_OPTIONS.WARNING]:
+ "text-warning-foreground [&_a:not(.orbit-text-link)]:text-link-warning-foreground hover:[&_a:not(.orbit-text-link)]:text-link-warning-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-warning-foreground-active",
+ [TYPE_OPTIONS.CRITICAL]:
+ "text-critical-foreground [&_a:not(.orbit-text-link)]:text-link-critical-foreground hover:[&_a:not(.orbit-text-link)]:text-link-critical-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-critical-foreground-active",
+ [TYPE_OPTIONS.WHITE]:
+ "text-white-foreground [&_a:not(.orbit-text-link)]:text-link-white-foreground hover:[&_a:not(.orbit-text-link)]:text-link-white-foreground-hover active:[&_a:not(.orbit-text-link)]:text-link-white-foreground-active",
+};
+
+export const backgroundClasses: Record = {
+ [TYPE_OPTIONS.PRIMARY]: "bg-text-primary-background",
+ [TYPE_OPTIONS.SECONDARY]: "bg-text-secondary-background",
+ [TYPE_OPTIONS.INFO]: "bg-text-info-background",
+ [TYPE_OPTIONS.SUCCESS]: "bg-text-success-background",
+ [TYPE_OPTIONS.WARNING]: "bg-text-warning-background",
+ [TYPE_OPTIONS.CRITICAL]: "bg-text-critical-background",
+ [TYPE_OPTIONS.WHITE]: "bg-text-white-background",
+};
+
+export const sizeClasses: Record = {
+ [SIZE_OPTIONS.SMALL]: "text-small leading-small",
+ [SIZE_OPTIONS.NORMAL]: "text-normal leading-normal",
+ [SIZE_OPTIONS.LARGE]: "text-large leading-large",
+ [SIZE_OPTIONS.EXTRA_LARGE]: "text-extra-large leading-extra-large",
+};
+
+export const weightClasses: Record = {
+ [WEIGHT_OPTIONS.NORMAL]: "font-normal",
+ [WEIGHT_OPTIONS.MEDIUM]: "font-medium",
+ [WEIGHT_OPTIONS.BOLD]: "font-bold",
+};
+
+export const textLinkCommonClasses = [
+ "[&_a:not(.orbit-text-link)]:font-medium",
+ "[&_a:not(.orbit-text-link)]:underline",
+ "hover:[&_a:not(.orbit-text-link)]:no-underline",
+ "active:[&_a:not(.orbit-text-link)]:no-underline",
+ "hover:[&_a:not(.orbit-text-link)]:outline-none",
+ "active:[&_a:not(.orbit-text-link)]:outline-none",
+];
diff --git a/packages/orbit-components/src/Text/index.js.flow b/packages/orbit-components/src/Text/index.js.flow
index 23576b0ae8..f3f9be0b70 100644
--- a/packages/orbit-components/src/Text/index.js.flow
+++ b/packages/orbit-components/src/Text/index.js.flow
@@ -3,7 +3,6 @@
DOCUMENTATION: https://orbit.kiwi/components/text/
*/
import * as React from "react";
-import type { StyledComponent } from "styled-components";
import type { spaceAfter } from "../common/getSpacingToken/index.js.flow";
import type { Globals, ObjectProperty } from "../common/common.js.flow";
@@ -32,5 +31,3 @@ export type Props = {|
|};
declare export default React.ComponentType;
-
-declare export var StyledText: StyledComponent;
diff --git a/packages/orbit-components/src/Text/index.tsx b/packages/orbit-components/src/Text/index.tsx
index df075d4de0..b7a847bd52 100644
--- a/packages/orbit-components/src/Text/index.tsx
+++ b/packages/orbit-components/src/Text/index.tsx
@@ -1,12 +1,8 @@
"use client";
import * as React from "react";
-import styled, { css } from "styled-components";
-import { convertHexToRgba } from "@kiwicom/orbit-design-tokens";
+import cx from "clsx";
-import type * as Common from "../common/types";
-import type { Theme } from "../defaultTheme";
-import defaultTheme from "../defaultTheme";
import {
TYPE_OPTIONS,
WEIGHT_OPTIONS,
@@ -14,112 +10,17 @@ import {
ALIGN_OPTIONS,
SIZE_OPTIONS,
} from "./consts";
-import getSpacingToken from "../common/getSpacingToken";
-import { textAlign } from "../utils/rtl";
-import { getLinkStyle, StyledTextLink } from "../TextLink";
-import { spacingUtility } from "../utils/common";
-import useTheme from "../hooks/useTheme";
-import type { Props, Type, Weight } from "./types";
-
-const getTypeToken = ({ theme, type }: { theme: Theme; type: Type }): string => {
- const typeTokens = {
- [TYPE_OPTIONS.PRIMARY]: theme.orbit.colorTextPrimary,
- [TYPE_OPTIONS.SECONDARY]: theme.orbit.colorTextSecondary,
- [TYPE_OPTIONS.INFO]: theme.orbit.colorTextInfo,
- [TYPE_OPTIONS.SUCCESS]: theme.orbit.colorTextSuccess,
- [TYPE_OPTIONS.WARNING]: theme.orbit.colorTextWarning,
- [TYPE_OPTIONS.CRITICAL]: theme.orbit.colorTextCritical,
- [TYPE_OPTIONS.WHITE]: theme.orbit.colorTextWhite,
- };
-
- return typeTokens[type];
-};
-
-const getWeightToken = ({ theme, weight }: { theme: Theme; weight: Weight }): string | null => {
- const weightTokens = {
- [WEIGHT_OPTIONS.NORMAL]: theme.orbit.fontWeightNormal,
- [WEIGHT_OPTIONS.MEDIUM]: theme.orbit.fontWeightMedium,
- [WEIGHT_OPTIONS.BOLD]: theme.orbit.fontWeightBold,
- };
-
- if (!weight) return null;
-
- return weightTokens[weight];
-};
-
-const getSizeToken = ({ theme, size }: { theme: Theme; size: Common.Size }): string | null => {
- const sizeTokens = {
- [SIZE_OPTIONS.EXTRA_LARGE]: theme.orbit.fontSizeTextExtraLarge,
- [SIZE_OPTIONS.LARGE]: theme.orbit.fontSizeTextLarge,
- [SIZE_OPTIONS.NORMAL]: theme.orbit.fontSizeTextNormal,
- [SIZE_OPTIONS.SMALL]: theme.orbit.fontSizeTextSmall,
- };
-
- if (!size) return null;
-
- return sizeTokens[size];
-};
-
-const getLineHeightToken = ({
- theme,
- size,
-}: {
- theme: Theme;
- size?: Common.Size | null;
-}): string | null => {
- const lineHeightTokens = {
- [SIZE_OPTIONS.EXTRA_LARGE]: theme.orbit.lineHeightTextExtraLarge,
- [SIZE_OPTIONS.LARGE]: theme.orbit.lineHeightTextLarge,
- [SIZE_OPTIONS.NORMAL]: theme.orbit.lineHeightTextNormal,
- [SIZE_OPTIONS.SMALL]: theme.orbit.lineHeightTextSmall,
- };
-
- if (!size) return null;
-
- return lineHeightTokens[size];
-};
-
-export const StyledText = styled(
- ({ element: TextElement = ELEMENT_OPTIONS.P, children, className, dataTest, id }) => (
-
- {children}
-
- ),
-)`
- ${({
- theme,
- align,
- uppercase,
- size,
- weight,
- strikeThrough,
- $type,
- italic,
- withBackground,
- margin,
- }) => css`
- font-family: ${theme.orbit.fontFamily};
- background: ${withBackground && convertHexToRgba(getTypeToken({ theme, type: $type }), 10)};
- font-size: ${getSizeToken({ theme, size })};
- font-weight: ${getWeightToken({ theme, weight })};
- color: ${getTypeToken({ theme, type: $type })};
- line-height: ${getLineHeightToken({ theme, size })};
- text-align: ${textAlign(align)};
- text-transform: ${uppercase && `uppercase`};
- text-decoration: ${strikeThrough && `line-through`};
- font-style: ${italic && `italic`};
- margin: 0;
- ${spacingUtility(margin)};
-
- a:not(${StyledTextLink}) {
- ${getLinkStyle({ theme, $type })};
- }
- `}
-`;
-
-StyledText.defaultProps = {
- theme: defaultTheme,
-};
+import type { Props } from "./types";
+import { spaceAfterClasses } from "../common/tailwind/spaceAfter";
+import {
+ backgroundClasses,
+ sizeClasses,
+ textLinkCommonClasses,
+ typeClasses,
+ weightClasses,
+} from "./helpers/twClasses";
+import { textAlignClasses } from "../common/tailwind/textAlign";
+import getMargin from "./helpers/getMargin";
const Text = ({
type = TYPE_OPTIONS.PRIMARY,
@@ -127,7 +28,7 @@ const Text = ({
weight = WEIGHT_OPTIONS.NORMAL,
align = ALIGN_OPTIONS.LEFT,
margin,
- as = ELEMENT_OPTIONS.P,
+ as: Component = ELEMENT_OPTIONS.P,
uppercase,
italic,
strikeThrough,
@@ -137,26 +38,30 @@ const Text = ({
withBackground,
id,
}: Props) => {
- const theme = useTheme();
+ const { vars: cssVar, classes: marginClasses } = getMargin(margin);
return (
-
{children}
-
+
);
};