Skip to content

Commit

Permalink
feat: remove mediaQueries
Browse files Browse the repository at this point in the history
This styled-components util function is now removed as we move away from Styled Components.

BREAKING CHANGE: mediaQueries function is no longer available.
This was a styled-components util function that is now no longer meant to be used.
Tokens and breakpoint values are still accessible.
  • Loading branch information
DSil committed Apr 4, 2024
1 parent a3637ae commit 8861191
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 153 deletions.
2 changes: 1 addition & 1 deletion packages/orbit-components/src/Hide/Hide.stories.tsx
Expand Up @@ -3,7 +3,7 @@ import { boolean } from "@storybook/addon-knobs";

import Separator from "../Separator";
import ChevronBackward from "../icons/ChevronBackward";
import type { Devices } from "../utils/mediaQuery/types";
import type { Devices } from "../utils/mediaQuery";

import Hide from ".";

Expand Down
2 changes: 1 addition & 1 deletion packages/orbit-components/src/index.ts
Expand Up @@ -117,7 +117,7 @@ export type { Theme } from "./defaultTheme";
export { fromPlainObject, getTokens } from "@kiwicom/orbit-design-tokens";

// utilities
export { default as mediaQueries } from "./utils/mediaQuery";
export { QUERIES, TOKEN, getBreakpointWidth } from "./utils/mediaQuery";
export { default as useMediaQuery } from "./hooks/useMediaQuery";
export { default as useTheme } from "./hooks/useTheme";
export { default as useLockScrolling } from "./hooks/useLockScrolling";
Expand Down
109 changes: 35 additions & 74 deletions packages/orbit-components/src/utils/mediaQuery/README.md
Expand Up @@ -2,50 +2,7 @@

The `orbit-components` package contains several media queries that are based on a mobile-first approach.

## Media query functions

By default, you should first define styles for mobile and then use queries for bigger devices.

The example below is a good start to implementing media query functions in a project using `styled-components`:

```jsx
import media from "@kiwicom/orbit-components/lib/utils/mediaQuery";
import styled, { css } from "styled-components";

const StyledComponent = styled.div`
width: 100%;
${media.desktop(css`
width: 50%;
`)};
`;
```

To use the component, combine it with your theme:

```jsx
import media from "@kiwicom/orbit-components/lib/utils/mediaQuery";
import styled, { css } from "styled-components";
import OrbitProvider from "@kiwicom/orbit-components/lib/OrbitProvider";
import defaultTheme from "@kiwicom/orbit-components/lib/defaultTheme";

const StyledComponent = styled.div`
width: 100%;
${media.desktop(css`
width: 50%;
`)};
`;
function App() {
return (
<OrbitProvider useId={React.useId} theme={defaultTheme}>
<StyledComponent>This div will be styled.</StyledComponent>
</OrbitProvider>
);
}
```

You can use the following media queries in your project:
The breakpoints are part of the theme and have the following values:

| Name | Applies from width |
| :----------- | :----------------- |
Expand All @@ -55,44 +12,48 @@ You can use the following media queries in your project:
| desktop | `992px` |
| largeDesktop | `1200px` |

## Breakpoints for testing purposes

To test your components with Enzyme, especially styles, you can also use the `getBreakpointWidth` function.
## Constants

Imagine that you have a component and want to test if it contains specific styles:
We export an enum `QUERIES` and an object `TOKEN` that can help with the usage of our tokens.

```jsx
const StyledComponent = styled.div`
width: 100%;
The `QUERIES` enum contains all the breakpoints.

${media.desktop(css`
width: 50%;
`)};
```ts
export enum QUERIES {
MEDIUMMOBILE = "mediumMobile",
LARGEMOBILE = "largeMobile",
TABLET = "tablet",
DESKTOP = "desktop",
LARGEDESKTOP = "largeDesktop",
}
```

