@kaizen/components 0.0.0-canary-useContainerQuery-20251123222018 → 0.0.0-canary-useContainerQuery-20251125222037

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.
@@ -3,12 +3,6 @@
3
3
  var tslib = require('tslib');
4
4
  var React = require('react');
5
5
  var useDebounce = require('use-debounce');
6
- function _interopDefault(e) {
7
- return e && e.__esModule ? e : {
8
- default: e
9
- };
10
- }
11
- var React__default = /*#__PURE__*/_interopDefault(React);
12
6
  var DEFAULT_DEBOUNCE_MS = 500;
13
7
  /**
14
8
  * Tailwind CSS default container query breakpoints in pixels
@@ -50,21 +44,17 @@ var parseBreakpointValue = function (value) {
50
44
  *
51
45
  * @returns An object containing:
52
46
  * - containerRef: A ref to attach to your container element
53
- * - queries: Boolean flags for each breakpoint (isXs, isSm, isMd, etc.) and custom queries
54
- * - components: React components for conditional rendering (XsOnly, SmOrLarger, etc.)
47
+ * - queries: Boolean flags for each breakpoint (isXsOrLarger, isSmOrLarger, isMdOrLarger, etc.) and custom queries
55
48
  *
56
49
  * @example
57
50
  * ```tsx
58
51
  * const MyComponent = () => {
59
- * const { containerRef, queries, components } = useContainerQueries()
60
- * const { MdOrLarger } = components
52
+ * const { containerRef, queries } = useContainerQueries()
61
53
  *
62
54
  * return (
63
55
  * <div ref={containerRef}>
64
- * {queries.isSm && <p>Small container</p>}
65
- * <MdOrLarger>
66
- * <p>Medium or larger container</p>
67
- * </MdOrLarger>
56
+ * {queries.isSmOrLarger && <p>Small container</p>}
57
+ * {queries.isMdOrLarger && <p>Medium or larger container</p>}
68
58
  * </div>
69
59
  * )
70
60
  * }
@@ -72,16 +62,15 @@ var parseBreakpointValue = function (value) {
72
62
  *
73
63
  * @example With custom queries
74
64
  * ```tsx
75
- * const { containerRef, queries, components } = useContainerQueries({
65
+ * const { containerRef, queries } = useContainerQueries({
76
66
  * compact: '400px',
77
67
  * spacious: '800px',
78
68
  * })
79
- * const { Compact, Spacious } = components
80
69
  *
81
70
  * return (
82
71
  * <div ref={containerRef}>
83
- * <Compact><p>Compact view</p></Compact>
84
- * <Spacious><p>Spacious view</p></Spacious>
72
+ * {queries.compact && <p>Compact view</p>}
73
+ * {queries.spacious && <p>Spacious view</p>}
85
74
  * </div>
86
75
  * )
87
76
  * ```
@@ -90,76 +79,7 @@ var useContainerQueries = function (propQueries) {
90
79
  if (propQueries === void 0) {
91
80
  propQueries = {};
92
81
  }
93
- // SSR support - return safe defaults when window is undefined
94
- if (typeof window === 'undefined') {
95
- return {
96
- // eslint-disable-next-line @typescript-eslint/no-empty-function
97
- containerRef: function () {},
98
- queries: {
99
- isXs: false,
100
- isSm: false,
101
- isMd: false,
102
- isLg: false,
103
- isXl: false,
104
- is2xl: false,
105
- is3xl: false,
106
- is4xl: false,
107
- is5xl: false,
108
- is6xl: false,
109
- is7xl: true // Default to largest for SSR
110
- },
111
- components: {
112
- 'XsOnly': function () {
113
- return React__default.default.createElement(React__default.default.Fragment, null);
114
- },
115
- 'SmOnly': function () {
116
- return React__default.default.createElement(React__default.default.Fragment, null);
117
- },
118
- 'MdOnly': function () {
119
- return React__default.default.createElement(React__default.default.Fragment, null);
120
- },
121
- 'LgOnly': function () {
122
- return React__default.default.createElement(React__default.default.Fragment, null);
123
- },
124
- 'XlOnly': function () {
125
- return React__default.default.createElement(React__default.default.Fragment, null);
126
- },
127
- '2xlOnly': function () {
128
- return React__default.default.createElement(React__default.default.Fragment, null);
129
- },
130
- '3xlOnly': function () {
131
- return React__default.default.createElement(React__default.default.Fragment, null);
132
- },
133
- '4xlOnly': function () {
134
- return React__default.default.createElement(React__default.default.Fragment, null);
135
- },
136
- '5xlOnly': function () {
137
- return React__default.default.createElement(React__default.default.Fragment, null);
138
- },
139
- '6xlOnly': function () {
140
- return React__default.default.createElement(React__default.default.Fragment, null);
141
- },
142
- '7xlOnly': function (props) {
143
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
144
- },
145
- 'XsOrLarger': function (props) {
146
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
147
- },
148
- 'SmOrLarger': function (props) {
149
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
150
- },
151
- 'MdOrLarger': function (props) {
152
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
153
- },
154
- 'LgOrLarger': function (props) {
155
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
156
- },
157
- 'XlOrLarger': function (props) {
158
- return React__default.default.createElement(React__default.default.Fragment, null, props.children);
159
- }
160
- }
161
- };
162
- }
82
+ var isClient = typeof window !== 'undefined';
163
83
  // Parse custom queries
164
84
  var customQueriesPx = React.useMemo(function () {
165
85
  return Object.entries(propQueries).reduce(function (acc, _a) {
@@ -181,6 +101,8 @@ var useContainerQueries = function (propQueries) {
181
101
  }, DEFAULT_DEBOUNCE_MS);
182
102
  // Callback ref for the container element
183
103
  var containerRef = React.useCallback(function (node) {
104
+ // Skip if SSR
105
+ if (!isClient) return;
184
106
  // Cleanup previous observer
185
107
  if (resizeObserverRef.current) {
186
108
  resizeObserverRef.current.disconnect();
@@ -202,7 +124,7 @@ var useContainerQueries = function (propQueries) {
202
124
  var width = node.getBoundingClientRect().width;
203
125
  setContainerWidth(width);
204
126
  }
205
- }, [debouncedSetContainerWidth]);
127
+ }, [debouncedSetContainerWidth, isClient]);
206
128
  // Cleanup on unmount
207
129
  React.useEffect(function () {
208
130
  return function () {
@@ -214,17 +136,17 @@ var useContainerQueries = function (propQueries) {
214
136
  // Calculate breakpoint matches based on container width
215
137
  var breakpointMatches = React.useMemo(function () {
216
138
  return {
217
- isXs: containerWidth >= DEFAULT_BREAKPOINTS.xs,
218
- isSm: containerWidth >= DEFAULT_BREAKPOINTS.sm,
219
- isMd: containerWidth >= DEFAULT_BREAKPOINTS.md,
220
- isLg: containerWidth >= DEFAULT_BREAKPOINTS.lg,
221
- isXl: containerWidth >= DEFAULT_BREAKPOINTS.xl,
222
- is2xl: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
223
- is3xl: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
224
- is4xl: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
225
- is5xl: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
226
- is6xl: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
227
- is7xl: containerWidth >= DEFAULT_BREAKPOINTS['7xl']
139
+ isXsOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xs,
140
+ isSmOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.sm,
141
+ isMdOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.md,
142
+ isLgOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.lg,
143
+ isXlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xl,
144
+ is2xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
145
+ is3xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
146
+ is4xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
147
+ is5xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
148
+ is6xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
149
+ is7xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['7xl']
228
150
  };
229
151
  }, [containerWidth]);
230
152
  // Calculate custom query matches
@@ -236,85 +158,9 @@ var useContainerQueries = function (propQueries) {
236
158
  return acc;
237
159
  }, {});
238
160
  }, [containerWidth, customQueriesPx]);
239
- // Helper function to check if container is at exact breakpoint (not larger)
240
- var isExactBreakpoint = React.useCallback(function (breakpoint) {
241
- var sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(function (_a, _b) {
242
- var a = _a[1];
243
- var b = _b[1];
244
- return a - b;
245
- });
246
- var currentIndex = sortedBreakpoints.findIndex(function (_a) {
247
- var key = _a[0];
248
- return key === breakpoint;
249
- });
250
- var nextBreakpoint = sortedBreakpoints[currentIndex + 1];
251
- var minWidth = DEFAULT_BREAKPOINTS[breakpoint];
252
- var maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity;
253
- return containerWidth >= minWidth && containerWidth < maxWidth;
254
- }, [containerWidth]);
255
- // Create helper components for Tailwind breakpoints
256
- var components = React.useMemo(function () {
257
- return tslib.__assign({
258
- 'XsOnly': function (props) {
259
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('xs') && props.children);
260
- },
261
- 'SmOnly': function (props) {
262
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('sm') && props.children);
263
- },
264
- 'MdOnly': function (props) {
265
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('md') && props.children);
266
- },
267
- 'LgOnly': function (props) {
268
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('lg') && props.children);
269
- },
270
- 'XlOnly': function (props) {
271
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('xl') && props.children);
272
- },
273
- '2xlOnly': function (props) {
274
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('2xl') && props.children);
275
- },
276
- '3xlOnly': function (props) {
277
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('3xl') && props.children);
278
- },
279
- '4xlOnly': function (props) {
280
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('4xl') && props.children);
281
- },
282
- '5xlOnly': function (props) {
283
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('5xl') && props.children);
284
- },
285
- '6xlOnly': function (props) {
286
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('6xl') && props.children);
287
- },
288
- '7xlOnly': function (props) {
289
- return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('7xl') && props.children);
290
- },
291
- 'XsOrLarger': function (props) {
292
- return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isXs && props.children);
293
- },
294
- 'SmOrLarger': function (props) {
295
- return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isSm && props.children);
296
- },
297
- 'MdOrLarger': function (props) {
298
- return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isMd && props.children);
299
- },
300
- 'LgOrLarger': function (props) {
301
- return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isLg && props.children);
302
- },
303
- 'XlOrLarger': function (props) {
304
- return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isXl && props.children);
305
- }
306
- }, Object.keys(customQueriesPx).reduce(function (acc, key) {
307
- var componentName = key.charAt(0).toUpperCase() + key.slice(1);
308
- acc[componentName] = function (props) {
309
- return React__default.default.createElement(React__default.default.Fragment, null, customMatches[key] && props.children);
310
- };
311
- return acc;
312
- }, {}));
313
- }, [breakpointMatches, customMatches, isExactBreakpoint, customQueriesPx]);
314
161
  return {
315
162
  containerRef: containerRef,
316
- queries: tslib.__assign(tslib.__assign({}, breakpointMatches), customMatches),
317
- components: components
163
+ queries: tslib.__assign(tslib.__assign({}, breakpointMatches), customMatches)
318
164
  };
319
165
  };
320
166
  exports.useContainerQueries = useContainerQueries;
@@ -1,5 +1,5 @@
1
1
  import { __assign } from 'tslib';
2
- import React, { useMemo, useState, useRef, useCallback, useEffect } from 'react';
2
+ import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
3
3
  import { useDebouncedCallback } from 'use-debounce';
4
4
  var DEFAULT_DEBOUNCE_MS = 500;
5
5
  /**
@@ -42,21 +42,17 @@ var parseBreakpointValue = function (value) {
42
42
  *
43
43
  * @returns An object containing:
44
44
  * - containerRef: A ref to attach to your container element
45
- * - queries: Boolean flags for each breakpoint (isXs, isSm, isMd, etc.) and custom queries
46
- * - components: React components for conditional rendering (XsOnly, SmOrLarger, etc.)
45
+ * - queries: Boolean flags for each breakpoint (isXsOrLarger, isSmOrLarger, isMdOrLarger, etc.) and custom queries
47
46
  *
48
47
  * @example
49
48
  * ```tsx
50
49
  * const MyComponent = () => {
51
- * const { containerRef, queries, components } = useContainerQueries()
52
- * const { MdOrLarger } = components
50
+ * const { containerRef, queries } = useContainerQueries()
53
51
  *
54
52
  * return (
55
53
  * <div ref={containerRef}>
56
- * {queries.isSm && <p>Small container</p>}
57
- * <MdOrLarger>
58
- * <p>Medium or larger container</p>
59
- * </MdOrLarger>
54
+ * {queries.isSmOrLarger && <p>Small container</p>}
55
+ * {queries.isMdOrLarger && <p>Medium or larger container</p>}
60
56
  * </div>
61
57
  * )
62
58
  * }
@@ -64,16 +60,15 @@ var parseBreakpointValue = function (value) {
64
60
  *
65
61
  * @example With custom queries
66
62
  * ```tsx
67
- * const { containerRef, queries, components } = useContainerQueries({
63
+ * const { containerRef, queries } = useContainerQueries({
68
64
  * compact: '400px',
69
65
  * spacious: '800px',
70
66
  * })
71
- * const { Compact, Spacious } = components
72
67
  *
73
68
  * return (
74
69
  * <div ref={containerRef}>
75
- * <Compact><p>Compact view</p></Compact>
76
- * <Spacious><p>Spacious view</p></Spacious>
70
+ * {queries.compact && <p>Compact view</p>}
71
+ * {queries.spacious && <p>Spacious view</p>}
77
72
  * </div>
78
73
  * )
79
74
  * ```
@@ -82,76 +77,7 @@ var useContainerQueries = function (propQueries) {
82
77
  if (propQueries === void 0) {
83
78
  propQueries = {};
84
79
  }
85
- // SSR support - return safe defaults when window is undefined
86
- if (typeof window === 'undefined') {
87
- return {
88
- // eslint-disable-next-line @typescript-eslint/no-empty-function
89
- containerRef: function () {},
90
- queries: {
91
- isXs: false,
92
- isSm: false,
93
- isMd: false,
94
- isLg: false,
95
- isXl: false,
96
- is2xl: false,
97
- is3xl: false,
98
- is4xl: false,
99
- is5xl: false,
100
- is6xl: false,
101
- is7xl: true // Default to largest for SSR
102
- },
103
- components: {
104
- 'XsOnly': function () {
105
- return /*#__PURE__*/React.createElement(React.Fragment, null);
106
- },
107
- 'SmOnly': function () {
108
- return /*#__PURE__*/React.createElement(React.Fragment, null);
109
- },
110
- 'MdOnly': function () {
111
- return /*#__PURE__*/React.createElement(React.Fragment, null);
112
- },
113
- 'LgOnly': function () {
114
- return /*#__PURE__*/React.createElement(React.Fragment, null);
115
- },
116
- 'XlOnly': function () {
117
- return /*#__PURE__*/React.createElement(React.Fragment, null);
118
- },
119
- '2xlOnly': function () {
120
- return /*#__PURE__*/React.createElement(React.Fragment, null);
121
- },
122
- '3xlOnly': function () {
123
- return /*#__PURE__*/React.createElement(React.Fragment, null);
124
- },
125
- '4xlOnly': function () {
126
- return /*#__PURE__*/React.createElement(React.Fragment, null);
127
- },
128
- '5xlOnly': function () {
129
- return /*#__PURE__*/React.createElement(React.Fragment, null);
130
- },
131
- '6xlOnly': function () {
132
- return /*#__PURE__*/React.createElement(React.Fragment, null);
133
- },
134
- '7xlOnly': function (props) {
135
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
136
- },
137
- 'XsOrLarger': function (props) {
138
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
139
- },
140
- 'SmOrLarger': function (props) {
141
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
142
- },
143
- 'MdOrLarger': function (props) {
144
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
145
- },
146
- 'LgOrLarger': function (props) {
147
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
148
- },
149
- 'XlOrLarger': function (props) {
150
- return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
151
- }
152
- }
153
- };
154
- }
80
+ var isClient = typeof window !== 'undefined';
155
81
  // Parse custom queries
