Skip to content

Commit

Permalink
feat: simplify resolving breakpoint input
Browse files Browse the repository at this point in the history
Signed-off-by: Griko Nibras <git@griko.id>
  • Loading branch information
Griko Nibras committed Nov 22, 2021
1 parent 06be6a0 commit 5a3daa7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 10 deletions.
56 changes: 52 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Custom hooks to use Tailwind CSS breakpoints for React 🎐🔨

- [Installing](#installing)
- [Usage](#usage)
- [Option #1: Resolve directly from `tailwind.config.js`](#option-1-resolve-directly-from-tailwindconfigjs)
- [Option #2: Only pass breakpoint values](#option-2-only-pass-breakpoint-values)
- [Available hooks](#available-hooks)
- [`useBreakpoint()`](#usebreakpoint)
- [`useBreakpointEffect()`](#usebreakpointeffect)
Expand All @@ -36,13 +38,59 @@ yarn add @kodingdotninja/use-tailwind-breakpoint

## Usage

[Similar to `pmndrs/zustand`'s `create` API](https://github.com/pmndrs/zustand/#first-create-a-store), create the breakpoint hooks by resolving your `tailwind.config.js`:
### Option #1: Resolve directly from `tailwind.config.js`

[Similar to `pmndrs/zustand`'s `create` API](https://github.com/pmndrs/zustand/#first-create-a-store), initialize the breakpoint hooks by passing the `tailwind.config.js` which will be resolved internally using [`resolveConfig`](https://github.com/tailwindlabs/tailwindcss/blob/master/src/util/resolveConfig.js):

```ts
// /hooks/tailwind.ts

import create from "@kodingdotninja/use-tailwind-breakpoint";

import tailwindConfig from "path/to/tailwind.config.js";

export const { useBreakpoint } = create(tailwindConfig);
```

> ⚠️ This possibly imports all `tailwind.config.js` values. Make sure to check the client bundle size.
### Option #2: Only pass breakpoint values

Extract the [`screens`](https://tailwindcss.com/docs/breakpoints) values into a separate file:

```js
// tailwind.screens.js or other name to separate breakpoint values
const screens = {
sm: "640px",
md: "768px",
// ...
};
```

To keep the same values, `require` inside `tailwind.config.js`:

```js
// tailwind.config.js
module.exports = {
theme: {
extend: {
screens: require("path/to/tailwind.screens.js"),
},
},
// ...
};
```

Then pass the extracted `screens` to the `create` function:

```ts
// /hooks/tailwind.ts

import create from "@kodingdotninja/use-tailwind-breakpoint";
import tailwindConfig from "path/to/tailwind.config";

export const { useBreakpoint, ... } = create(tailwindConfig);
import tailwindScreens from "path/to/tailwind.screens.js";

export const { useBreakpoint } = create(screens);
```

## Available hooks
Expand All @@ -52,7 +100,7 @@ export const { useBreakpoint, ... } = create(tailwindConfig);
Use breakpoint value from given breakpoint token

```jsx
import { useBreakpoint } from "@kodingdotninja/use-tailwind-breakpoint";
import { useBreakpoint } from "./lib/";

function App() {
const isDesktop = useBreakpoint("md");
Expand Down
13 changes: 7 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { TailwindConfig } from "tailwindcss/tailwind-config";

export * from "./utils";

export type Breakpoints = { readonly [breakpoint: string]: string };

export type CreatorReturnType = {
/**
* Use breakpoint value from given breakpoint token
Expand Down Expand Up @@ -75,7 +77,7 @@ export type CreatorReturnType = {
*
* ---
*
* @param configFile Tailwind CSS configuration file (`tailwind.config.js`)
* @param configOrScreens Tailwind CSS configuration file (`tailwind.config.js`)
*
* @returns Breakpoint hooks
*
Expand All @@ -90,19 +92,18 @@ export type CreatorReturnType = {
* export const { useBreakpoint, useBreakpointEffect, useBreakpointValue, ... } = create(tailwindConfig);
* ```
*/
export function create<Config extends TailwindConfig>(configFile: Config) {
const config = resolveConfig(configFile);
export function create<ConfigOrScreens extends TailwindConfig | Breakpoints>(configOrScreens: ConfigOrScreens) {
const screens = (resolveConfig(configOrScreens as TailwindConfig).theme.screens ?? configOrScreens) as Breakpoints;

function useBreakpoint<Breakpoint>(breakpoint: Breakpoint, defaultValue: boolean = false) {
function useBreakpoint(breakpoint: string, defaultValue: boolean = false) {
const [match, setMatch] = React.useState(() => defaultValue);
const matchRef = React.useRef(defaultValue);

useIsomorphicEffect(() => {
if (!(isBrowser && "matchMedia" in window)) return undefined;

function track() {
// @ts-expect-error tsconfig.compilerOptions.strict prevents accessing index with unknown value type
const value = (config.theme.screens?.[breakpoint] as string) ?? "999999px";
const value = screens?.[breakpoint] ?? "999999px";
const query = window.matchMedia(`(min-width: ${value})`);
matchRef.current = query.matches;
if (matchRef.current != match) {
Expand Down

0 comments on commit 5a3daa7

Please sign in to comment.