react-resize-detector-context 0.1.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,11 +1,23 @@
1
1
  # ⚛️ React Resize Detector Context
2
2
 
3
+
3
4
  ![Demo GIF](/doc/assets/demo.gif)
4
5
 
6
+
7
+
5
8
  A lightweight React context that leverages [react-resize-detector](https://github.com/maslianok/react-resize-detector) to dynamically detect the
6
9
  current breakpoint based on an element's width. It provides utility functions and helper components to conditionally render content based on
7
10
  responsive breakpoints – all fully typed in TypeScript for excellent IDE support. 😎
8
11
 
12
+ [![npm version](https://img.shields.io/npm/v/react-resize-detector-context.svg)](https://www.npmjs.com/package/react-resize-detector-context)
13
+ [![npm downloads](https://img.shields.io/npm/dm/react-resize-detector-context.svg)](https://www.npmjs.com/package/react-resize-detector-context)
14
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-resize-detector-context)](https://bundlephobia.com/package/react-resize-detector-context)
15
+ [![codecov](https://codecov.io/gh/smartlabsat/react-resize-detector-context/branch/main/graph/badge.svg)](https://codecov.io/gh/smartlabsat/react-resize-detector-context)
16
+ [![CI](https://github.com/smartlabsat/react-resize-detector-context/actions/workflows/ci.yml/badge.svg)](https://github.com/smartlabsat/react-resize-detector-context/actions/workflows/ci.yml)
17
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
18
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
19
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
20
+
9
21
  ---
10
22
 
11
23
  ## Table of Contents 📚
@@ -23,6 +35,8 @@ responsive breakpoints – all fully typed in TypeScript for excellent IDE suppo
23
35
  - [useBreakpoint Hook](#usebreakpoint-hook)
24
36
  - [Available Scripts](#available-scripts)
25
37
  - [Contribution Guidelines](#contribution-guidelines)
38
+ - [Roadmap](#roadmap)
39
+ - [Changelog](#changelog)
26
40
  - [License](#license)
27
41
 
28
42
  ---
@@ -67,7 +81,7 @@ values.
67
81
 
68
82
  ```typescript
69
83
  import React from 'react';
70
- import { BreakpointProvider, useBreakpoint } from 'my-breakpoint-package';
84
+ import { BreakpointProvider, useBreakpoint } from 'react-resize-detector-context';
71
85
 
72
86
  const breakpoints = {
73
87
  XS: 0,
@@ -114,7 +128,7 @@ Render content only when specific breakpoint conditions are met.
114
128
 
115
129
  ```typescript
116
130
  import React from 'react';
117
- import { BreakpointProvider, BreakpointConditional } from 'my-breakpoint-package';
131
+ import { BreakpointProvider, BreakpointConditional } from 'react-resize-detector-context';
118
132
 
119
133
  const breakpoints = {
120
134
  XS: 0,
@@ -152,7 +166,7 @@ Define your own custom breakpoints – for example, using car sizes:
152
166
 
153
167
  ```typescript
154
168
  import React from 'react';
155
- import { BreakpointProvider, useBreakpoint } from 'my-breakpoint-package';
169
+ import { BreakpointProvider, useBreakpoint } from 'react-resize-detector-context';
156
170
 
157
171
  const carBreakpoints = {
158
172
  Smart: 0,
@@ -243,7 +257,7 @@ The `useBreakpoint` hook provides access to the responsive context. It returns a
243
257
 
244
258
  ```typescript
245
259
  import React from 'react';
246
- import { BreakpointProvider, useBreakpoint } from 'my-breakpoint-package';
260
+ import { BreakpointProvider, useBreakpoint } from 'react-resize-detector-context';
247
261
 
248
262
  const breakpoints = {
249
263
  XS: 0,
@@ -340,6 +354,18 @@ Let's build something awesome together! 🚀✨
340
354
 
341
355
  ---
342
356
 
357
+ ## Roadmap
358
+
359
+ Check out our [ROADMAP.md](./ROADMAP.md) to see what features are planned for future releases!
360
+
361
+ ---
362
+
363
+ ## Changelog
364
+
365
+ See [CHANGELOG.md](./CHANGELOG.md) for a list of changes.
366
+
367
+ ---
368
+
343
369
  ## License
344
370
 
345
371
  This project is licensed under the MIT License.
package/dist/index.d.mts CHANGED
@@ -40,6 +40,11 @@ interface BreakpointProviderProps {
40
40
  targetRef?: {
41
41
  current: HTMLElement | null;
42
42
  };
43
+ /**
44
+ * Optional: Enable development mode to show console warnings and errors.
45
+ * Defaults to false in production (NODE_ENV === 'production').
46
+ */
47
+ devMode?: boolean;
43
48
  }
44
49
  /**
45
50
  * BreakpointProvider 🚀
package/dist/index.d.ts CHANGED
@@ -40,6 +40,11 @@ interface BreakpointProviderProps {
40
40
  targetRef?: {
41
41
  current: HTMLElement | null;
42
42
  };
43
+ /**
44
+ * Optional: Enable development mode to show console warnings and errors.
45
+ * Defaults to false in production (NODE_ENV === 'production').
46
+ */
47
+ devMode?: boolean;
43
48
  }
44
49
  /**
45
50
  * BreakpointProvider 🚀
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var k=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var R=(e,t)=>{for(var s in t)k(e,s,{get:t[s],enumerable:!0})},T=(e,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let p of w(t))!C.call(e,p)&&p!==s&&k(e,p,{get:()=>t[p],enumerable:!(o=P(t,p))||o.enumerable});return e};var y=e=>T(k({},"__esModule",{value:!0}),e);var A={};R(A,{BreakpointConditional:()=>g,BreakpointProvider:()=>L,useBreakpoint:()=>b});module.exports=y(A);var d=require("react"),B=require("react-resize-detector"),u=require("react/jsx-runtime"),f=(0,d.createContext)(void 0),L=({breakpoints:e,children:t,targetRef:s})=>{let{width:o,ref:p}=(0,B.useResizeDetector)({targetRef:s}),n=(0,d.useMemo)(()=>Object.entries(e).map(([r,l])=>[r,l]).sort(([,r],[,l])=>r-l),[e]);(0,d.useEffect)(()=>{n.filter(([,l],c)=>n.findIndex(([,m])=>m===l)!==c).length>0&&console.error("BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.")},[n]);let a=(0,d.useMemo)(()=>{if(o===void 0)return null;let r=null;return n.forEach(([l,c])=>{o>=c&&(r=l)}),r},[o,n]);(0,d.useEffect)(()=>{o!==void 0&&o>0&&a===null&&(n.length>0&&o<n[0][1]?console.error(`BreakpointProvider: The current width (${o}px) is less than the smallest breakpoint value (${n[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`):console.error("BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object."))},[o,a,n]);let i=r=>n.findIndex(([l])=>l===r),v=r=>a?i(a)>=i(r):!1,x=r=>a?i(a)<i(r):!1;function h(r){if(a)return r[a]}return(0,u.jsx)(f.Provider,{value:{width:o??0,breakpoint:a,breakpoints:e,isAtLeast:v,isBelow:x,valueByBreakpoint:h},children:s?t:(0,u.jsx)("div",{ref:p,children:t})})},b=()=>{let e=(0,d.useContext)(f);if(!e)throw new Error("useBreakpoint must be used within a BreakpointProvider");return e},g=({show:e,isAtLeast:t,isBelow:s,children:o})=>{let{breakpoint:p,isAtLeast:n,isBelow:a}=b(),i=!0;return e&&p&&(i=i&&e.includes(p)),t&&(i=i&&n(t)),s&&(i=i&&a(s)),i?(0,u.jsx)(u.Fragment,{children:o}):null};0&&(module.exports={BreakpointConditional,BreakpointProvider,useBreakpoint});
2
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2luZGV4LnRzIiwgIi4uL3NyYy9CcmVha3BvaW50Q29udGV4dC50c3giXSwKICAic291cmNlc0NvbnRlbnQiOiBbImV4cG9ydCAqIGZyb20gJy4vQnJlYWtwb2ludENvbnRleHQnO1xuIiwgImltcG9ydCBSZWFjdCwgeyBjcmVhdGVDb250ZXh0LCB1c2VDb250ZXh0LCB1c2VNZW1vLCB1c2VFZmZlY3QgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VSZXNpemVEZXRlY3RvciB9IGZyb20gJ3JlYWN0LXJlc2l6ZS1kZXRlY3Rvcic7XG5cbmV4cG9ydCB0eXBlIEJyZWFrcG9pbnQgPSBzdHJpbmc7IC8vIEFsbG93IGFyYml0cmFyeSBicmVha3BvaW50IG5hbWVzXG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJlYWtwb2ludENvbnRleHRUeXBlIHtcbiAgLyoqIEN1cnJlbnQgd2lkdGggb2YgdGhlIG9ic2VydmVkIGVsZW1lbnQgKi9cbiAgd2lkdGg6IG51bWJlcjtcbiAgLyoqIEN1cnJlbnRseSBhY3RpdmUgYnJlYWtwb2ludCAqL1xuICBicmVha3BvaW50OiBCcmVha3BvaW50IHwgbnVsbDtcbiAgLyoqIERlZmluZWQgYnJlYWtwb2ludHMsIGUuZy4sIHsgWFM6IDAsIFNNOiA1MDAsIE1EOiA3MDAsIExHOiA5MDAsIFhMOiAxMTAwIH0gKi9cbiAgYnJlYWtwb2ludHM6IFJlY29yZDxCcmVha3BvaW50LCBudW1iZXI+O1xuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGN1cnJlbnQgYnJlYWtwb2ludCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHByb3ZpZGVkIG9uZS5cbiAgICogRS5nLjogaXNBdExlYXN0KCdNRCcpIHJldHVybnMgdHJ1ZSBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIE1ELFxuICAgKiBMRywgb3IgWEwuXG4gICAqL1xuICBpc0F0TGVhc3Q6IChzaXplOiBCcmVha3BvaW50KSA9PiBib29sZWFuO1xuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGN1cnJlbnQgYnJlYWtwb2ludCBpcyBsZXNzIHRoYW4gdGhlIHByb3ZpZGVkIG9uZS5cbiAgICovXG4gIGlzQmVsb3c6IChzaXplOiBCcmVha3BvaW50KSA9PiBib29sZWFuO1xuICAvKipcbiAgICogUmV0dXJucyBhIHZhbHVlIGZyb20gdGhlIG1hcHBpbmcgYmFzZWQgb24gdGhlIGN1cnJlbnQgYnJlYWtwb2ludC5cbiAgICogRS5nLjogdmFsdWVCeUJyZWFrcG9pbnQoeyBNRDogMywgTEc6IDIgfSkgcmV0dXJucyAzIGZvciBNRCBhbmQgMiBmb3IgTEcuXG4gICAqL1xuICB2YWx1ZUJ5QnJlYWtwb2ludDogPFQ+KHZhbHVlczogUGFydGlhbDxSZWNvcmQ8QnJlYWtwb2ludCwgVD4+KSA9PiBUIHwgdW5kZWZpbmVkO1xufVxuXG5jb25zdCBCcmVha3BvaW50Q29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8QnJlYWtwb2ludENvbnRleHRUeXBlIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuXG4vKipcbiAqIEluc3RlYWQgb2YgdXNpbmcgUmVhY3QuUmVmT2JqZWN0PEhUTUxFbGVtZW50PiAod2hpY2ggaXMgaW52YXJpYW50KSxcbiAqIHdlIHVzZSBhIHN0cnVjdHVyYWwgdHlwZSB0aGF0IGFjY2VwdHMgYW55IG9iamVjdCB3aXRoIGEgYGN1cnJlbnQ6IEhUTUxFbGVtZW50IHwgbnVsbGAgcHJvcGVydHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQnJlYWtwb2ludFByb3ZpZGVyUHJvcHMge1xuICAvKiogRGVmaW5lZCBicmVha3BvaW50cyAqL1xuICBicmVha3BvaW50czogUmVjb3JkPEJyZWFrcG9pbnQsIG51bWJlcj47XG4gIC8qKiBDaGlsZCBjb21wb25lbnRzIHRoYXQgdXNlIHRoZSBjb250ZXh0ICovXG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGU7XG4gIC8qKlxuICAgKiBPcHRpb25hbDogUHJvdmlkZSBhIHJlZiB0byB0aGUgZWxlbWVudCB0byBiZSBvYnNlcnZlZC5cbiAgICogSWYgbm90IHByb3ZpZGVkLCBhbiBpbnRlcm5hbCA8ZGl2IHJlZj17Li4ufT4gd2lsbCBiZSByZW5kZXJlZC5cbiAgICovXG4gIHRhcmdldFJlZj86IHsgY3VycmVudDogSFRNTEVsZW1lbnQgfCBudWxsIH07XG59XG5cbi8qKlxuICogQnJlYWtwb2ludFByb3ZpZGVyIFx1RDgzRFx1REU4MFxuICpcbiAqIFVzZXMgcmVhY3QtcmVzaXplLWRldGVjdG9yIHRvIG1lYXN1cmUgdGhlIHdpZHRoIG9mIGFuIGVsZW1lbnQgYW5kIGRldGVybWluZSB0aGUgY3VycmVudCBicmVha3BvaW50XG4gKiBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgYnJlYWtwb2ludHMuIEFkZGl0aW9uYWxseSwgaXQgcHJvdmlkZXMgdXRpbGl0eSBmdW5jdGlvbnMgKGlzQXRMZWFzdCwgaXNCZWxvdylcbiAqIGFuZCB2YWx1ZUJ5QnJlYWtwb2ludC5cbiAqXG4gKiBcdTI2QTBcdUZFMEYgKipFZGdlIENhc2VzIC8gV2FybmluZ3M6KipcbiAqIC0gSWYgdGhlIG1lYXN1cmVkIHdpZHRoIGlzIHVuZGVmaW5lZCBvciAwLCBhbiBlcnJvciBpcyBsb2dnZWQgaW4gdGhlIGNvbnNvbGUuXG4gKiAtIElmIHRoZSBjdXJyZW50IHdpZHRoIGlzIGxlc3MgdGhhbiB0aGUgc21hbGxlc3QgYnJlYWtwb2ludCAoYW5kIHdpZHRoID4gMCksIGFuIGVycm9yIGlzIGxvZ2dlZC5cbiAqIC0gSWYgZHVwbGljYXRlIGJyZWFrcG9pbnQgdmFsdWVzIGFyZSBkZXRlY3RlZCwgYW4gZXJyb3IgaXMgbG9nZ2VkLlxuICovXG5leHBvcnQgY29uc3QgQnJlYWtwb2ludFByb3ZpZGVyOiBSZWFjdC5GQzxCcmVha3BvaW50UHJvdmlkZXJQcm9wcz4gPSAoeyBicmVha3BvaW50cywgY2hpbGRyZW4sIHRhcmdldFJlZiB9KSA9PiB7XG4gIC8vIElmIGEgdGFyZ2V0UmVmIGlzIHByb3ZpZGVkLCB1c2VSZXNpemVEZXRlY3RvciBvYnNlcnZlcyB0aGF0IGVsZW1lbnQ7IG90aGVyd2lzZSwgYW4gaW50ZXJuYWwgcmVmIGlzIGNyZWF0ZWQuXG4gIGNvbnN0IHsgd2lkdGgsIHJlZiB9ID0gdXNlUmVzaXplRGV0ZWN0b3IoeyB0YXJnZXRSZWYgfSk7XG5cbiAgLy8gU29ydCB0aGUgYnJlYWtwb2ludHMgaW4gYXNjZW5kaW5nIG9yZGVyIGJhc2VkIG9uIHRoZWlyIG51bWVyaWMgdmFsdWVzLiBcdUQ4M0RcdUREMjJcbiAgY29uc3Qgc29ydGVkQnJlYWtwb2ludHMgPSB1c2VNZW1vKCgpID0+IHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoYnJlYWtwb2ludHMpXG4gICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IFtrZXksIHZhbHVlXSBhcyBbQnJlYWtwb2ludCwgbnVtYmVyXSlcbiAgICAgIC5zb3J0KChbLCBhXSwgWywgYl0pID0+IGEgLSBiKTtcbiAgfSwgW2JyZWFrcG9pbnRzXSk7XG5cbiAgLyoqIENoZWNrIGZvciBkdXBsaWNhdGUgYnJlYWtwb2ludCB2YWx1ZXMgKi9cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBkdXBsaWNhdGVzID0gc29ydGVkQnJlYWtwb2ludHMuZmlsdGVyKFxuICAgICAgKFssIHZhbHVlXSwgaW5kZXgpID0+IHNvcnRlZEJyZWFrcG9pbnRzLmZpbmRJbmRleCgoWywgdl0pID0+IHYgPT09IHZhbHVlKSAhPT0gaW5kZXhcbiAgICApO1xuICAgIGlmIChkdXBsaWNhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0JyZWFrcG9pbnRQcm92aWRlcjogRHVwbGljYXRlIGJyZWFrcG9pbnQgdmFsdWVzIGRldGVjdGVkLiBUaGlzIG1heSBsZWFkIHRvIHVuZXhwZWN0ZWQgYmVoYXZpb3IuJyk7XG4gICAgfVxuICB9LCBbc29ydGVkQnJlYWtwb2ludHNdKTtcblxuICAvLyBEZXRlcm1pbmUgdGhlIGN1cnJlbnQgYnJlYWtwb2ludCBiYXNlZCBvbiB0aGUgbWVhc3VyZWQgd2lkdGguIFx1RDgzRFx1RENDRlxuICBjb25zdCBjdXJyZW50QnJlYWtwb2ludCA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICh3aWR0aCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gbnVsbDtcbiAgICBsZXQgYWN0aXZlOiBCcmVha3BvaW50IHwgbnVsbCA9IG51bGw7XG4gICAgc29ydGVkQnJlYWtwb2ludHMuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAod2lkdGggPj0gdmFsdWUpIHtcbiAgICAgICAgYWN0aXZlID0ga2V5O1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhY3RpdmU7XG4gIH0sIFt3aWR0aCwgc29ydGVkQnJlYWtwb2ludHNdKTtcblxuICAvLyBMb2cgZXJyb3IgaWYgd2lkdGggPiAwIGJ1dCBubyBicmVha3BvaW50IGNvdWxkIGJlIGRldGVybWluZWRcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAod2lkdGggIT09IHVuZGVmaW5lZCAmJiB3aWR0aCA+IDAgJiYgY3VycmVudEJyZWFrcG9pbnQgPT09IG51bGwpIHtcbiAgICAgIGlmIChzb3J0ZWRCcmVha3BvaW50cy5sZW5ndGggPiAwICYmIHdpZHRoIDwgc29ydGVkQnJlYWtwb2ludHNbMF1bMV0pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICBgQnJlYWtwb2ludFByb3ZpZGVyOiBUaGUgY3VycmVudCB3aWR0aCAoJHt3aWR0aH1weCkgaXMgbGVzcyB0aGFuIHRoZSBzbWFsbGVzdCBicmVha3BvaW50IHZhbHVlICgke3NvcnRlZEJyZWFrcG9pbnRzWzBdWzFdfXB4KS4gQ29uc2lkZXIgaW5jbHVkaW5nIGEgYnJlYWtwb2ludCB3aXRoIGEgdmFsdWUgb2YgMCB0byBjb3ZlciBhbGwgY2FzZXMuYFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAnQnJlYWtwb2ludFByb3ZpZGVyOiBObyBicmVha3BvaW50IGNvdWxkIGJlIGRldGVybWluZWQgZnJvbSB0aGUgcHJvdmlkZWQgY29uZmlndXJhdGlvbi4gQ2hlY2sgeW91ciBicmVha3BvaW50cyBvYmplY3QuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSwgW3dpZHRoLCBjdXJyZW50QnJlYWtwb2ludCwgc29ydGVkQnJlYWtwb2ludHNdKTtcblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpbmRleCBvZiBhIGJyZWFrcG9pbnQgaW4gdGhlIHNvcnRlZCBhcnJheS4gXHVEODNEXHVERDBEXG4gIGNvbnN0IGdldEJyZWFrcG9pbnRJbmRleCA9IChzaXplOiBCcmVha3BvaW50KTogbnVtYmVyID0+IHtcbiAgICByZXR1cm4gc29ydGVkQnJlYWtwb2ludHMuZmluZEluZGV4KChba2V5XSkgPT4ga2V5ID09PSBzaXplKTtcbiAgfTtcblxuICBjb25zdCBpc0F0TGVhc3QgPSAoc2l6ZTogQnJlYWtwb2ludCk6IGJvb2xlYW4gPT4ge1xuICAgIGlmICghY3VycmVudEJyZWFrcG9pbnQpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gZ2V0QnJlYWtwb2ludEluZGV4KGN1cnJlbnRCcmVha3BvaW50KSA+PSBnZXRCcmVha3BvaW50SW5kZXgoc2l6ZSk7XG4gIH07XG5cbiAgY29uc3QgaXNCZWxvdyA9IChzaXplOiBCcmVha3BvaW50KTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKCFjdXJyZW50QnJlYWtwb2ludCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBnZXRCcmVha3BvaW50SW5kZXgoY3VycmVudEJyZWFrcG9pbnQpIDwgZ2V0QnJlYWtwb2ludEluZGV4KHNpemUpO1xuICB9O1xuXG4gIC8vIERlZmluZSB2YWx1ZUJ5QnJlYWtwb2ludCBhcyBhIGZ1bmN0aW9uIGRlY2xhcmF0aW9uIHRvIGF2b2lkIEpTWCBwYXJzaW5nIGlzc3VlcyBpbiBUU1ggZmlsZXMuIFx1RDgzQ1x1REZBOFxuICBmdW5jdGlvbiB2YWx1ZUJ5QnJlYWtwb2ludDxUPih2YWx1ZXM6IFBhcnRpYWw8UmVjb3JkPEJyZWFrcG9pbnQsIFQ+Pik6IFQgfCB1bmRlZmluZWQge1xuICAgIGlmICghY3VycmVudEJyZWFrcG9pbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHZhbHVlc1tjdXJyZW50QnJlYWtwb2ludF07XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxCcmVha3BvaW50Q29udGV4dC5Qcm92aWRlclxuICAgICAgdmFsdWU9e3tcbiAgICAgICAgd2lkdGg6IHdpZHRoID8/IDAsXG4gICAgICAgIGJyZWFrcG9pbnQ6IGN1cnJlbnRCcmVha3BvaW50LFxuICAgICAgICBicmVha3BvaW50cyxcbiAgICAgICAgaXNBdExlYXN0LFxuICAgICAgICBpc0JlbG93LFxuICAgICAgICB2YWx1ZUJ5QnJlYWtwb2ludCxcbiAgICAgIH19XG4gICAgPlxuICAgICAgey8qIElmIGEgdGFyZ2V0UmVmIGlzIHByb3ZpZGVkLCB0aGF0IHJlZiBpcyBhbHJlYWR5IGF0dGFjaGVkIHRvIGFuIGV4dGVybmFsIGVsZW1lbnQuXG4gICAgICAgICAgT3RoZXJ3aXNlLCByZW5kZXIgYSA8ZGl2IHJlZj17cmVmfT4gdG8gb2JzZXJ2ZSBpdHMgc2l6ZS4gXHVEODNEXHVEQ0QwICovfVxuICAgICAge3RhcmdldFJlZiA/IGNoaWxkcmVuIDogPGRpdiByZWY9e3JlZn0+e2NoaWxkcmVufTwvZGl2Pn1cbiAgICA8L0JyZWFrcG9pbnRDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufTtcblxuLyoqXG4gKiBIb29rIGZvciBhY2Nlc3NpbmcgdGhlIEJyZWFrcG9pbnRDb250ZXh0LlxuICogVGhyb3dzIGFuIGVycm9yIGlmIHVzZWQgb3V0c2lkZSBvZiBhIEJyZWFrcG9pbnRQcm92aWRlci4gXHUyNkEwXHVGRTBGXG4gKi9cbmV4cG9ydCBjb25zdCB1c2VCcmVha3BvaW50ID0gKCk6IEJyZWFrcG9pbnRDb250ZXh0VHlwZSA9PiB7XG4gIGNvbnN0IGNvbnRleHQgPSB1c2VDb250ZXh0KEJyZWFrcG9pbnRDb250ZXh0KTtcbiAgaWYgKCFjb250ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1c2VCcmVha3BvaW50IG11c3QgYmUgdXNlZCB3aXRoaW4gYSBCcmVha3BvaW50UHJvdmlkZXInKTtcbiAgfVxuICByZXR1cm4gY29udGV4dDtcbn07XG5cbmludGVyZmFjZSBCcmVha3BvaW50Q29uZGl0aW9uYWxQcm9wcyB7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBicmVha3BvaW50cyBhdCB3aGljaCB0aGUgY2hpbGRyZW4gc2hvdWxkIGJlIGRpc3BsYXllZC5cbiAgICogRS5nLjogWydNRCcsICdMRyddIHJlbmRlcnMgY2hpbGRyZW4gb25seSBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIE1EIG9yIExHLlxuICAgKi9cbiAgc2hvdz86IEJyZWFrcG9pbnRbXTtcbiAgLyoqXG4gICAqIFRoZSBjaGlsZHJlbiBhcmUgZGlzcGxheWVkIG9ubHkgaWYgdGhlIGN1cnJlbnQgYnJlYWtwb2ludCBpcyBhdCBsZWFzdCB0aGlzIHZhbHVlLlxuICAgKiBFLmcuOiBpc0F0TGVhc3Q9XCJNRFwiIHJlbmRlcnMgY2hpbGRyZW4gZm9yIE1ELCBMRywgb3IgWEwuXG4gICAqL1xuICBpc0F0TGVhc3Q/OiBCcmVha3BvaW50O1xuICAvKipcbiAgICogVGhlIGNoaWxkcmVuIGFyZSBkaXNwbGF5ZWQgb25seSBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIGJlbG93IHRoaXMgdmFsdWUuXG4gICAqL1xuICBpc0JlbG93PzogQnJlYWtwb2ludDtcbiAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbn1cblxuLyoqXG4gKiBCcmVha3BvaW50Q29uZGl0aW9uYWwgXHVEODNDXHVERkE4XG4gKlxuICogUmVuZGVycyBpdHMgY2hpbGRyZW4gb25seSBpZiBhbGwgcHJvdmlkZWQgY29uZGl0aW9ucyByZWdhcmRpbmcgdGhlIGN1cnJlbnQgYnJlYWtwb2ludCBhcmUgbWV0LlxuICovXG5leHBvcnQgY29uc3QgQnJlYWtwb2ludENvbmRpdGlvbmFsOiBSZWFjdC5GQzxCcmVha3BvaW50Q29uZGl0aW9uYWxQcm9wcz4gPSAoe1xuICBzaG93LFxuICBpc0F0TGVhc3Q6IG1pblNpemUsXG4gIGlzQmVsb3c6IG1heFNpemUsXG4gIGNoaWxkcmVuLFxufSkgPT4ge1xuICBjb25zdCB7IGJyZWFrcG9pbnQsIGlzQXRMZWFzdDogY29udGV4dElzQXRMZWFzdCwgaXNCZWxvdzogY29udGV4dElzQmVsb3cgfSA9IHVzZUJyZWFrcG9pbnQoKTtcblxuICBsZXQgc2hvdWxkUmVuZGVyID0gdHJ1ZTtcblxuICBpZiAoc2hvdyAmJiBicmVha3BvaW50KSB7XG4gICAgc2hvdWxkUmVuZGVyID0gc2hvdWxkUmVuZGVyICYmIHNob3cuaW5jbHVkZXMoYnJlYWtwb2ludCk7XG4gIH1cbiAgaWYgKG1pblNpemUpIHtcbiAgICBzaG91bGRSZW5kZXIgPSBzaG91bGRSZW5kZXIgJiYgY29udGV4dElzQXRMZWFzdChtaW5TaXplKTtcbiAgfVxuICBpZiAobWF4U2l6ZSkge1xuICAgIHNob3VsZFJlbmRlciA9IHNob3VsZFJlbmRlciAmJiBjb250ZXh0SXNCZWxvdyhtYXhTaXplKTtcbiAgfVxuXG4gIHJldHVybiBzaG91bGRSZW5kZXIgPyA8PntjaGlsZHJlbn08Lz4gOiBudWxsO1xufTsiXSwKICAibWFwcGluZ3MiOiAieWFBQUEsSUFBQUEsRUFBQSxHQUFBQyxFQUFBRCxFQUFBLDJCQUFBRSxFQUFBLHVCQUFBQyxFQUFBLGtCQUFBQyxJQUFBLGVBQUFDLEVBQUFMLEdDQUEsSUFBQU0sRUFBcUUsaUJBQ3JFQyxFQUFrQyxpQ0E0SUpDLEVBQUEsNkJBaEh4QkMsS0FBb0IsaUJBQWlELE1BQVMsRUE4QnZFQyxFQUF3RCxDQUFDLENBQUUsWUFBQUMsRUFBYSxTQUFBQyxFQUFVLFVBQUFDLENBQVUsSUFBTSxDQUU3RyxHQUFNLENBQUUsTUFBQUMsRUFBTyxJQUFBQyxDQUFJLEtBQUkscUJBQWtCLENBQUUsVUFBQUYsQ0FBVSxDQUFDLEVBR2hERyxLQUFvQixXQUFRLElBQ3pCLE9BQU8sUUFBUUwsQ0FBVyxFQUM5QixJQUFJLENBQUMsQ0FBQ00sRUFBS0MsQ0FBSyxJQUFNLENBQUNELEVBQUtDLENBQUssQ0FBeUIsRUFDMUQsS0FBSyxDQUFDLENBQUMsQ0FBRUMsQ0FBQyxFQUFHLENBQUMsQ0FBRUMsQ0FBQyxJQUFNRCxFQUFJQyxDQUFDLEVBQzlCLENBQUNULENBQVcsQ0FBQyxLQUdoQixhQUFVLElBQU0sQ0FDS0ssRUFBa0IsT0FDbkMsQ0FBQyxDQUFDLENBQUVFLENBQUssRUFBR0csSUFBVUwsRUFBa0IsVUFBVSxDQUFDLENBQUMsQ0FBRU0sQ0FBQyxJQUFNQSxJQUFNSixDQUFLLElBQU1HLENBQ2hGLEVBQ2UsT0FBUyxHQUN0QixRQUFRLE1BQU0saUdBQWlHLENBRW5ILEVBQUcsQ0FBQ0wsQ0FBaUIsQ0FBQyxFQUd0QixJQUFNTyxLQUFvQixXQUFRLElBQU0sQ0FDdEMsR0FBSVQsSUFBVSxPQUFXLE9BQU8sS0FDaEMsSUFBSVUsRUFBNEIsS0FDaEMsT0FBQVIsRUFBa0IsUUFBUSxDQUFDLENBQUNDLEVBQUtDLENBQUssSUFBTSxDQUN0Q0osR0FBU0ksSUFDWE0sRUFBU1AsRUFFYixDQUFDLEVBQ01PLENBQ1QsRUFBRyxDQUFDVixFQUFPRSxDQUFpQixDQUFDLEtBRzdCLGFBQVUsSUFBTSxDQUNWRixJQUFVLFFBQWFBLEVBQVEsR0FBS1MsSUFBc0IsT0FDeERQLEVBQWtCLE9BQVMsR0FBS0YsRUFBUUUsRUFBa0IsQ0FBQyxFQUFFLENBQUMsRUFDaEUsUUFBUSxNQUNOLDBDQUEwQ0YsQ0FBSyxtREFBbURFLEVBQWtCLENBQUMsRUFBRSxDQUFDLENBQUMsNEVBQzNILEVBRUEsUUFBUSxNQUNOLHVIQUNGLEVBR04sRUFBRyxDQUFDRixFQUFPUyxFQUFtQlAsQ0FBaUIsQ0FBQyxFQUdoRCxJQUFNUyxFQUFzQkMsR0FDbkJWLEVBQWtCLFVBQVUsQ0FBQyxDQUFDQyxDQUFHLElBQU1BLElBQVFTLENBQUksRUFHdERDLEVBQWFELEdBQ1pILEVBQ0VFLEVBQW1CRixDQUFpQixHQUFLRSxFQUFtQkMsQ0FBSSxFQUR4QyxHQUkzQkUsRUFBV0YsR0FDVkgsRUFDRUUsRUFBbUJGLENBQWlCLEVBQUlFLEVBQW1CQyxDQUFJLEVBRHZDLEdBS2pDLFNBQVNHLEVBQXFCQyxFQUF1RCxDQUNuRixHQUFLUCxFQUNMLE9BQU9PLEVBQU9QLENBQWlCLENBQ2pDLENBRUEsU0FDRSxPQUFDZCxFQUFrQixTQUFsQixDQUNDLE1BQU8sQ0FDTCxNQUFPSyxHQUFTLEVBQ2hCLFdBQVlTLEVBQ1osWUFBQVosRUFDQSxVQUFBZ0IsRUFDQSxRQUFBQyxFQUNBLGtCQUFBQyxDQUNGLEVBSUMsU0FBQWhCLEVBQVlELEtBQVcsT0FBQyxPQUFJLElBQUtHLEVBQU0sU0FBQUgsRUFBUyxFQUNuRCxDQUVKLEVBTWFtQixFQUFnQixJQUE2QixDQUN4RCxJQUFNQyxLQUFVLGNBQVd2QixDQUFpQixFQUM1QyxHQUFJLENBQUN1QixFQUNILE1BQU0sSUFBSSxNQUFNLHdEQUF3RCxFQUUxRSxPQUFPQSxDQUNULEVBeUJhQyxFQUE4RCxDQUFDLENBQzFFLEtBQUFDLEVBQ0EsVUFBV0MsRUFDWCxRQUFTQyxFQUNULFNBQUF4QixDQUNGLElBQU0sQ0FDSixHQUFNLENBQUUsV0FBQXlCLEVBQVksVUFBV0MsRUFBa0IsUUFBU0MsQ0FBZSxFQUFJUixFQUFjLEVBRXZGUyxFQUFlLEdBRW5CLE9BQUlOLEdBQVFHLElBQ1ZHLEVBQWVBLEdBQWdCTixFQUFLLFNBQVNHLENBQVUsR0FFckRGLElBQ0ZLLEVBQWVBLEdBQWdCRixFQUFpQkgsQ0FBTyxHQUVyREMsSUFDRkksRUFBZUEsR0FBZ0JELEVBQWVILENBQU8sR0FHaERJLEtBQWUsbUJBQUcsU0FBQTVCLEVBQVMsRUFBTSxJQUMxQyIsCiAgIm5hbWVzIjogWyJzcmNfZXhwb3J0cyIsICJfX2V4cG9ydCIsICJCcmVha3BvaW50Q29uZGl0aW9uYWwiLCAiQnJlYWtwb2ludFByb3ZpZGVyIiwgInVzZUJyZWFrcG9pbnQiLCAiX190b0NvbW1vbkpTIiwgImltcG9ydF9yZWFjdCIsICJpbXBvcnRfcmVhY3RfcmVzaXplX2RldGVjdG9yIiwgImltcG9ydF9qc3hfcnVudGltZSIsICJCcmVha3BvaW50Q29udGV4dCIsICJCcmVha3BvaW50UHJvdmlkZXIiLCAiYnJlYWtwb2ludHMiLCAiY2hpbGRyZW4iLCAidGFyZ2V0UmVmIiwgIndpZHRoIiwgInJlZiIsICJzb3J0ZWRCcmVha3BvaW50cyIsICJrZXkiLCAidmFsdWUiLCAiYSIsICJiIiwgImluZGV4IiwgInYiLCAiY3VycmVudEJyZWFrcG9pbnQiLCAiYWN0aXZlIiwgImdldEJyZWFrcG9pbnRJbmRleCIsICJzaXplIiwgImlzQXRMZWFzdCIsICJpc0JlbG93IiwgInZhbHVlQnlCcmVha3BvaW50IiwgInZhbHVlcyIsICJ1c2VCcmVha3BvaW50IiwgImNvbnRleHQiLCAiQnJlYWtwb2ludENvbmRpdGlvbmFsIiwgInNob3ciLCAibWluU2l6ZSIsICJtYXhTaXplIiwgImJyZWFrcG9pbnQiLCAiY29udGV4dElzQXRMZWFzdCIsICJjb250ZXh0SXNCZWxvdyIsICJzaG91bGRSZW5kZXIiXQp9Cg==
1
+ "use strict";var B=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var y=(t,r)=>{for(var s in r)B(t,s,{get:r[s],enumerable:!0})},L=(t,r,s,l)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of R(r))!T.call(t,n)&&n!==s&&B(t,n,{get:()=>r[n],enumerable:!(l=C(r,n))||l.enumerable});return t};var g=t=>L(B({},"__esModule",{value:!0}),t);var I={};y(I,{BreakpointConditional:()=>E,BreakpointProvider:()=>A,useBreakpoint:()=>h});module.exports=g(I);var a=require("react"),v=require("react-resize-detector"),u=require("react/jsx-runtime"),b=(0,a.createContext)(void 0),A=({breakpoints:t,children:r,targetRef:s,devMode:l})=>{let n=l!==void 0?l:process.env.NODE_ENV!=="production",{width:i,ref:k}=(0,v.useResizeDetector)({targetRef:s}),e=(0,a.useMemo)(()=>Object.entries(t).map(([o,d])=>[o,d]).sort(([,o],[,d])=>o-d),[t]);(0,a.useEffect)(()=>{e.filter(([,d],f)=>e.findIndex(([,w])=>w===d)!==f).length>0&&n&&console.error("\u274C BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.")},[e]);let p=(0,a.useMemo)(()=>{if(i===void 0)return null;let o=null;return e.forEach(([d,f])=>{i>=f&&(o=d)}),o},[i,e]);(0,a.useEffect)(()=>{(i===void 0||i===0)&&n&&console.error("\u274C BreakpointProvider: element width is undefined or 0")},[i,n]),(0,a.useEffect)(()=>{i!==void 0&&i>0&&p===null&&(e.length>0&&i<e[0][1]?n&&console.error(`\u274C BreakpointProvider: The current width (${i}px) is less than the smallest breakpoint value (${e[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`):n&&console.error("\u274C BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object."))},[i,p,e]);let c=o=>e.findIndex(([d])=>d===o),x=o=>p?c(p)>=c(o):!1,m=o=>p?c(p)<c(o):!1;function P(o){if(p)return o[p]}return(0,u.jsx)(b.Provider,{value:{width:i??0,breakpoint:p,breakpoints:t,isAtLeast:x,isBelow:m,valueByBreakpoint:P},children:s?r:(0,u.jsx)("div",{ref:k,children:r})})},h=()=>{let t=(0,a.useContext)(b);if(!t)throw new Error("useBreakpoint must be used within a BreakpointProvider");return t},E=({show:t,isAtLeast:r,isBelow:s,children:l})=>{let{breakpoint:n,isAtLeast:i,isBelow:k}=h(),e=!0;return t&&n&&(e=e&&t.includes(n)),r&&(e=e&&i(r)),s&&(e=e&&k(s)),e?(0,u.jsx)(u.Fragment,{children:l}):null};0&&(module.exports={BreakpointConditional,BreakpointProvider,useBreakpoint});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/BreakpointContext.tsx"],"sourcesContent":["export * from './BreakpointContext';\n","import React, { createContext, useContext, useMemo, useEffect } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nexport type Breakpoint = string; // Allow arbitrary breakpoint names\n\nexport interface BreakpointContextType {\n /** Current width of the observed element */\n width: number;\n /** Currently active breakpoint */\n breakpoint: Breakpoint | null;\n /** Defined breakpoints, e.g., { XS: 0, SM: 500, MD: 700, LG: 900, XL: 1100 } */\n breakpoints: Record<Breakpoint, number>;\n /**\n * Returns `true` if the current breakpoint is greater than or equal to the provided one.\n * E.g.: isAtLeast('MD') returns true if the current breakpoint is MD,\n * LG, or XL.\n */\n isAtLeast: (size: Breakpoint) => boolean;\n /**\n * Returns `true` if the current breakpoint is less than the provided one.\n */\n isBelow: (size: Breakpoint) => boolean;\n /**\n * Returns a value from the mapping based on the current breakpoint.\n * E.g.: valueByBreakpoint({ MD: 3, LG: 2 }) returns 3 for MD and 2 for LG.\n */\n valueByBreakpoint: <T>(values: Partial<Record<Breakpoint, T>>) => T | undefined;\n}\n\nconst BreakpointContext = createContext<BreakpointContextType | undefined>(undefined);\n\n/**\n * Instead of using React.RefObject<HTMLElement> (which is invariant),\n * we use a structural type that accepts any object with a `current: HTMLElement | null` property.\n */\nexport interface BreakpointProviderProps {\n /** Defined breakpoints */\n breakpoints: Record<Breakpoint, number>;\n /** Child components that use the context */\n children: React.ReactNode;\n /**\n * Optional: Provide a ref to the element to be observed.\n * If not provided, an internal <div ref={...}> will be rendered.\n */\n targetRef?: { current: HTMLElement | null };\n /**\n * Optional: Enable development mode to show console warnings and errors.\n * Defaults to false in production (NODE_ENV === 'production').\n */\n devMode?: boolean;\n}\n\n/**\n * BreakpointProvider 🚀\n *\n * Uses react-resize-detector to measure the width of an element and determine the current breakpoint\n * based on the provided breakpoints. Additionally, it provides utility functions (isAtLeast, isBelow)\n * and valueByBreakpoint.\n *\n * ⚠️ **Edge Cases / Warnings:**\n * - If the measured width is undefined or 0, an error is logged in the console.\n * - If the current width is less than the smallest breakpoint (and width > 0), an error is logged.\n * - If duplicate breakpoint values are detected, an error is logged.\n */\nexport const BreakpointProvider: React.FC<BreakpointProviderProps> = ({\n breakpoints,\n children,\n targetRef,\n devMode,\n}) => {\n // Determine if we should log based on devMode prop or NODE_ENV\n const shouldLog = devMode !== undefined ? devMode : process.env.NODE_ENV !== 'production';\n // If a targetRef is provided, useResizeDetector observes that element; otherwise, an internal ref is created.\n const { width, ref } = useResizeDetector({ targetRef });\n\n // Sort the breakpoints in ascending order based on their numeric values. 🔢\n const sortedBreakpoints = useMemo(() => {\n return Object.entries(breakpoints)\n .map(([key, value]) => [key, value] as [Breakpoint, number])\n .sort(([, a], [, b]) => a - b);\n }, [breakpoints]);\n\n /** Check for duplicate breakpoint values */\n useEffect(() => {\n const duplicates = sortedBreakpoints.filter(\n ([, value], index) => sortedBreakpoints.findIndex(([, v]) => v === value) !== index\n );\n if (duplicates.length > 0) {\n if (shouldLog) {\n console.error(\n '❌ BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.'\n );\n }\n }\n }, [sortedBreakpoints]);\n\n // Determine the current breakpoint based on the measured width. 📏\n const currentBreakpoint = useMemo(() => {\n if (width === undefined) return null;\n let active: Breakpoint | null = null;\n sortedBreakpoints.forEach(([key, value]) => {\n if (width >= value) {\n active = key;\n }\n });\n return active;\n }, [width, sortedBreakpoints]);\n\n // Log error if width is undefined or 0\n useEffect(() => {\n if (width === undefined || width === 0) {\n if (shouldLog) {\n console.error('❌ BreakpointProvider: element width is undefined or 0');\n }\n }\n }, [width, shouldLog]);\n\n // Log error if width > 0 but no breakpoint could be determined\n useEffect(() => {\n if (width !== undefined && width > 0 && currentBreakpoint === null) {\n if (sortedBreakpoints.length > 0 && width < sortedBreakpoints[0][1]) {\n if (shouldLog) {\n console.error(\n `❌ BreakpointProvider: The current width (${width}px) is less than the smallest breakpoint value (${sortedBreakpoints[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`\n );\n }\n } else {\n if (shouldLog) {\n console.error(\n '❌ BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object.'\n );\n }\n }\n }\n }, [width, currentBreakpoint, sortedBreakpoints]);\n\n // Helper function to get the index of a breakpoint in the sorted array. 🔍\n const getBreakpointIndex = (size: Breakpoint): number => {\n return sortedBreakpoints.findIndex(([key]) => key === size);\n };\n\n const isAtLeast = (size: Breakpoint): boolean => {\n if (!currentBreakpoint) return false;\n return getBreakpointIndex(currentBreakpoint) >= getBreakpointIndex(size);\n };\n\n const isBelow = (size: Breakpoint): boolean => {\n if (!currentBreakpoint) return false;\n return getBreakpointIndex(currentBreakpoint) < getBreakpointIndex(size);\n };\n\n // Define valueByBreakpoint as a function declaration to avoid JSX parsing issues in TSX files. 🎨\n function valueByBreakpoint<T>(values: Partial<Record<Breakpoint, T>>): T | undefined {\n if (!currentBreakpoint) return undefined;\n return values[currentBreakpoint];\n }\n\n return (\n <BreakpointContext.Provider\n value={{\n width: width ?? 0,\n breakpoint: currentBreakpoint,\n breakpoints,\n isAtLeast,\n isBelow,\n valueByBreakpoint,\n }}\n >\n {/* If a targetRef is provided, that ref is already attached to an external element.\n Otherwise, render a <div ref={ref}> to observe its size. 📐 */}\n {targetRef ? children : <div ref={ref}>{children}</div>}\n </BreakpointContext.Provider>\n );\n};\n\n/**\n * Hook for accessing the BreakpointContext.\n * Throws an error if used outside of a BreakpointProvider. ⚠️\n */\nexport const useBreakpoint = (): BreakpointContextType => {\n const context = useContext(BreakpointContext);\n if (!context) {\n throw new Error('useBreakpoint must be used within a BreakpointProvider');\n }\n return context;\n};\n\ninterface BreakpointConditionalProps {\n /**\n * Array of breakpoints at which the children should be displayed.\n * E.g.: ['MD', 'LG'] renders children only if the current breakpoint is MD or LG.\n */\n show?: Breakpoint[];\n /**\n * The children are displayed only if the current breakpoint is at least this value.\n * E.g.: isAtLeast=\"MD\" renders children for MD, LG, or XL.\n */\n isAtLeast?: Breakpoint;\n /**\n * The children are displayed only if the current breakpoint is below this value.\n */\n isBelow?: Breakpoint;\n children: React.ReactNode;\n}\n\n/**\n * BreakpointConditional 🎨\n *\n * Renders its children only if all provided conditions regarding the current breakpoint are met.\n */\nexport const BreakpointConditional: React.FC<BreakpointConditionalProps> = ({\n show,\n isAtLeast: minSize,\n isBelow: maxSize,\n children,\n}) => {\n const { breakpoint, isAtLeast: contextIsAtLeast, isBelow: contextIsBelow } = useBreakpoint();\n\n let shouldRender = true;\n\n if (show && breakpoint) {\n shouldRender = shouldRender && show.includes(breakpoint);\n }\n if (minSize) {\n shouldRender = shouldRender && contextIsAtLeast(minSize);\n }\n if (maxSize) {\n shouldRender = shouldRender && contextIsBelow(maxSize);\n }\n\n return shouldRender ? <>{children}</> : null;\n};\n"],"mappings":"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","names":["src_exports","__export","BreakpointConditional","BreakpointProvider","useBreakpoint","__toCommonJS","import_react","import_react_resize_detector","import_jsx_runtime","BreakpointContext","BreakpointProvider","breakpoints","children","targetRef","devMode","shouldLog","width","ref","sortedBreakpoints","key","value","a","b","index","v","currentBreakpoint","active","getBreakpointIndex","size","isAtLeast","isBelow","valueByBreakpoint","values","useBreakpoint","context","BreakpointConditional","show","minSize","maxSize","breakpoint","contextIsAtLeast","contextIsBelow","shouldRender"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{createContext as h,useContext as m,useMemo as c,useEffect as k}from"react";import{useResizeDetector as P}from"react-resize-detector";import{Fragment as C,jsx as u}from"react/jsx-runtime";var B=h(void 0),L=({breakpoints:i,children:s,targetRef:p})=>{let{width:o,ref:d}=P({targetRef:p}),t=c(()=>Object.entries(i).map(([e,a])=>[e,a]).sort(([,e],[,a])=>e-a),[i]);k(()=>{t.filter(([,a],l)=>t.findIndex(([,x])=>x===a)!==l).length>0&&console.error("BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.")},[t]);let n=c(()=>{if(o===void 0)return null;let e=null;return t.forEach(([a,l])=>{o>=l&&(e=a)}),e},[o,t]);k(()=>{o!==void 0&&o>0&&n===null&&(t.length>0&&o<t[0][1]?console.error(`BreakpointProvider: The current width (${o}px) is less than the smallest breakpoint value (${t[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`):console.error("BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object."))},[o,n,t]);let r=e=>t.findIndex(([a])=>a===e),f=e=>n?r(n)>=r(e):!1,b=e=>n?r(n)<r(e):!1;function v(e){if(n)return e[n]}return u(B.Provider,{value:{width:o??0,breakpoint:n,breakpoints:i,isAtLeast:f,isBelow:b,valueByBreakpoint:v},children:p?s:u("div",{ref:d,children:s})})},w=()=>{let i=m(B);if(!i)throw new Error("useBreakpoint must be used within a BreakpointProvider");return i},g=({show:i,isAtLeast:s,isBelow:p,children:o})=>{let{breakpoint:d,isAtLeast:t,isBelow:n}=w(),r=!0;return i&&d&&(r=r&&i.includes(d)),s&&(r=r&&t(s)),p&&(r=r&&n(p)),r?u(C,{children:o}):null};export{g as BreakpointConditional,L as BreakpointProvider,w as useBreakpoint};
2
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL0JyZWFrcG9pbnRDb250ZXh0LnRzeCJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IFJlYWN0LCB7IGNyZWF0ZUNvbnRleHQsIHVzZUNvbnRleHQsIHVzZU1lbW8sIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZVJlc2l6ZURldGVjdG9yIH0gZnJvbSAncmVhY3QtcmVzaXplLWRldGVjdG9yJztcblxuZXhwb3J0IHR5cGUgQnJlYWtwb2ludCA9IHN0cmluZzsgLy8gQWxsb3cgYXJiaXRyYXJ5IGJyZWFrcG9pbnQgbmFtZXNcblxuZXhwb3J0IGludGVyZmFjZSBCcmVha3BvaW50Q29udGV4dFR5cGUge1xuICAvKiogQ3VycmVudCB3aWR0aCBvZiB0aGUgb2JzZXJ2ZWQgZWxlbWVudCAqL1xuICB3aWR0aDogbnVtYmVyO1xuICAvKiogQ3VycmVudGx5IGFjdGl2ZSBicmVha3BvaW50ICovXG4gIGJyZWFrcG9pbnQ6IEJyZWFrcG9pbnQgfCBudWxsO1xuICAvKiogRGVmaW5lZCBicmVha3BvaW50cywgZS5nLiwgeyBYUzogMCwgU006IDUwMCwgTUQ6IDcwMCwgTEc6IDkwMCwgWEw6IDExMDAgfSAqL1xuICBicmVha3BvaW50czogUmVjb3JkPEJyZWFrcG9pbnQsIG51bWJlcj47XG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgcHJvdmlkZWQgb25lLlxuICAgKiBFLmcuOiBpc0F0TGVhc3QoJ01EJykgcmV0dXJucyB0cnVlIGlmIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQgaXMgTUQsXG4gICAqIExHLCBvciBYTC5cbiAgICovXG4gIGlzQXRMZWFzdDogKHNpemU6IEJyZWFrcG9pbnQpID0+IGJvb2xlYW47XG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIGxlc3MgdGhhbiB0aGUgcHJvdmlkZWQgb25lLlxuICAgKi9cbiAgaXNCZWxvdzogKHNpemU6IEJyZWFrcG9pbnQpID0+IGJvb2xlYW47XG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdmFsdWUgZnJvbSB0aGUgbWFwcGluZyBiYXNlZCBvbiB0aGUgY3VycmVudCBicmVha3BvaW50LlxuICAgKiBFLmcuOiB2YWx1ZUJ5QnJlYWtwb2ludCh7IE1EOiAzLCBMRzogMiB9KSByZXR1cm5zIDMgZm9yIE1EIGFuZCAyIGZvciBMRy5cbiAgICovXG4gIHZhbHVlQnlCcmVha3BvaW50OiA8VD4odmFsdWVzOiBQYXJ0aWFsPFJlY29yZDxCcmVha3BvaW50LCBUPj4pID0+IFQgfCB1bmRlZmluZWQ7XG59XG5cbmNvbnN0IEJyZWFrcG9pbnRDb250ZXh0ID0gY3JlYXRlQ29udGV4dDxCcmVha3BvaW50Q29udGV4dFR5cGUgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG5cbi8qKlxuICogSW5zdGVhZCBvZiB1c2luZyBSZWFjdC5SZWZPYmplY3Q8SFRNTEVsZW1lbnQ+ICh3aGljaCBpcyBpbnZhcmlhbnQpLFxuICogd2UgdXNlIGEgc3RydWN0dXJhbCB0eXBlIHRoYXQgYWNjZXB0cyBhbnkgb2JqZWN0IHdpdGggYSBgY3VycmVudDogSFRNTEVsZW1lbnQgfCBudWxsYCBwcm9wZXJ0eS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCcmVha3BvaW50UHJvdmlkZXJQcm9wcyB7XG4gIC8qKiBEZWZpbmVkIGJyZWFrcG9pbnRzICovXG4gIGJyZWFrcG9pbnRzOiBSZWNvcmQ8QnJlYWtwb2ludCwgbnVtYmVyPjtcbiAgLyoqIENoaWxkIGNvbXBvbmVudHMgdGhhdCB1c2UgdGhlIGNvbnRleHQgKi9cbiAgY2hpbGRyZW46IFJlYWN0LlJlYWN0Tm9kZTtcbiAgLyoqXG4gICAqIE9wdGlvbmFsOiBQcm92aWRlIGEgcmVmIHRvIHRoZSBlbGVtZW50IHRvIGJlIG9ic2VydmVkLlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIGFuIGludGVybmFsIDxkaXYgcmVmPXsuLi59PiB3aWxsIGJlIHJlbmRlcmVkLlxuICAgKi9cbiAgdGFyZ2V0UmVmPzogeyBjdXJyZW50OiBIVE1MRWxlbWVudCB8IG51bGwgfTtcbn1cblxuLyoqXG4gKiBCcmVha3BvaW50UHJvdmlkZXIgXHVEODNEXHVERTgwXG4gKlxuICogVXNlcyByZWFjdC1yZXNpemUtZGV0ZWN0b3IgdG8gbWVhc3VyZSB0aGUgd2lkdGggb2YgYW4gZWxlbWVudCBhbmQgZGV0ZXJtaW5lIHRoZSBjdXJyZW50IGJyZWFrcG9pbnRcbiAqIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBicmVha3BvaW50cy4gQWRkaXRpb25hbGx5LCBpdCBwcm92aWRlcyB1dGlsaXR5IGZ1bmN0aW9ucyAoaXNBdExlYXN0LCBpc0JlbG93KVxuICogYW5kIHZhbHVlQnlCcmVha3BvaW50LlxuICpcbiAqIFx1MjZBMFx1RkUwRiAqKkVkZ2UgQ2FzZXMgLyBXYXJuaW5nczoqKlxuICogLSBJZiB0aGUgbWVhc3VyZWQgd2lkdGggaXMgdW5kZWZpbmVkIG9yIDAsIGFuIGVycm9yIGlzIGxvZ2dlZCBpbiB0aGUgY29uc29sZS5cbiAqIC0gSWYgdGhlIGN1cnJlbnQgd2lkdGggaXMgbGVzcyB0aGFuIHRoZSBzbWFsbGVzdCBicmVha3BvaW50IChhbmQgd2lkdGggPiAwKSwgYW4gZXJyb3IgaXMgbG9nZ2VkLlxuICogLSBJZiBkdXBsaWNhdGUgYnJlYWtwb2ludCB2YWx1ZXMgYXJlIGRldGVjdGVkLCBhbiBlcnJvciBpcyBsb2dnZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBCcmVha3BvaW50UHJvdmlkZXI6IFJlYWN0LkZDPEJyZWFrcG9pbnRQcm92aWRlclByb3BzPiA9ICh7IGJyZWFrcG9pbnRzLCBjaGlsZHJlbiwgdGFyZ2V0UmVmIH0pID0+IHtcbiAgLy8gSWYgYSB0YXJnZXRSZWYgaXMgcHJvdmlkZWQsIHVzZVJlc2l6ZURldGVjdG9yIG9ic2VydmVzIHRoYXQgZWxlbWVudDsgb3RoZXJ3aXNlLCBhbiBpbnRlcm5hbCByZWYgaXMgY3JlYXRlZC5cbiAgY29uc3QgeyB3aWR0aCwgcmVmIH0gPSB1c2VSZXNpemVEZXRlY3Rvcih7IHRhcmdldFJlZiB9KTtcblxuICAvLyBTb3J0IHRoZSBicmVha3BvaW50cyBpbiBhc2NlbmRpbmcgb3JkZXIgYmFzZWQgb24gdGhlaXIgbnVtZXJpYyB2YWx1ZXMuIFx1RDgzRFx1REQyMlxuICBjb25zdCBzb3J0ZWRCcmVha3BvaW50cyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhicmVha3BvaW50cylcbiAgICAgIC5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW2tleSwgdmFsdWVdIGFzIFtCcmVha3BvaW50LCBudW1iZXJdKVxuICAgICAgLnNvcnQoKFssIGFdLCBbLCBiXSkgPT4gYSAtIGIpO1xuICB9LCBbYnJlYWtwb2ludHNdKTtcblxuICAvKiogQ2hlY2sgZm9yIGR1cGxpY2F0ZSBicmVha3BvaW50IHZhbHVlcyAqL1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGR1cGxpY2F0ZXMgPSBzb3J0ZWRCcmVha3BvaW50cy5maWx0ZXIoXG4gICAgICAoWywgdmFsdWVdLCBpbmRleCkgPT4gc29ydGVkQnJlYWtwb2ludHMuZmluZEluZGV4KChbLCB2XSkgPT4gdiA9PT0gdmFsdWUpICE9PSBpbmRleFxuICAgICk7XG4gICAgaWYgKGR1cGxpY2F0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc29sZS5lcnJvcignQnJlYWtwb2ludFByb3ZpZGVyOiBEdXBsaWNhdGUgYnJlYWtwb2ludCB2YWx1ZXMgZGV0ZWN0ZWQuIFRoaXMgbWF5IGxlYWQgdG8gdW5leHBlY3RlZCBiZWhhdmlvci4nKTtcbiAgICB9XG4gIH0sIFtzb3J0ZWRCcmVha3BvaW50c10pO1xuXG4gIC8vIERldGVybWluZSB0aGUgY3VycmVudCBicmVha3BvaW50IGJhc2VkIG9uIHRoZSBtZWFzdXJlZCB3aWR0aC4gXHVEODNEXHVEQ0NGXG4gIGNvbnN0IGN1cnJlbnRCcmVha3BvaW50ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgaWYgKHdpZHRoID09PSB1bmRlZmluZWQpIHJldHVybiBudWxsO1xuICAgIGxldCBhY3RpdmU6IEJyZWFrcG9pbnQgfCBudWxsID0gbnVsbDtcbiAgICBzb3J0ZWRCcmVha3BvaW50cy5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICh3aWR0aCA+PSB2YWx1ZSkge1xuICAgICAgICBhY3RpdmUgPSBrZXk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjdGl2ZTtcbiAgfSwgW3dpZHRoLCBzb3J0ZWRCcmVha3BvaW50c10pO1xuXG4gIC8vIExvZyBlcnJvciBpZiB3aWR0aCA+IDAgYnV0IG5vIGJyZWFrcG9pbnQgY291bGQgYmUgZGV0ZXJtaW5lZFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICh3aWR0aCAhPT0gdW5kZWZpbmVkICYmIHdpZHRoID4gMCAmJiBjdXJyZW50QnJlYWtwb2ludCA9PT0gbnVsbCkge1xuICAgICAgaWYgKHNvcnRlZEJyZWFrcG9pbnRzLmxlbmd0aCA+IDAgJiYgd2lkdGggPCBzb3J0ZWRCcmVha3BvaW50c1swXVsxXSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGBCcmVha3BvaW50UHJvdmlkZXI6IFRoZSBjdXJyZW50IHdpZHRoICgke3dpZHRofXB4KSBpcyBsZXNzIHRoYW4gdGhlIHNtYWxsZXN0IGJyZWFrcG9pbnQgdmFsdWUgKCR7c29ydGVkQnJlYWtwb2ludHNbMF1bMV19cHgpLiBDb25zaWRlciBpbmNsdWRpbmcgYSBicmVha3BvaW50IHdpdGggYSB2YWx1ZSBvZiAwIHRvIGNvdmVyIGFsbCBjYXNlcy5gXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICdCcmVha3BvaW50UHJvdmlkZXI6IE5vIGJyZWFrcG9pbnQgY291bGQgYmUgZGV0ZXJtaW5lZCBmcm9tIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uLiBDaGVjayB5b3VyIGJyZWFrcG9pbnRzIG9iamVjdC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9LCBbd2lkdGgsIGN1cnJlbnRCcmVha3BvaW50LCBzb3J0ZWRCcmVha3BvaW50c10pO1xuXG4gIC8vIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGluZGV4IG9mIGEgYnJlYWtwb2ludCBpbiB0aGUgc29ydGVkIGFycmF5LiBcdUQ4M0RcdUREMERcbiAgY29uc3QgZ2V0QnJlYWtwb2ludEluZGV4ID0gKHNpemU6IEJyZWFrcG9pbnQpOiBudW1iZXIgPT4ge1xuICAgIHJldHVybiBzb3J0ZWRCcmVha3BvaW50cy5maW5kSW5kZXgoKFtrZXldKSA9PiBrZXkgPT09IHNpemUpO1xuICB9O1xuXG4gIGNvbnN0IGlzQXRMZWFzdCA9IChzaXplOiBCcmVha3BvaW50KTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKCFjdXJyZW50QnJlYWtwb2ludCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBnZXRCcmVha3BvaW50SW5kZXgoY3VycmVudEJyZWFrcG9pbnQpID49IGdldEJyZWFrcG9pbnRJbmRleChzaXplKTtcbiAgfTtcblxuICBjb25zdCBpc0JlbG93ID0gKHNpemU6IEJyZWFrcG9pbnQpOiBib29sZWFuID0+IHtcbiAgICBpZiAoIWN1cnJlbnRCcmVha3BvaW50KSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGdldEJyZWFrcG9pbnRJbmRleChjdXJyZW50QnJlYWtwb2ludCkgPCBnZXRCcmVha3BvaW50SW5kZXgoc2l6ZSk7XG4gIH07XG5cbiAgLy8gRGVmaW5lIHZhbHVlQnlCcmVha3BvaW50IGFzIGEgZnVuY3Rpb24gZGVjbGFyYXRpb24gdG8gYXZvaWQgSlNYIHBhcnNpbmcgaXNzdWVzIGluIFRTWCBmaWxlcy4gXHVEODNDXHVERkE4XG4gIGZ1bmN0aW9uIHZhbHVlQnlCcmVha3BvaW50PFQ+KHZhbHVlczogUGFydGlhbDxSZWNvcmQ8QnJlYWtwb2ludCwgVD4+KTogVCB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFjdXJyZW50QnJlYWtwb2ludCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdmFsdWVzW2N1cnJlbnRCcmVha3BvaW50XTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPEJyZWFrcG9pbnRDb250ZXh0LlByb3ZpZGVyXG4gICAgICB2YWx1ZT17e1xuICAgICAgICB3aWR0aDogd2lkdGggPz8gMCxcbiAgICAgICAgYnJlYWtwb2ludDogY3VycmVudEJyZWFrcG9pbnQsXG4gICAgICAgIGJyZWFrcG9pbnRzLFxuICAgICAgICBpc0F0TGVhc3QsXG4gICAgICAgIGlzQmVsb3csXG4gICAgICAgIHZhbHVlQnlCcmVha3BvaW50LFxuICAgICAgfX1cbiAgICA+XG4gICAgICB7LyogSWYgYSB0YXJnZXRSZWYgaXMgcHJvdmlkZWQsIHRoYXQgcmVmIGlzIGFscmVhZHkgYXR0YWNoZWQgdG8gYW4gZXh0ZXJuYWwgZWxlbWVudC5cbiAgICAgICAgICBPdGhlcndpc2UsIHJlbmRlciBhIDxkaXYgcmVmPXtyZWZ9PiB0byBvYnNlcnZlIGl0cyBzaXplLiBcdUQ4M0RcdURDRDAgKi99XG4gICAgICB7dGFyZ2V0UmVmID8gY2hpbGRyZW4gOiA8ZGl2IHJlZj17cmVmfT57Y2hpbGRyZW59PC9kaXY+fVxuICAgIDwvQnJlYWtwb2ludENvbnRleHQuUHJvdmlkZXI+XG4gICk7XG59O1xuXG4vKipcbiAqIEhvb2sgZm9yIGFjY2Vzc2luZyB0aGUgQnJlYWtwb2ludENvbnRleHQuXG4gKiBUaHJvd3MgYW4gZXJyb3IgaWYgdXNlZCBvdXRzaWRlIG9mIGEgQnJlYWtwb2ludFByb3ZpZGVyLiBcdTI2QTBcdUZFMEZcbiAqL1xuZXhwb3J0IGNvbnN0IHVzZUJyZWFrcG9pbnQgPSAoKTogQnJlYWtwb2ludENvbnRleHRUeXBlID0+IHtcbiAgY29uc3QgY29udGV4dCA9IHVzZUNvbnRleHQoQnJlYWtwb2ludENvbnRleHQpO1xuICBpZiAoIWNvbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZUJyZWFrcG9pbnQgbXVzdCBiZSB1c2VkIHdpdGhpbiBhIEJyZWFrcG9pbnRQcm92aWRlcicpO1xuICB9XG4gIHJldHVybiBjb250ZXh0O1xufTtcblxuaW50ZXJmYWNlIEJyZWFrcG9pbnRDb25kaXRpb25hbFByb3BzIHtcbiAgLyoqXG4gICAqIEFycmF5IG9mIGJyZWFrcG9pbnRzIGF0IHdoaWNoIHRoZSBjaGlsZHJlbiBzaG91bGQgYmUgZGlzcGxheWVkLlxuICAgKiBFLmcuOiBbJ01EJywgJ0xHJ10gcmVuZGVycyBjaGlsZHJlbiBvbmx5IGlmIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQgaXMgTUQgb3IgTEcuXG4gICAqL1xuICBzaG93PzogQnJlYWtwb2ludFtdO1xuICAvKipcbiAgICogVGhlIGNoaWxkcmVuIGFyZSBkaXNwbGF5ZWQgb25seSBpZiB0aGUgY3VycmVudCBicmVha3BvaW50IGlzIGF0IGxlYXN0IHRoaXMgdmFsdWUuXG4gICAqIEUuZy46IGlzQXRMZWFzdD1cIk1EXCIgcmVuZGVycyBjaGlsZHJlbiBmb3IgTUQsIExHLCBvciBYTC5cbiAgICovXG4gIGlzQXRMZWFzdD86IEJyZWFrcG9pbnQ7XG4gIC8qKlxuICAgKiBUaGUgY2hpbGRyZW4gYXJlIGRpc3BsYXllZCBvbmx5IGlmIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQgaXMgYmVsb3cgdGhpcyB2YWx1ZS5cbiAgICovXG4gIGlzQmVsb3c/OiBCcmVha3BvaW50O1xuICBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlO1xufVxuXG4vKipcbiAqIEJyZWFrcG9pbnRDb25kaXRpb25hbCBcdUQ4M0NcdURGQThcbiAqXG4gKiBSZW5kZXJzIGl0cyBjaGlsZHJlbiBvbmx5IGlmIGFsbCBwcm92aWRlZCBjb25kaXRpb25zIHJlZ2FyZGluZyB0aGUgY3VycmVudCBicmVha3BvaW50IGFyZSBtZXQuXG4gKi9cbmV4cG9ydCBjb25zdCBCcmVha3BvaW50Q29uZGl0aW9uYWw6IFJlYWN0LkZDPEJyZWFrcG9pbnRDb25kaXRpb25hbFByb3BzPiA9ICh7XG4gIHNob3csXG4gIGlzQXRMZWFzdDogbWluU2l6ZSxcbiAgaXNCZWxvdzogbWF4U2l6ZSxcbiAgY2hpbGRyZW4sXG59KSA9PiB7XG4gIGNvbnN0IHsgYnJlYWtwb2ludCwgaXNBdExlYXN0OiBjb250ZXh0SXNBdExlYXN0LCBpc0JlbG93OiBjb250ZXh0SXNCZWxvdyB9ID0gdXNlQnJlYWtwb2ludCgpO1xuXG4gIGxldCBzaG91bGRSZW5kZXIgPSB0cnVlO1xuXG4gIGlmIChzaG93ICYmIGJyZWFrcG9pbnQpIHtcbiAgICBzaG91bGRSZW5kZXIgPSBzaG91bGRSZW5kZXIgJiYgc2hvdy5pbmNsdWRlcyhicmVha3BvaW50KTtcbiAgfVxuICBpZiAobWluU2l6ZSkge1xuICAgIHNob3VsZFJlbmRlciA9IHNob3VsZFJlbmRlciAmJiBjb250ZXh0SXNBdExlYXN0KG1pblNpemUpO1xuICB9XG4gIGlmIChtYXhTaXplKSB7XG4gICAgc2hvdWxkUmVuZGVyID0gc2hvdWxkUmVuZGVyICYmIGNvbnRleHRJc0JlbG93KG1heFNpemUpO1xuICB9XG5cbiAgcmV0dXJuIHNob3VsZFJlbmRlciA/IDw+e2NoaWxkcmVufTwvPiA6IG51bGw7XG59OyJdLAogICJtYXBwaW5ncyI6ICJBQUFBLE9BQWdCLGlCQUFBQSxFQUFlLGNBQUFDLEVBQVksV0FBQUMsRUFBUyxhQUFBQyxNQUFpQixRQUNyRSxPQUFTLHFCQUFBQyxNQUF5Qix3QkE0SUosT0E0RE4sWUFBQUMsRUE1RE0sT0FBQUMsTUFBQSxvQkFoSDlCLElBQU1DLEVBQW9CUCxFQUFpRCxNQUFTLEVBOEJ2RVEsRUFBd0QsQ0FBQyxDQUFFLFlBQUFDLEVBQWEsU0FBQUMsRUFBVSxVQUFBQyxDQUFVLElBQU0sQ0FFN0csR0FBTSxDQUFFLE1BQUFDLEVBQU8sSUFBQUMsQ0FBSSxFQUFJVCxFQUFrQixDQUFFLFVBQUFPLENBQVUsQ0FBQyxFQUdoREcsRUFBb0JaLEVBQVEsSUFDekIsT0FBTyxRQUFRTyxDQUFXLEVBQzlCLElBQUksQ0FBQyxDQUFDTSxFQUFLQyxDQUFLLElBQU0sQ0FBQ0QsRUFBS0MsQ0FBSyxDQUF5QixFQUMxRCxLQUFLLENBQUMsQ0FBQyxDQUFFQyxDQUFDLEVBQUcsQ0FBQyxDQUFFQyxDQUFDLElBQU1ELEVBQUlDLENBQUMsRUFDOUIsQ0FBQ1QsQ0FBVyxDQUFDLEVBR2hCTixFQUFVLElBQU0sQ0FDS1csRUFBa0IsT0FDbkMsQ0FBQyxDQUFDLENBQUVFLENBQUssRUFBR0csSUFBVUwsRUFBa0IsVUFBVSxDQUFDLENBQUMsQ0FBRU0sQ0FBQyxJQUFNQSxJQUFNSixDQUFLLElBQU1HLENBQ2hGLEVBQ2UsT0FBUyxHQUN0QixRQUFRLE1BQU0saUdBQWlHLENBRW5ILEVBQUcsQ0FBQ0wsQ0FBaUIsQ0FBQyxFQUd0QixJQUFNTyxFQUFvQm5CLEVBQVEsSUFBTSxDQUN0QyxHQUFJVSxJQUFVLE9BQVcsT0FBTyxLQUNoQyxJQUFJVSxFQUE0QixLQUNoQyxPQUFBUixFQUFrQixRQUFRLENBQUMsQ0FBQ0MsRUFBS0MsQ0FBSyxJQUFNLENBQ3RDSixHQUFTSSxJQUNYTSxFQUFTUCxFQUViLENBQUMsRUFDTU8sQ0FDVCxFQUFHLENBQUNWLEVBQU9FLENBQWlCLENBQUMsRUFHN0JYLEVBQVUsSUFBTSxDQUNWUyxJQUFVLFFBQWFBLEVBQVEsR0FBS1MsSUFBc0IsT0FDeERQLEVBQWtCLE9BQVMsR0FBS0YsRUFBUUUsRUFBa0IsQ0FBQyxFQUFFLENBQUMsRUFDaEUsUUFBUSxNQUNOLDBDQUEwQ0YsQ0FBSyxtREFBbURFLEVBQWtCLENBQUMsRUFBRSxDQUFDLENBQUMsNEVBQzNILEVBRUEsUUFBUSxNQUNOLHVIQUNGLEVBR04sRUFBRyxDQUFDRixFQUFPUyxFQUFtQlAsQ0FBaUIsQ0FBQyxFQUdoRCxJQUFNUyxFQUFzQkMsR0FDbkJWLEVBQWtCLFVBQVUsQ0FBQyxDQUFDQyxDQUFHLElBQU1BLElBQVFTLENBQUksRUFHdERDLEVBQWFELEdBQ1pILEVBQ0VFLEVBQW1CRixDQUFpQixHQUFLRSxFQUFtQkMsQ0FBSSxFQUR4QyxHQUkzQkUsRUFBV0YsR0FDVkgsRUFDRUUsRUFBbUJGLENBQWlCLEVBQUlFLEVBQW1CQyxDQUFJLEVBRHZDLEdBS2pDLFNBQVNHLEVBQXFCQyxFQUF1RCxDQUNuRixHQUFLUCxFQUNMLE9BQU9PLEVBQU9QLENBQWlCLENBQ2pDLENBRUEsT0FDRWYsRUFBQ0MsRUFBa0IsU0FBbEIsQ0FDQyxNQUFPLENBQ0wsTUFBT0ssR0FBUyxFQUNoQixXQUFZUyxFQUNaLFlBQUFaLEVBQ0EsVUFBQWdCLEVBQ0EsUUFBQUMsRUFDQSxrQkFBQUMsQ0FDRixFQUlDLFNBQUFoQixFQUFZRCxFQUFXSixFQUFDLE9BQUksSUFBS08sRUFBTSxTQUFBSCxFQUFTLEVBQ25ELENBRUosRUFNYW1CLEVBQWdCLElBQTZCLENBQ3hELElBQU1DLEVBQVU3QixFQUFXTSxDQUFpQixFQUM1QyxHQUFJLENBQUN1QixFQUNILE1BQU0sSUFBSSxNQUFNLHdEQUF3RCxFQUUxRSxPQUFPQSxDQUNULEVBeUJhQyxFQUE4RCxDQUFDLENBQzFFLEtBQUFDLEVBQ0EsVUFBV0MsRUFDWCxRQUFTQyxFQUNULFNBQUF4QixDQUNGLElBQU0sQ0FDSixHQUFNLENBQUUsV0FBQXlCLEVBQVksVUFBV0MsRUFBa0IsUUFBU0MsQ0FBZSxFQUFJUixFQUFjLEVBRXZGUyxFQUFlLEdBRW5CLE9BQUlOLEdBQVFHLElBQ1ZHLEVBQWVBLEdBQWdCTixFQUFLLFNBQVNHLENBQVUsR0FFckRGLElBQ0ZLLEVBQWVBLEdBQWdCRixFQUFpQkgsQ0FBTyxHQUVyREMsSUFDRkksRUFBZUEsR0FBZ0JELEVBQWVILENBQU8sR0FHaERJLEVBQWVoQyxFQUFBRCxFQUFBLENBQUcsU0FBQUssRUFBUyxFQUFNLElBQzFDIiwKICAibmFtZXMiOiBbImNyZWF0ZUNvbnRleHQiLCAidXNlQ29udGV4dCIsICJ1c2VNZW1vIiwgInVzZUVmZmVjdCIsICJ1c2VSZXNpemVEZXRlY3RvciIsICJGcmFnbWVudCIsICJqc3giLCAiQnJlYWtwb2ludENvbnRleHQiLCAiQnJlYWtwb2ludFByb3ZpZGVyIiwgImJyZWFrcG9pbnRzIiwgImNoaWxkcmVuIiwgInRhcmdldFJlZiIsICJ3aWR0aCIsICJyZWYiLCAic29ydGVkQnJlYWtwb2ludHMiLCAia2V5IiwgInZhbHVlIiwgImEiLCAiYiIsICJpbmRleCIsICJ2IiwgImN1cnJlbnRCcmVha3BvaW50IiwgImFjdGl2ZSIsICJnZXRCcmVha3BvaW50SW5kZXgiLCAic2l6ZSIsICJpc0F0TGVhc3QiLCAiaXNCZWxvdyIsICJ2YWx1ZUJ5QnJlYWtwb2ludCIsICJ2YWx1ZXMiLCAidXNlQnJlYWtwb2ludCIsICJjb250ZXh0IiwgIkJyZWFrcG9pbnRDb25kaXRpb25hbCIsICJzaG93IiwgIm1pblNpemUiLCAibWF4U2l6ZSIsICJicmVha3BvaW50IiwgImNvbnRleHRJc0F0TGVhc3QiLCAiY29udGV4dElzQmVsb3ciLCAic2hvdWxkUmVuZGVyIl0KfQo=
1
+ import{createContext as P,useContext as w,useMemo as B,useEffect as k}from"react";import{useResizeDetector as C}from"react-resize-detector";import{Fragment as T,jsx as f}from"react/jsx-runtime";var v=P(void 0),A=({breakpoints:o,children:s,targetRef:p,devMode:d})=>{let a=d!==void 0?d:process.env.NODE_ENV!=="production",{width:r,ref:u}=C({targetRef:p}),e=B(()=>Object.entries(o).map(([t,i])=>[t,i]).sort(([,t],[,i])=>t-i),[o]);k(()=>{e.filter(([,i],c)=>e.findIndex(([,m])=>m===i)!==c).length>0&&a&&console.error("\u274C BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.")},[e]);let n=B(()=>{if(r===void 0)return null;let t=null;return e.forEach(([i,c])=>{r>=c&&(t=i)}),t},[r,e]);k(()=>{(r===void 0||r===0)&&a&&console.error("\u274C BreakpointProvider: element width is undefined or 0")},[r,a]),k(()=>{r!==void 0&&r>0&&n===null&&(e.length>0&&r<e[0][1]?a&&console.error(`\u274C BreakpointProvider: The current width (${r}px) is less than the smallest breakpoint value (${e[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`):a&&console.error("\u274C BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object."))},[r,n,e]);let l=t=>e.findIndex(([i])=>i===t),b=t=>n?l(n)>=l(t):!1,h=t=>n?l(n)<l(t):!1;function x(t){if(n)return t[n]}return f(v.Provider,{value:{width:r??0,breakpoint:n,breakpoints:o,isAtLeast:b,isBelow:h,valueByBreakpoint:x},children:p?s:f("div",{ref:u,children:s})})},R=()=>{let o=w(v);if(!o)throw new Error("useBreakpoint must be used within a BreakpointProvider");return o},E=({show:o,isAtLeast:s,isBelow:p,children:d})=>{let{breakpoint:a,isAtLeast:r,isBelow:u}=R(),e=!0;return o&&a&&(e=e&&o.includes(a)),s&&(e=e&&r(s)),p&&(e=e&&u(p)),e?f(T,{children:d}):null};export{E as BreakpointConditional,A as BreakpointProvider,R as useBreakpoint};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/BreakpointContext.tsx"],"sourcesContent":["import React, { createContext, useContext, useMemo, useEffect } from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nexport type Breakpoint = string; // Allow arbitrary breakpoint names\n\nexport interface BreakpointContextType {\n /** Current width of the observed element */\n width: number;\n /** Currently active breakpoint */\n breakpoint: Breakpoint | null;\n /** Defined breakpoints, e.g., { XS: 0, SM: 500, MD: 700, LG: 900, XL: 1100 } */\n breakpoints: Record<Breakpoint, number>;\n /**\n * Returns `true` if the current breakpoint is greater than or equal to the provided one.\n * E.g.: isAtLeast('MD') returns true if the current breakpoint is MD,\n * LG, or XL.\n */\n isAtLeast: (size: Breakpoint) => boolean;\n /**\n * Returns `true` if the current breakpoint is less than the provided one.\n */\n isBelow: (size: Breakpoint) => boolean;\n /**\n * Returns a value from the mapping based on the current breakpoint.\n * E.g.: valueByBreakpoint({ MD: 3, LG: 2 }) returns 3 for MD and 2 for LG.\n */\n valueByBreakpoint: <T>(values: Partial<Record<Breakpoint, T>>) => T | undefined;\n}\n\nconst BreakpointContext = createContext<BreakpointContextType | undefined>(undefined);\n\n/**\n * Instead of using React.RefObject<HTMLElement> (which is invariant),\n * we use a structural type that accepts any object with a `current: HTMLElement | null` property.\n */\nexport interface BreakpointProviderProps {\n /** Defined breakpoints */\n breakpoints: Record<Breakpoint, number>;\n /** Child components that use the context */\n children: React.ReactNode;\n /**\n * Optional: Provide a ref to the element to be observed.\n * If not provided, an internal <div ref={...}> will be rendered.\n */\n targetRef?: { current: HTMLElement | null };\n /**\n * Optional: Enable development mode to show console warnings and errors.\n * Defaults to false in production (NODE_ENV === 'production').\n */\n devMode?: boolean;\n}\n\n/**\n * BreakpointProvider 🚀\n *\n * Uses react-resize-detector to measure the width of an element and determine the current breakpoint\n * based on the provided breakpoints. Additionally, it provides utility functions (isAtLeast, isBelow)\n * and valueByBreakpoint.\n *\n * ⚠️ **Edge Cases / Warnings:**\n * - If the measured width is undefined or 0, an error is logged in the console.\n * - If the current width is less than the smallest breakpoint (and width > 0), an error is logged.\n * - If duplicate breakpoint values are detected, an error is logged.\n */\nexport const BreakpointProvider: React.FC<BreakpointProviderProps> = ({\n breakpoints,\n children,\n targetRef,\n devMode,\n}) => {\n // Determine if we should log based on devMode prop or NODE_ENV\n const shouldLog = devMode !== undefined ? devMode : process.env.NODE_ENV !== 'production';\n // If a targetRef is provided, useResizeDetector observes that element; otherwise, an internal ref is created.\n const { width, ref } = useResizeDetector({ targetRef });\n\n // Sort the breakpoints in ascending order based on their numeric values. 🔢\n const sortedBreakpoints = useMemo(() => {\n return Object.entries(breakpoints)\n .map(([key, value]) => [key, value] as [Breakpoint, number])\n .sort(([, a], [, b]) => a - b);\n }, [breakpoints]);\n\n /** Check for duplicate breakpoint values */\n useEffect(() => {\n const duplicates = sortedBreakpoints.filter(\n ([, value], index) => sortedBreakpoints.findIndex(([, v]) => v === value) !== index\n );\n if (duplicates.length > 0) {\n if (shouldLog) {\n console.error(\n '❌ BreakpointProvider: Duplicate breakpoint values detected. This may lead to unexpected behavior.'\n );\n }\n }\n }, [sortedBreakpoints]);\n\n // Determine the current breakpoint based on the measured width. 📏\n const currentBreakpoint = useMemo(() => {\n if (width === undefined) return null;\n let active: Breakpoint | null = null;\n sortedBreakpoints.forEach(([key, value]) => {\n if (width >= value) {\n active = key;\n }\n });\n return active;\n }, [width, sortedBreakpoints]);\n\n // Log error if width is undefined or 0\n useEffect(() => {\n if (width === undefined || width === 0) {\n if (shouldLog) {\n console.error('❌ BreakpointProvider: element width is undefined or 0');\n }\n }\n }, [width, shouldLog]);\n\n // Log error if width > 0 but no breakpoint could be determined\n useEffect(() => {\n if (width !== undefined && width > 0 && currentBreakpoint === null) {\n if (sortedBreakpoints.length > 0 && width < sortedBreakpoints[0][1]) {\n if (shouldLog) {\n console.error(\n `❌ BreakpointProvider: The current width (${width}px) is less than the smallest breakpoint value (${sortedBreakpoints[0][1]}px). Consider including a breakpoint with a value of 0 to cover all cases.`\n );\n }\n } else {\n if (shouldLog) {\n console.error(\n '❌ BreakpointProvider: No breakpoint could be determined from the provided configuration. Check your breakpoints object.'\n );\n }\n }\n }\n }, [width, currentBreakpoint, sortedBreakpoints]);\n\n // Helper function to get the index of a breakpoint in the sorted array. 🔍\n const getBreakpointIndex = (size: Breakpoint): number => {\n return sortedBreakpoints.findIndex(([key]) => key === size);\n };\n\n const isAtLeast = (size: Breakpoint): boolean => {\n if (!currentBreakpoint) return false;\n return getBreakpointIndex(currentBreakpoint) >= getBreakpointIndex(size);\n };\n\n const isBelow = (size: Breakpoint): boolean => {\n if (!currentBreakpoint) return false;\n return getBreakpointIndex(currentBreakpoint) < getBreakpointIndex(size);\n };\n\n // Define valueByBreakpoint as a function declaration to avoid JSX parsing issues in TSX files. 🎨\n function valueByBreakpoint<T>(values: Partial<Record<Breakpoint, T>>): T | undefined {\n if (!currentBreakpoint) return undefined;\n return values[currentBreakpoint];\n }\n\n return (\n <BreakpointContext.Provider\n value={{\n width: width ?? 0,\n breakpoint: currentBreakpoint,\n breakpoints,\n isAtLeast,\n isBelow,\n valueByBreakpoint,\n }}\n >\n {/* If a targetRef is provided, that ref is already attached to an external element.\n Otherwise, render a <div ref={ref}> to observe its size. 📐 */}\n {targetRef ? children : <div ref={ref}>{children}</div>}\n </BreakpointContext.Provider>\n );\n};\n\n/**\n * Hook for accessing the BreakpointContext.\n * Throws an error if used outside of a BreakpointProvider. ⚠️\n */\nexport const useBreakpoint = (): BreakpointContextType => {\n const context = useContext(BreakpointContext);\n if (!context) {\n throw new Error('useBreakpoint must be used within a BreakpointProvider');\n }\n return context;\n};\n\ninterface BreakpointConditionalProps {\n /**\n * Array of breakpoints at which the children should be displayed.\n * E.g.: ['MD', 'LG'] renders children only if the current breakpoint is MD or LG.\n */\n show?: Breakpoint[];\n /**\n * The children are displayed only if the current breakpoint is at least this value.\n * E.g.: isAtLeast=\"MD\" renders children for MD, LG, or XL.\n */\n isAtLeast?: Breakpoint;\n /**\n * The children are displayed only if the current breakpoint is below this value.\n */\n isBelow?: Breakpoint;\n children: React.ReactNode;\n}\n\n/**\n * BreakpointConditional 🎨\n *\n * Renders its children only if all provided conditions regarding the current breakpoint are met.\n */\nexport const BreakpointConditional: React.FC<BreakpointConditionalProps> = ({\n show,\n isAtLeast: minSize,\n isBelow: maxSize,\n children,\n}) => {\n const { breakpoint, isAtLeast: contextIsAtLeast, isBelow: contextIsBelow } = useBreakpoint();\n\n let shouldRender = true;\n\n if (show && breakpoint) {\n shouldRender = shouldRender && show.includes(breakpoint);\n }\n if (minSize) {\n shouldRender = shouldRender && contextIsAtLeast(minSize);\n }\n if (maxSize) {\n shouldRender = shouldRender && contextIsBelow(maxSize);\n }\n\n return shouldRender ? <>{children}</> : null;\n};\n"],"mappings":"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","names":["createContext","useContext","useMemo","useEffect","useResizeDetector","Fragment","jsx","BreakpointContext","BreakpointProvider","breakpoints","children","targetRef","devMode","shouldLog","width","ref","sortedBreakpoints","key","value","a","b","index","v","currentBreakpoint","active","getBreakpointIndex","size","isAtLeast","isBelow","valueByBreakpoint","values","useBreakpoint","context","BreakpointConditional","show","minSize","maxSize","breakpoint","contextIsAtLeast","contextIsBelow","shouldRender"]}
package/package.json CHANGED
@@ -1,13 +1,23 @@
1
1
  {
2
2
  "name": "react-resize-detector-context",
3
- "description": "",
4
- "version": "0.1.2",
5
- "author": "",
6
- "license": "",
7
- "keywords": [],
3
+ "description": "React context that detects element width and provides responsive breakpoint utilities with conditional rendering components",
4
+ "version": "0.2.1",
5
+ "author": "Christopher Schwarz",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "react",
9
+ "resize",
10
+ "detector",
11
+ "breakpoint",
12
+ "responsive",
13
+ "context",
14
+ "width",
15
+ "conditional",
16
+ "rendering"
17
+ ],
8
18
  "repository": {
9
19
  "type": "git",
10
- "url": ""
20
+ "url": "https://github.com/smartlabsat/react-resize-detector-context"
11
21
  },
12
22
  "scripts": {
13
23
  "dev": "concurrently \"pnpm build --watch\" \"pnpm storybook\" \"pnpm test\" ",
@@ -17,6 +27,7 @@
17
27
  "format": "prettier --write src",
18
28
  "test": "vitest",
19
29
  "test:ci": "vitest run --coverage",
30
+ "typecheck": "tsc --noEmit",
20
31
  "commit": "cz",
21
32
  "storybook": "storybook dev -p 6006",
22
33
  "storybook:build": "storybook build",
@@ -60,21 +71,21 @@
60
71
  "node": ">=18.0.0"
61
72
  },
62
73
  "devDependencies": {
63
- "@emotion/styled": "^11.14.0",
64
- "@eslint/js": "^9.20.0",
74
+ "@emotion/styled": "^11.14.1",
75
+ "@eslint/js": "^9.33.0",
65
76
  "@mui/material": "^6.4.3",
66
77
  "@ryansonshine/commitizen": "4.2.8",
67
78
  "@ryansonshine/cz-conventional-changelog": "3.3.4",
68
- "@storybook/addon-essentials": "8.4.7",
69
- "@storybook/addon-interactions": "8.4.7",
70
- "@storybook/addon-links": "8.4.7",
79
+ "@storybook/addon-essentials": "8.6.14",
80
+ "@storybook/addon-interactions": "8.6.14",
81
+ "@storybook/addon-links": "8.6.14",
71
82
  "@storybook/addon-webpack5-compiler-swc": "2.0.0",
72
- "@storybook/blocks": "8.4.7",
73
- "@storybook/react": "8.4.7",
74
- "@storybook/react-webpack5": "8.4.7",
75
- "@storybook/test": "8.4.7",
83
+ "@storybook/blocks": "8.6.14",
84
+ "@storybook/react": "8.6.14",
85
+ "@storybook/react-webpack5": "8.6.14",
86
+ "@storybook/test": "8.6.14",
76
87
  "@testing-library/jest-dom": "6.6.3",
77
- "@testing-library/react": "^16.1.0",
88
+ "@testing-library/react": "^16.3.0",
78
89
  "@types/node": "22.10.5",
79
90
  "@types/react": "18.3.13",
80
91
  "@types/react-dom": "18.3.1",
@@ -82,26 +93,26 @@
82
93
  "@types/testing-library__jest-dom": "^5.14.9",
83
94
  "@vitest/coverage-v8": "2.1.8",
84
95
  "concurrently": "9.1.2",
85
- "eslint": "^9.20.0",
86
- "eslint-plugin-react": "^7.37.4",
96
+ "eslint": "^9.33.0",
97
+ "eslint-plugin-react": "^7.37.5",
87
98
  "globals": "^15.14.0",
88
99
  "husky": "^9.1.7",
89
100
  "jsdom": "25.0.1",
90
101
  "lefthook": "1.10.1",
91
102
  "lint-staged": "^15.4.3",
92
- "prettier": "^3.5.0",
103
+ "prettier": "^3.6.2",
93
104
  "prop-types": "15.8.1",
94
105
  "react": "18.3.1",
95
106
  "react-dom": "18.3.1",
96
107
  "react-test-renderer": "18.3.1",
97
108
  "release-it": "17.11.0",
98
- "storybook": "8.4.7",
109
+ "storybook": "8.6.14",
99
110
  "ts-node": "10.9.2",
100
111
  "tsconfig-paths": "4.2.0",
101
112
  "tsup": "8.3.5",
102
113
  "tsx": "4.19.2",
103
114
  "typescript": "5.7.2",
104
- "typescript-eslint": "^8.23.0",
115
+ "typescript-eslint": "^8.40.0",
105
116
  "vitest": "^2.1.8"
106
117
  },
107
118
  "peerDependencies": {
@@ -114,7 +125,6 @@
114
125
  }
115
126
  },
116
127
  "dependencies": {
117
- "@emotion/styled": "^11.14.0",
118
- "react-resize-detector": "^12.0.2"
128
+ "react-resize-detector": "^12.1.0"
119
129
  }
120
130
  }