156
82
  var customQueriesPx = useMemo(function () {
157
83
  return Object.entries(propQueries).reduce(function (acc, _a) {
@@ -173,6 +99,8 @@ var useContainerQueries = function (propQueries) {
173
99
  }, DEFAULT_DEBOUNCE_MS);
174
100
  // Callback ref for the container element
175
101
  var containerRef = useCallback(function (node) {
102
+ // Skip if SSR
103
+ if (!isClient) return;
176
104
  // Cleanup previous observer
177
105
  if (resizeObserverRef.current) {
178
106
  resizeObserverRef.current.disconnect();
@@ -194,7 +122,7 @@ var useContainerQueries = function (propQueries) {
194
122
  var width = node.getBoundingClientRect().width;
195
123
  setContainerWidth(width);
196
124
  }
197
- }, [debouncedSetContainerWidth]);
125
+ }, [debouncedSetContainerWidth, isClient]);
198
126
  // Cleanup on unmount
199
127
  useEffect(function () {
200
128
  return function () {
@@ -206,17 +134,17 @@ var useContainerQueries = function (propQueries) {
206
134
  // Calculate breakpoint matches based on container width
207
135
  var breakpointMatches = useMemo(function () {
208
136
  return {
209
- isXs: containerWidth >= DEFAULT_BREAKPOINTS.xs,
210
- isSm: containerWidth >= DEFAULT_BREAKPOINTS.sm,
211
- isMd: containerWidth >= DEFAULT_BREAKPOINTS.md,
212
- isLg: containerWidth >= DEFAULT_BREAKPOINTS.lg,
213
- isXl: containerWidth >= DEFAULT_BREAKPOINTS.xl,
214
- is2xl: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
215
- is3xl: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
216
- is4xl: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
217
- is5xl: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
218
- is6xl: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
219
- is7xl: containerWidth >= DEFAULT_BREAKPOINTS['7xl']
137
+ isXsOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xs,
138
+ isSmOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.sm,
139
+ isMdOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.md,
140
+ isLgOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.lg,
141
+ isXlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xl,
142
+ is2xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
143
+ is3xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
144
+ is4xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
145
+ is5xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
146
+ is6xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
147
+ is7xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['7xl']
220
148
  };
221
149
  }, [containerWidth]);
222
150
  // Calculate custom query matches
@@ -228,85 +156,9 @@ var useContainerQueries = function (propQueries) {
228
156
  return acc;
229
157
  }, {});
230
158
  }, [containerWidth, customQueriesPx]);
231
- // Helper function to check if container is at exact breakpoint (not larger)
232
- var isExactBreakpoint = useCallback(function (breakpoint) {
233
- var sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(function (_a, _b) {
234
- var a = _a[1];
235
- var b = _b[1];
236
- return a - b;
237
- });
238
- var currentIndex = sortedBreakpoints.findIndex(function (_a) {
239
- var key = _a[0];
240
- return key === breakpoint;
241
- });
242
- var nextBreakpoint = sortedBreakpoints[currentIndex + 1];
243
- var minWidth = DEFAULT_BREAKPOINTS[breakpoint];
244
- var maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity;
245
- return containerWidth >= minWidth && containerWidth < maxWidth;
246
- }, [containerWidth]);
247
- // Create helper components for Tailwind breakpoints
248
- var components = useMemo(function () {
249
- return __assign({
250
- 'XsOnly': function (props) {
251
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('xs') && props.children);
252
- },
253
- 'SmOnly': function (props) {
254
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('sm') && props.children);
255
- },
256
- 'MdOnly': function (props) {
257
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('md') && props.children);
258
- },
259
- 'LgOnly': function (props) {
260
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('lg') && props.children);
261
- },
262
- 'XlOnly': function (props) {
263
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('xl') && props.children);
264
- },
265
- '2xlOnly': function (props) {
266
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('2xl') && props.children);
267
- },
268
- '3xlOnly': function (props) {
269
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('3xl') && props.children);
270
- },
271
- '4xlOnly': function (props) {
272
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('4xl') && props.children);
273
- },
274
- '5xlOnly': function (props) {
275
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('5xl') && props.children);
276
- },
277
- '6xlOnly': function (props) {
278
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('6xl') && props.children);
279
- },
280
- '7xlOnly': function (props) {
281
- return /*#__PURE__*/React.createElement(React.Fragment, null, isExactBreakpoint('7xl') && props.children);
282
- },
283
- 'XsOrLarger': function (props) {
284
- return /*#__PURE__*/React.createElement(React.Fragment, null, breakpointMatches.isXs && props.children);
285
- },
286
- 'SmOrLarger': function (props) {
287
- return /*#__PURE__*/React.createElement(React.Fragment, null, breakpointMatches.isSm && props.children);
288
- },
289
- 'MdOrLarger': function (props) {
290
- return /*#__PURE__*/React.createElement(React.Fragment, null, breakpointMatches.isMd && props.children);
291
- },
292
- 'LgOrLarger': function (props) {
293
- return /*#__PURE__*/React.createElement(React.Fragment, null, breakpointMatches.isLg && props.children);
294
- },
295
- 'XlOrLarger': function (props) {
296
- return /*#__PURE__*/React.createElement(React.Fragment, null, breakpointMatches.isXl && props.children);
297
- }
298
- }, Object.keys(customQueriesPx).reduce(function (acc, key) {
299
- var componentName = key.charAt(0).toUpperCase() + key.slice(1);
300
- acc[componentName] = function (props) {
301
- return /*#__PURE__*/React.createElement(React.Fragment, null, customMatches[key] && props.children);
302
- };
303
- return acc;
304
- }, {}));
305
- }, [breakpointMatches, customMatches, isExactBreakpoint, customQueriesPx]);
306
159
  return {
307
160
  containerRef: containerRef,
308
- queries: __assign(__assign({}, breakpointMatches), customMatches),
309
- components: components
161
+ queries: __assign(__assign({}, breakpointMatches), customMatches)
310
162
  };