In this case, you would need to `mount` this component and than check if it has specific styles with the `toHaveStyleRule` function from the [`jest-styled-components`](https://www.npmjs.com/package/jest-styled-components) package.
The `TOKEN` object contains the breakpoints as keys, associated with the corresponding name of the token as value.

The `getBreakpointWidth` function accepts the viewport name and a theme object. You can use it like this:
```ts
export const TOKEN = {
mediumMobile: "widthBreakpointMediumMobile",
largeMobile: "widthBreakpointLargeMobile",
tablet: "widthBreakpointTablet",
desktop: "widthBreakpointDesktop",
largeDesktop: "widthBreakpointLargeDesktop",
} as const;
```

```jsx
import * as React from "react";
import { render } from "@testing-library/react";
import theme from "@kiwicom/orbit-components/lib/defaultTheme";
import { getBreakpointWidth } from "@kiwicom/orbit-components/lib/utils/mediaQuery";
## getBreakpointWidth function

import StyledComponent from "./";
In case you need to access the value of the breakpoint (for testing purposes, for instance) you can use the `getBreakpointWidth` function.

describe("StyledComponent", () => {
it("should have 100% width by default", () => {
render(<StyledComponent data-test="test" />);
expect(screen.getByTestId("test")).toHaveStyleRule("width", "100%");
});
This function can also be used to return formatted strings useful for event listeners, for example.

it("should have a width of 50% on a desktop viewport", () => {
render(<StyledComponent data-test="test" />);
expect(screen.getByTestId("test")).toHaveStyleRule("width", "50%", {
media: getBreakpointWidth("desktop", theme),
});
});
});
```ts
getBreakpointWidth(breakpoint: keyof typeof TOKEN, theme: Theme, pure?: boolean) => string | number
```

### Arguments

| Name | Type | Description |
| :--------- | :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| breakpoint | `keyof typeof TOKEN` | The name of the breakpoint. |
| theme | `Theme` | The theme object. |
| pure | `boolean` | Optional. If `true`, the function will return the value as number. If false, it will return a string `"(min-width: ${VAL}px)"`, where `VAL` is the value of the breakpoint width. |
@@ -0,0 +1,40 @@
import Theme from "../../../defaultTheme";
import { getBreakpointWidth, QUERIES } from "..";

describe("getBreakpointWidth", () => {
const theme = Theme;

it("should return correct value as string for each query", () => {
expect(getBreakpointWidth(QUERIES.MEDIUMMOBILE, theme)).toBe(
`(min-width: ${theme.orbit.widthBreakpointMediumMobile}px)`,
);
expect(getBreakpointWidth(QUERIES.LARGEMOBILE, theme)).toBe(
`(min-width: ${theme.orbit.widthBreakpointLargeMobile}px)`,
);
expect(getBreakpointWidth(QUERIES.TABLET, theme)).toBe(
`(min-width: ${theme.orbit.widthBreakpointTablet}px)`,
);
expect(getBreakpointWidth(QUERIES.DESKTOP, theme)).toBe(
`(min-width: ${theme.orbit.widthBreakpointDesktop}px)`,
);
expect(getBreakpointWidth(QUERIES.LARGEDESKTOP, theme)).toBe(
`(min-width: ${theme.orbit.widthBreakpointLargeDesktop}px)`,
);
});

it("should return correct value for each query when pure is true", () => {
expect(getBreakpointWidth(QUERIES.MEDIUMMOBILE, theme, true)).toBe(
theme.orbit.widthBreakpointMediumMobile,
);
expect(getBreakpointWidth(QUERIES.LARGEMOBILE, theme, true)).toBe(
theme.orbit.widthBreakpointLargeMobile,
);
expect(getBreakpointWidth(QUERIES.TABLET, theme, true)).toBe(theme.orbit.widthBreakpointTablet);
expect(getBreakpointWidth(QUERIES.DESKTOP, theme, true)).toBe(
theme.orbit.widthBreakpointDesktop,
);
expect(getBreakpointWidth(QUERIES.LARGEDESKTOP, theme, true)).toBe(
theme.orbit.widthBreakpointLargeDesktop,
);
});
});

This file was deleted.

16 changes: 0 additions & 16 deletions packages/orbit-components/src/utils/mediaQuery/consts.ts

This file was deleted.

49 changes: 26 additions & 23 deletions packages/orbit-components/src/utils/mediaQuery/index.ts
@@ -1,36 +1,39 @@
import { css } from "styled-components";

import type { Theme } from "../../defaultTheme";
import { QUERIES } from "./consts";
import type { MediaQueries } from "./types";

export type Devices =
| "largeDesktop"
| "desktop"
| "tablet"
| "largeMobile"
| "mediumMobile"
| "smallMobile";

export enum QUERIES {
MEDIUMMOBILE = "mediumMobile",
LARGEMOBILE = "largeMobile",
TABLET = "tablet",
DESKTOP = "desktop",
LARGEDESKTOP = "largeDesktop",
}

export const TOKEN = {
mediumMobile: "widthBreakpointMediumMobile",
largeMobile: "widthBreakpointLargeMobile",
tablet: "widthBreakpointTablet",
desktop: "widthBreakpointDesktop",
largeDesktop: "widthBreakpointLargeDesktop",
};
} as const;

export const getBreakpointWidth = (
name: keyof typeof TOKEN,
export interface GetBreakpointWidth {
(name: keyof typeof TOKEN, theme: Theme): string;
(name: keyof typeof TOKEN, theme: Theme, pure: false): string;
(name: keyof typeof TOKEN, theme: Theme, pure: true): number;
}

export const getBreakpointWidth: GetBreakpointWidth = (
name: string,
theme: Theme,
pure?: boolean,
): string => {
) => {
return pure ? theme.orbit[TOKEN[name]] : `(min-width: ${theme.orbit[TOKEN[name]]}px)`;
};

const mediaQueries = Object.values(QUERIES).reduce<MediaQueries>(
(acc: MediaQueries, device: keyof typeof TOKEN) => {
acc[device] = style => css`
@media ${({ theme }) => getBreakpointWidth(device, theme)} {
${style};
}
`;

return acc;
},
{ mediumMobile: {}, largeMobile: {}, tablet: {}, desktop: {}, largeDesktop: {} } as MediaQueries,
);

export default mediaQueries;
24 changes: 0 additions & 24 deletions packages/orbit-components/src/utils/mediaQuery/types.d.ts

This file was deleted.

0 comments on commit 8861191

Please sign in to comment.