311
163
  };
312
164
  export { useContainerQueries };
@@ -1,41 +1,19 @@
1
- import React, { type ReactNode } from 'react';
1
+ import type React from 'react';
2
2
  type Props = Record<string, string>;
3
- type GenericChildrenType = {
4
- children?: ReactNode;
5
- };
6
3
  type ContainerQueries = {
7
- isXs: boolean;
8
- isSm: boolean;
9
- isMd: boolean;
10
- isLg: boolean;
11
- isXl: boolean;
12
- is2xl: boolean;
13
- is3xl: boolean;
14
- is4xl: boolean;
15
- is5xl: boolean;
16
- is6xl: boolean;
17
- is7xl: boolean;
4
+ isXsOrLarger: boolean;
5
+ isSmOrLarger: boolean;
6
+ isMdOrLarger: boolean;
7
+ isLgOrLarger: boolean;
8
+ isXlOrLarger: boolean;
9
+ is2xlOrLarger: boolean;
10
+ is3xlOrLarger: boolean;
11
+ is4xlOrLarger: boolean;
12
+ is5xlOrLarger: boolean;
13
+ is6xlOrLarger: boolean;
14
+ is7xlOrLarger: boolean;
18
15
  [key: string]: boolean;
19
16
  };
20
- type ContainerComponents = {
21
- 'XsOnly': (props: GenericChildrenType) => JSX.Element;
22
- 'SmOnly': (props: GenericChildrenType) => JSX.Element;
23
- 'MdOnly': (props: GenericChildrenType) => JSX.Element;
24
- 'LgOnly': (props: GenericChildrenType) => JSX.Element;
25
- 'XlOnly': (props: GenericChildrenType) => JSX.Element;
26
- '2xlOnly': (props: GenericChildrenType) => JSX.Element;
27
- '3xlOnly': (props: GenericChildrenType) => JSX.Element;
28
- '4xlOnly': (props: GenericChildrenType) => JSX.Element;
29
- '5xlOnly': (props: GenericChildrenType) => JSX.Element;
30
- '6xlOnly': (props: GenericChildrenType) => JSX.Element;
31
- '7xlOnly': (props: GenericChildrenType) => JSX.Element;
32
- 'XsOrLarger': (props: GenericChildrenType) => JSX.Element;
33
- 'SmOrLarger': (props: GenericChildrenType) => JSX.Element;
34
- 'MdOrLarger': (props: GenericChildrenType) => JSX.Element;
35
- 'LgOrLarger': (props: GenericChildrenType) => JSX.Element;
36
- 'XlOrLarger': (props: GenericChildrenType) => JSX.Element;
37
- [key: string]: (props: GenericChildrenType) => JSX.Element;
38
- };
39
17
  /**
40
18
  * A React hook for responding to container size changes using Tailwind CSS container query breakpoints.
41
19
  *
@@ -47,21 +25,17 @@ type ContainerComponents = {
47
25
  *
48
26
  * @returns An object containing:
49
27
  * - containerRef: A ref to attach to your container element
50
- * - queries: Boolean flags for each breakpoint (isXs, isSm, isMd, etc.) and custom queries
51
- * - components: React components for conditional rendering (XsOnly, SmOrLarger, etc.)
28
+ * - queries: Boolean flags for each breakpoint (isXsOrLarger, isSmOrLarger, isMdOrLarger, etc.) and custom queries
52
29
  *
53
30
  * @example
54
31
  * ```tsx
55
32
  * const MyComponent = () => {
56
- * const { containerRef, queries, components } = useContainerQueries()
57
- * const { MdOrLarger } = components
33
+ * const { containerRef, queries } = useContainerQueries()
58
34
  *
59
35
  * return (
60
36
  * <div ref={containerRef}>
61
- * {queries.isSm && <p>Small container</p>}
62
- * <MdOrLarger>
63
- * <p>Medium or larger container</p>
64
- * </MdOrLarger>
37
+ * {queries.isSmOrLarger && <p>Small container</p>}
38
+ * {queries.isMdOrLarger && <p>Medium or larger container</p>}
65
39
  * </div>
66
40
  * )
67
41
  * }
@@ -69,16 +43,15 @@ type ContainerComponents = {
69
43
  *
70
44
  * @example With custom queries
71
45
  * ```tsx
72
- * const { containerRef, queries, components } = useContainerQueries({
46
+ * const { containerRef, queries } = useContainerQueries({
73
47
  * compact: '400px',
74
48
  * spacious: '800px',
75
49
  * })
76
- * const { Compact, Spacious } = components
77
50
  *
78
51
  * return (
79
52
  * <div ref={containerRef}>
80
- * <Compact><p>Compact view</p></Compact>
81
- * <Spacious><p>Spacious view</p></Spacious>
53
+ * {queries.compact && <p>Compact view</p>}
54
+ * {queries.spacious && <p>Spacious view</p>}
82
55
  * </div>
83
56
  * )
84
57
  * ```
@@ -86,6 +59,5 @@ type ContainerComponents = {
86
59
  export declare const useContainerQueries: (propQueries?: Props) => {
87
60
  containerRef: React.RefCallback<HTMLElement>;
88
61
  queries: ContainerQueries;
89
- components: ContainerComponents;
90
62
  };
91
63
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaizen/components",
3
- "version": "0.0.0-canary-useContainerQuery-20251123222018",
3
+ "version": "0.0.0-canary-useContainerQuery-20251125222037",
4
4
  "description": "Kaizen component library",
5
5
  "author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
6
6
  "homepage": "https://cultureamp.design",
@@ -4,22 +4,16 @@ import { vi } from 'vitest'
4
4
  import { useContainerQueries } from './useContainerQueries'
5
5
 
6
6
  const ExampleComponent = (): JSX.Element => {
7
- const { containerRef, queries, components } = useContainerQueries({
7
+ const { containerRef, queries } = useContainerQueries({
8
8
  compact: '400px',
9
9
  wide: '800px',
10
10
  })
11
- const { MdOrLarger, Compact } = components
12
11
 
13
12
  return (
14
13
  <div ref={containerRef} data-testid="container">
15
- {queries.isSm && <button type="button">Small query boolean</button>}
16
- <MdOrLarger>
17
- <button type="button">Medium or larger component</button>
18
- </MdOrLarger>
14
+ {queries.isSmOrLarger && <button type="button">Small query boolean</button>}
15
+ {queries.isMdOrLarger && <button type="button">Medium or larger query</button>}
19
16
  {queries.compact && <button type="button">Compact query boolean</button>}
20
- <Compact>
21
- <button type="button">Compact component</button>
22
- </Compact>
23
17
  </div>
24
18
  )
25
19
  }
@@ -129,7 +123,7 @@ describe('useContainerQueries()', () => {
129
123
  // Initially at 300px, should not show sm (384px) or md (448px) content
130
124
  expect(screen.queryByRole('button', { name: /Small query boolean/i })).not.toBeInTheDocument()
131
125
  expect(
132
- screen.queryByRole('button', { name: /Medium or larger component/i }),
126
+ screen.queryByRole('button', { name: /Medium or larger query/i }),
133
127
  ).not.toBeInTheDocument()
134
128
 
135
129
  // Trigger resize to 400px (sm breakpoint is 384px)
@@ -141,7 +135,7 @@ describe('useContainerQueries()', () => {
141
135
 
142
136
  expect(screen.queryByRole('button', { name: /Small query boolean/i })).toBeInTheDocument()
143
137
  expect(
144
- screen.queryByRole('button', { name: /Medium or larger component/i }),
138
+ screen.queryByRole('button', { name: /Medium or larger query/i }),
145
139
  ).not.toBeInTheDocument()
146
140
 
147
141
  // Trigger resize to 500px (md breakpoint is 448px)
@@ -152,9 +146,7 @@ describe('useContainerQueries()', () => {
152
146
  })
153
147
 
154
148
  expect(screen.queryByRole('button', { name: /Small query boolean/i })).toBeInTheDocument()
155
- expect(
156
- screen.queryByRole('button', { name: /Medium or larger component/i }),
157
- ).toBeInTheDocument()
149
+ expect(screen.queryByRole('button', { name: /Medium or larger query/i })).toBeInTheDocument()
158
150
  })
159
151
 
160
152
  it('shows and hides content based on custom queries', async () => {
@@ -178,7 +170,6 @@ describe('useContainerQueries()', () => {
178
170
 
179
171
  // Initially at 300px, custom 'compact' query (400px) should not match
180
172
  expect(screen.queryByRole('button', { name: /Compact query boolean/i })).not.toBeInTheDocument()
181
- expect(screen.queryByRole('button', { name: /Compact component/i })).not.toBeInTheDocument()
182
173
 
183
174
  // Trigger resize to 450px (compact is 400px)
184
175
  await act(async () => {
@@ -188,7 +179,6 @@ describe('useContainerQueries()', () => {
188
179
  })
189
180
 
190
181
  expect(screen.queryByRole('button', { name: /Compact query boolean/i })).toBeInTheDocument()
191
- expect(screen.queryByRole('button', { name: /Compact component/i })).toBeInTheDocument()
192
182
  })
193
183
 
194
184
  it('returns SSR-safe defaults when window is undefined', () => {
@@ -1,9 +1,8 @@
1
- /* eslint-disable react-hooks/rules-of-hooks */
2
- import React, { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
1
+ import type React from 'react'
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
3
3
  import { useDebouncedCallback } from 'use-debounce'
4
4
 
5
5
  type Props = Record<string, string>
6
- type GenericChildrenType = { children?: ReactNode }
7
6
 
8
7
  const DEFAULT_DEBOUNCE_MS = 500
9
8
 
@@ -38,45 +37,21 @@ const parseBreakpointValue = (value: string): number => {
38
37
  return parseFloat(value)
39
38
  }
40
39
 
41
- type HelperComponentProps = {
42
- children?: ReactNode
43
- }
44
-
45
40
  type ContainerQueries = {
46
- isXs: boolean
47
- isSm: boolean
48
- isMd: boolean
49
- isLg: boolean
50
- isXl: boolean
51
- is2xl: boolean
52
- is3xl: boolean
53
- is4xl: boolean
54
- is5xl: boolean
55
- is6xl: boolean
56
- is7xl: boolean
41
+ isXsOrLarger: boolean
42
+ isSmOrLarger: boolean
43
+ isMdOrLarger: boolean
44
+ isLgOrLarger: boolean
45
+ isXlOrLarger: boolean
46
+ is2xlOrLarger: boolean
47
+ is3xlOrLarger: boolean
48
+ is4xlOrLarger: boolean
49
+ is5xlOrLarger: boolean
50
+ is6xlOrLarger: boolean
51
+ is7xlOrLarger: boolean
57
52
  [key: string]: boolean
58
53
  }
59
54
 
60
- type ContainerComponents = {
61
- 'XsOnly': (props: GenericChildrenType) => JSX.Element
62
- 'SmOnly': (props: GenericChildrenType) => JSX.Element
63
- 'MdOnly': (props: GenericChildrenType) => JSX.Element
64
- 'LgOnly': (props: GenericChildrenType) => JSX.Element
65
- 'XlOnly': (props: GenericChildrenType) => JSX.Element
66
- '2xlOnly': (props: GenericChildrenType) => JSX.Element
67
- '3xlOnly': (props: GenericChildrenType) => JSX.Element
68
- '4xlOnly': (props: GenericChildrenType) => JSX.Element
69
- '5xlOnly': (props: GenericChildrenType) => JSX.Element
70
- '6xlOnly': (props: GenericChildrenType) => JSX.Element
71
- '7xlOnly': (props: GenericChildrenType) => JSX.Element
72
- 'XsOrLarger': (props: GenericChildrenType) => JSX.Element
73
- 'SmOrLarger': (props: GenericChildrenType) => JSX.Element
74
- 'MdOrLarger': (props: GenericChildrenType) => JSX.Element
75
- 'LgOrLarger': (props: GenericChildrenType) => JSX.Element
76
- 'XlOrLarger': (props: GenericChildrenType) => JSX.Element
77
- [key: string]: (props: GenericChildrenType) => JSX.Element
78
- }
79
-
80
55
  /**
81
56
  * A React hook for responding to container size changes using Tailwind CSS container query breakpoints.
82
57
  *
@@ -88,21 +63,17 @@ type ContainerComponents = {
88
63
  *
89
64
  * @returns An object containing:
90
65
  * - containerRef: A ref to attach to your container element
91
- * - queries: Boolean flags for each breakpoint (isXs, isSm, isMd, etc.) and custom queries
92
- * - components: React components for conditional rendering (XsOnly, SmOrLarger, etc.)
66
+ * - queries: Boolean flags for each breakpoint (isXsOrLarger, isSmOrLarger, isMdOrLarger, etc.) and custom queries
93
67
  *
94
68
  * @example
95
69
  * ```tsx
96
70
  * const MyComponent = () => {
97
- * const { containerRef, queries, components } = useContainerQueries()
98
- * const { MdOrLarger } = components
71
+ * const { containerRef, queries } = useContainerQueries()
99
72
  *
100
73
  * return (
101
74
  * <div ref={containerRef}>
102
- * {queries.isSm && <p>Small container</p>}
103
- * <MdOrLarger>
104
- * <p>Medium or larger container</p>
105
- * </MdOrLarger>
75
+ * {queries.isSmOrLarger && <p>Small container</p>}
76
+ * {queries.isMdOrLarger && <p>Medium or larger container</p>}
106
77
  * </div>
107
78
  * )
108
79
  * }
@@ -110,16 +81,15 @@ type ContainerComponents = {
110
81
  *
111
82
  * @example With custom queries
112
83
  * ```tsx
113
- * const { containerRef, queries, components } = useContainerQueries({
84
+ * const { containerRef, queries } = useContainerQueries({
114
85
  * compact: '400px',
115
86
  * spacious: '800px',
116
87
  * })
117
- * const { Compact, Spacious } = components
118
88
  *
119
89
  * return (
120
90
  * <div ref={containerRef}>
121
- * <Compact><p>Compact view</p></Compact>
122
- * <Spacious><p>Spacious view</p></Spacious>
91
+ * {queries.compact && <p>Compact view</p>}
92
+ * {queries.spacious && <p>Spacious view</p>}
123
93
  * </div>
124
94
  * )
125
95
  * ```
@@ -129,46 +99,8 @@ export const useContainerQueries = (
129
99
  ): {
130
100
  containerRef: React.RefCallback<HTMLElement>
131
101
  queries: ContainerQueries
132
- components: ContainerComponents
133
102
  } => {
134
- // SSR support - return safe defaults when window is undefined
135
- if (typeof window === 'undefined') {
136
- return {
137
- // eslint-disable-next-line @typescript-eslint/no-empty-function
138
- containerRef: () => {},
139
- queries: {
140
- isXs: false,
141
- isSm: false,
142
- isMd: false,
143
- isLg: false,
144
- isXl: false,
145
- is2xl: false,
146
- is3xl: false,
147
- is4xl: false,
148
- is5xl: false,
149
- is6xl: false,
150
- is7xl: true, // Default to largest for SSR
151
- },
152
- components: {
153
- 'XsOnly': () => <></>,
154
- 'SmOnly': () => <></>,
155
- 'MdOnly': () => <></>,
156
- 'LgOnly': () => <></>,
157
- 'XlOnly': () => <></>,
158
- '2xlOnly': () => <></>,
159
- '3xlOnly': () => <></>,
160
- '4xlOnly': () => <></>,
161
- '5xlOnly': () => <></>,
162
- '6xlOnly': () => <></>,
163
- '7xlOnly': (props: HelperComponentProps) => <>{props.children}</>,
164
- 'XsOrLarger': (props: HelperComponentProps) => <>{props.children}</>,
165
- 'SmOrLarger': (props: HelperComponentProps) => <>{props.children}</>,
166
- 'MdOrLarger': (props: HelperComponentProps) => <>{props.children}</>,
167
- 'LgOrLarger': (props: HelperComponentProps) => <>{props.children}</>,
168
- 'XlOrLarger': (props: HelperComponentProps) => <>{props.children}</>,
169
- },
170
- }
171
- }
103
+ const isClient = typeof window !== 'undefined'
172
104
 
173
105
  // Parse custom queries
174
106
  const customQueriesPx = useMemo(
@@ -197,6 +129,9 @@ export const useContainerQueries = (
197
129
  // Callback ref for the container element
198
130
  const containerRef = useCallback(
199
131
  (node: HTMLElement | null) => {
132
+ // Skip if SSR
133
+ if (!isClient) return
134
+
200
135
  // Cleanup previous observer
201
136
  if (resizeObserverRef.current) {
202
137
  resizeObserverRef.current.disconnect()
@@ -220,7 +155,7 @@ export const useContainerQueries = (
220
155
  setContainerWidth(width)
221
156
  }
222
157
  },
223
- [debouncedSetContainerWidth],
158
+ [debouncedSetContainerWidth, isClient],
224
159
  )
225
160
 
226
161
  // Cleanup on unmount
@@ -236,17 +171,17 @@ export const useContainerQueries = (
236
171
  // Calculate breakpoint matches based on container width
237
172
  const breakpointMatches = useMemo(
238
173
  () => ({
239
- isXs: containerWidth >= DEFAULT_BREAKPOINTS.xs,
240
- isSm: containerWidth >= DEFAULT_BREAKPOINTS.sm,
241
- isMd: containerWidth >= DEFAULT_BREAKPOINTS.md,
242
- isLg: containerWidth >= DEFAULT_BREAKPOINTS.lg,
243
- isXl: containerWidth >= DEFAULT_BREAKPOINTS.xl,
244
- is2xl: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
245
- is3xl: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
246
- is4xl: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
247
- is5xl: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
248
- is6xl: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
249
- is7xl: containerWidth >= DEFAULT_BREAKPOINTS['7xl'],
174
+ isXsOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xs,
175
+ isSmOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.sm,
176
+ isMdOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.md,
177
+ isLgOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.lg,
178
+ isXlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS.xl,
179
+ is2xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['2xl'],
180
+ is3xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['3xl'],
181
+ is4xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['4xl'],
182
+ is5xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['5xl'],
183
+ is6xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['6xl'],
184
+ is7xlOrLarger: containerWidth >= DEFAULT_BREAKPOINTS['7xl'],
250
185
  }),
251
186
  [containerWidth],
252
187
  )
@@ -264,68 +199,8 @@ export const useContainerQueries = (
264
199
  [containerWidth, customQueriesPx],
265
200
  )
266
201
 
267
- // Helper function to check if container is at exact breakpoint (not larger)
268
- const isExactBreakpoint = useCallback(
269
- (breakpoint: keyof typeof DEFAULT_BREAKPOINTS): boolean => {
270
- const sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(([, a], [, b]) => a - b)
271
- const currentIndex = sortedBreakpoints.findIndex(([key]) => key === breakpoint)
272
- const nextBreakpoint = sortedBreakpoints[currentIndex + 1]
273
-
274
- const minWidth = DEFAULT_BREAKPOINTS[breakpoint]
275
- const maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity
276
-
277
- return containerWidth >= minWidth && containerWidth < maxWidth
278
- },
279
- [containerWidth],
280
- )
281
-
282
- // Create helper components for Tailwind breakpoints
283
- const components = useMemo(
284
- () => ({
285
- 'XsOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('xs') && props.children}</>,
286
- 'SmOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('sm') && props.children}</>,
287
- 'MdOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('md') && props.children}</>,
288
- 'LgOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('lg') && props.children}</>,
289
- 'XlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('xl') && props.children}</>,
290
- '2xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('2xl') && props.children}</>,
291
- '3xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('3xl') && props.children}</>,
292
- '4xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('4xl') && props.children}</>,
293
- '5xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('5xl') && props.children}</>,
294
- '6xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('6xl') && props.children}</>,
295
- '7xlOnly': (props: HelperComponentProps) => <>{isExactBreakpoint('7xl') && props.children}</>,
296
- 'XsOrLarger': (props: HelperComponentProps) => (
297
- <>{breakpointMatches.isXs && props.children}</>
298
- ),
299
- 'SmOrLarger': (props: HelperComponentProps) => (
300
- <>{breakpointMatches.isSm && props.children}</>
301
- ),
302
- 'MdOrLarger': (props: HelperComponentProps) => (
303
- <>{breakpointMatches.isMd && props.children}</>
304
- ),
305
- 'LgOrLarger': (props: HelperComponentProps) => (
306
- <>{breakpointMatches.isLg && props.children}</>
307
- ),
308
- 'XlOrLarger': (props: HelperComponentProps) => (
309
- <>{breakpointMatches.isXl && props.children}</>
310
- ),
311
- // Custom query components
312
- ...Object.keys(customQueriesPx).reduce(
313
- (acc, key) => {
314
- const componentName = key.charAt(0).toUpperCase() + key.slice(1)
315
- acc[componentName] = (props: HelperComponentProps): JSX.Element => (
316
- <>{customMatches[key] && props.children}</>
317
- )
318
- return acc
319
- },
320
- {} as Record<string, (props: GenericChildrenType) => JSX.Element>,
321
- ),
322
- }),
323
- [breakpointMatches, customMatches, isExactBreakpoint, customQueriesPx],
324
- )
325
-
326
202
  return {
327
203
  containerRef,
328
204
  queries: { ...breakpointMatches, ...customMatches },
329
- components,
330
205
  }
331
206
  }