@kaizen/components 0.0.0-canary-useContainerQueries-20251121043854 → 0.0.0-canary-useContainerQuery-20251123222018
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/dist/cjs/src/Button/Button.cjs +1 -0
- package/dist/cjs/src/LinkButton/LinkButton.cjs +1 -0
- package/dist/cjs/src/Pagination/Pagination.cjs +1 -0
- package/dist/cjs/src/Tooltip/OverlayArrow.cjs +1 -0
- package/dist/cjs/src/Tooltip/Tooltip.cjs +1 -0
- package/dist/cjs/src/utils/useContainerQueries.cjs +36 -50
- package/dist/esm/src/Button/Button.mjs +1 -0
- package/dist/esm/src/LinkButton/LinkButton.mjs +1 -0
- package/dist/esm/src/Pagination/Pagination.mjs +1 -0
- package/dist/esm/src/Tooltip/OverlayArrow.mjs +1 -0
- package/dist/esm/src/Tooltip/Tooltip.mjs +1 -0
- package/dist/esm/src/utils/useContainerQueries.mjs +36 -50
- package/package.json +1 -1
- package/src/utils/useContainerQueries.spec.tsx +6 -0
- package/src/utils/useContainerQueries.tsx +60 -62
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactAriaComponents = require('react-aria-components');
|
|
6
|
+
require('use-debounce');
|
|
6
7
|
var ReversedColors = require('../utils/ReversedColors/ReversedColors.cjs');
|
|
7
8
|
var mergeClassNames = require('../utils/mergeClassNames.cjs');
|
|
8
9
|
var PendingContent = require('./subcomponents/PendingContent/PendingContent.cjs');
|
|
@@ -11,6 +11,7 @@ require('../Loading/LoadingParagraph/LoadingParagraph.cjs');
|
|
|
11
11
|
require('../Loading/LoadingSpinner/LoadingSpinner.cjs');
|
|
12
12
|
require('../VisuallyHidden/VisuallyHidden.cjs');
|
|
13
13
|
var ButtonContent = require('../Button/subcomponents/ButtonContent/ButtonContent.cjs');
|
|
14
|
+
require('use-debounce');
|
|
14
15
|
var ReversedColors = require('../utils/ReversedColors/ReversedColors.cjs');
|
|
15
16
|
var mergeClassNames = require('../utils/mergeClassNames.cjs');
|
|
16
17
|
var Button_module = require('../Button/Button.module.css.cjs');
|
|
@@ -4,6 +4,7 @@ var tslib = require('tslib');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var classnames = require('classnames');
|
|
6
6
|
var useMediaQueries = require('../utils/useMediaQueries.cjs');
|
|
7
|
+
require('use-debounce');
|
|
7
8
|
require('../utils/ReversedColors/ReversedColors.cjs');
|
|
8
9
|
var DirectionalLink = require('./subcomponents/DirectionalLink/DirectionalLink.cjs');
|
|
9
10
|
var PaginationLink = require('./subcomponents/PaginationLink/PaginationLink.cjs');
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactAriaComponents = require('react-aria-components');
|
|
6
|
+
require('use-debounce');
|
|
6
7
|
var ReversedColors = require('../utils/ReversedColors/ReversedColors.cjs');
|
|
7
8
|
var mergeClassNames = require('../utils/mergeClassNames.cjs');
|
|
8
9
|
var OverlayArrow_module = require('./OverlayArrow.module.scss.cjs');
|
|
@@ -4,6 +4,7 @@ var tslib = require('tslib');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var reactAriaComponents = require('react-aria-components');
|
|
6
6
|
var VisuallyHidden = require('../VisuallyHidden/VisuallyHidden.cjs');
|
|
7
|
+
require('use-debounce');
|
|
7
8
|
var ReversedColors = require('../utils/ReversedColors/ReversedColors.cjs');
|
|
8
9
|
var mergeClassNames = require('../utils/mergeClassNames.cjs');
|
|
9
10
|
var OverlayArrow = require('./OverlayArrow.cjs');
|
|
@@ -2,39 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var React = require('react');
|
|
5
|
+
var useDebounce = require('use-debounce');
|
|
5
6
|
function _interopDefault(e) {
|
|
6
7
|
return e && e.__esModule ? e : {
|
|
7
8
|
default: e
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
11
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
11
|
-
|
|
12
|
+
var DEFAULT_DEBOUNCE_MS = 500;
|
|
12
13
|
/**
|
|
13
|
-
* Tailwind CSS default container query breakpoints
|
|
14
|
+
* Tailwind CSS default container query breakpoints in pixels
|
|
14
15
|
* These match the default values from @tailwindcss/container-queries plugin
|
|
15
16
|
*/
|
|
16
17
|
var DEFAULT_BREAKPOINTS = {
|
|
17
|
-
'xs':
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
'
|
|
22
|
-
|
|
23
|
-
'
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
|
|
27
|
-
'
|
|
28
|
-
// 672px
|
|
29
|
-
'3xl': '48rem',
|
|
30
|
-
// 768px
|
|
31
|
-
'4xl': '56rem',
|
|
32
|
-
// 896px
|
|
33
|
-
'5xl': '64rem',
|
|
34
|
-
// 1024px
|
|
35
|
-
'6xl': '72rem',
|
|
36
|
-
// 1152px
|
|
37
|
-
'7xl': '80rem' // 1280px
|
|
18
|
+
'xs': 320,
|
|
19
|
+
'sm': 384,
|
|
20
|
+
'md': 448,
|
|
21
|
+
'lg': 512,
|
|
22
|
+
'xl': 576,
|
|
23
|
+
'2xl': 672,
|
|
24
|
+
'3xl': 768,
|
|
25
|
+
'4xl': 896,
|
|
26
|
+
'5xl': 1024,
|
|
27
|
+
'6xl': 1152,
|
|
28
|
+
'7xl': 1280
|
|
38
29
|
};
|
|
39
30
|
/**
|
|
40
31
|
* Convert rem/px values to pixels for comparison
|
|
@@ -169,15 +160,6 @@ var useContainerQueries = function (propQueries) {
|
|
|
169
160
|
}
|
|
170
161
|
};
|
|
171
162
|
}
|
|
172
|
-
// Parse all breakpoints to pixel values for comparison
|
|
173
|
-
var breakpointsPx = React.useMemo(function () {
|
|
174
|
-
return Object.entries(DEFAULT_BREAKPOINTS).reduce(function (acc, _a) {
|
|
175
|
-
var key = _a[0],
|
|
176
|
-
value = _a[1];
|
|
177
|
-
acc[key] = parseBreakpointValue(value);
|
|
178
|
-
return acc;
|
|
179
|
-
}, {});
|
|
180
|
-
}, []);
|
|
181
163
|
// Parse custom queries
|
|
182
164
|
var customQueriesPx = React.useMemo(function () {
|
|
183
165
|
return Object.entries(propQueries).reduce(function (acc, _a) {
|
|
@@ -193,6 +175,10 @@ var useContainerQueries = function (propQueries) {
|
|
|
193
175
|
setContainerWidth = _a[1];
|
|
194
176
|
// ResizeObserver ref
|
|
195
177
|
var resizeObserverRef = React.useRef(null);
|
|
178
|
+
// Debounced width update
|
|
179
|
+
var debouncedSetContainerWidth = useDebounce.useDebouncedCallback(function (width) {
|
|
180
|
+
setContainerWidth(width);
|
|
181
|
+
}, DEFAULT_DEBOUNCE_MS);
|
|
196
182
|
// Callback ref for the container element
|
|
197
183
|
var containerRef = React.useCallback(function (node) {
|
|
198
184
|
// Cleanup previous observer
|
|
@@ -208,15 +194,15 @@ var useContainerQueries = function (propQueries) {
|
|
|
208
194
|
var entry = entries_1[_i];
|
|
209
195
|
// Use borderBoxSize for more accurate measurements
|
|
210
196
|
var width_1 = (_c = (_b = (_a = entry.borderBoxSize) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.inlineSize) !== null && _c !== void 0 ? _c : entry.contentRect.width;
|
|
211
|
-
|
|
197
|
+
debouncedSetContainerWidth(width_1);
|
|
212
198
|
}
|
|
213
199
|
});
|
|
214
200
|
resizeObserverRef.current.observe(node);
|
|
215
|
-
// Set initial width
|
|
201
|
+
// Set initial width immediately (no debounce for initial render)
|
|
216
202
|
var width = node.getBoundingClientRect().width;
|
|
217
203
|
setContainerWidth(width);
|
|
218
204
|
}
|
|
219
|
-
}, []);
|
|
205
|
+
}, [debouncedSetContainerWidth]);
|
|
220
206
|
// Cleanup on unmount
|
|
221
207
|
React.useEffect(function () {
|
|
222
208
|
return function () {
|
|
@@ -228,19 +214,19 @@ var useContainerQueries = function (propQueries) {
|
|
|
228
214
|
// Calculate breakpoint matches based on container width
|
|
229
215
|
var breakpointMatches = React.useMemo(function () {
|
|
230
216
|
return {
|
|
231
|
-
isXs: containerWidth >=
|
|
232
|
-
isSm: containerWidth >=
|
|
233
|
-
isMd: containerWidth >=
|
|
234
|
-
isLg: containerWidth >=
|
|
235
|
-
isXl: containerWidth >=
|
|
236
|
-
is2xl: containerWidth >=
|
|
237
|
-
is3xl: containerWidth >=
|
|
238
|
-
is4xl: containerWidth >=
|
|
239
|
-
is5xl: containerWidth >=
|
|
240
|
-
is6xl: containerWidth >=
|
|
241
|
-
is7xl: containerWidth >=
|
|
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']
|
|
242
228
|
};
|
|
243
|
-
}, [containerWidth
|
|
229
|
+
}, [containerWidth]);
|
|
244
230
|
// Calculate custom query matches
|
|
245
231
|
var customMatches = React.useMemo(function () {
|
|
246
232
|
return Object.entries(customQueriesPx).reduce(function (acc, _a) {
|
|
@@ -252,7 +238,7 @@ var useContainerQueries = function (propQueries) {
|
|
|
252
238
|
}, [containerWidth, customQueriesPx]);
|
|
253
239
|
// Helper function to check if container is at exact breakpoint (not larger)
|
|
254
240
|
var isExactBreakpoint = React.useCallback(function (breakpoint) {
|
|
255
|
-
var sortedBreakpoints = Object.entries(
|
|
241
|
+
var sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(function (_a, _b) {
|
|
256
242
|
var a = _a[1];
|
|
257
243
|
var b = _b[1];
|
|
258
244
|
return a - b;
|
|
@@ -262,10 +248,10 @@ var useContainerQueries = function (propQueries) {
|
|
|
262
248
|
return key === breakpoint;
|
|
263
249
|
});
|
|
264
250
|
var nextBreakpoint = sortedBreakpoints[currentIndex + 1];
|
|
265
|
-
var minWidth =
|
|
251
|
+
var minWidth = DEFAULT_BREAKPOINTS[breakpoint];
|
|
266
252
|
var maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity;
|
|
267
253
|
return containerWidth >= minWidth && containerWidth < maxWidth;
|
|
268
|
-
}, [containerWidth
|
|
254
|
+
}, [containerWidth]);
|
|
269
255
|
// Create helper components for Tailwind breakpoints
|
|
270
256
|
var components = React.useMemo(function () {
|
|
271
257
|
return tslib.__assign({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __rest, __assign } from 'tslib';
|
|
2
2
|
import React, { forwardRef } from 'react';
|
|
3
3
|
import { Button as Button$1 } from 'react-aria-components';
|
|
4
|
+
import 'use-debounce';
|
|
4
5
|
import { useReversedColors } from '../utils/ReversedColors/ReversedColors.mjs';
|
|
5
6
|
import { mergeClassNames } from '../utils/mergeClassNames.mjs';
|
|
6
7
|
import { PendingContent } from './subcomponents/PendingContent/PendingContent.mjs';
|
|
@@ -9,6 +9,7 @@ import '../Loading/LoadingParagraph/LoadingParagraph.mjs';
|
|
|
9
9
|
import '../Loading/LoadingSpinner/LoadingSpinner.mjs';
|
|
10
10
|
import '../VisuallyHidden/VisuallyHidden.mjs';
|
|
11
11
|
import { ButtonContent } from '../Button/subcomponents/ButtonContent/ButtonContent.mjs';
|
|
12
|
+
import 'use-debounce';
|
|
12
13
|
import { useReversedColors } from '../utils/ReversedColors/ReversedColors.mjs';
|
|
13
14
|
import { mergeClassNames } from '../utils/mergeClassNames.mjs';
|
|
14
15
|
import buttonStyles from '../Button/Button.module.css.mjs';
|
|
@@ -2,6 +2,7 @@ import { __rest, __assign } from 'tslib';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
4
|
import { useMediaQueries } from '../utils/useMediaQueries.mjs';
|
|
5
|
+
import 'use-debounce';
|
|
5
6
|
import '../utils/ReversedColors/ReversedColors.mjs';
|
|
6
7
|
import { DirectionalLink } from './subcomponents/DirectionalLink/DirectionalLink.mjs';
|
|
7
8
|
import { PaginationLink } from './subcomponents/PaginationLink/PaginationLink.mjs';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __assign } from 'tslib';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { OverlayArrow as OverlayArrow$1 } from 'react-aria-components';
|
|
4
|
+
import 'use-debounce';
|
|
4
5
|
import { useReversedColors } from '../utils/ReversedColors/ReversedColors.mjs';
|
|
5
6
|
import { mergeClassNames } from '../utils/mergeClassNames.mjs';
|
|
6
7
|
import styles from './OverlayArrow.module.scss.mjs';
|
|
@@ -3,6 +3,7 @@ import React, { forwardRef, useContext, useState, useLayoutEffect } from 'react'
|
|
|
3
3
|
import { useContextProps, TooltipContext, TooltipTriggerStateContext, Tooltip as Tooltip$1 } from 'react-aria-components';
|
|
4
4
|
export { TooltipContext } from 'react-aria-components';
|
|
5
5
|
import { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden.mjs';
|
|
6
|
+
import 'use-debounce';
|
|
6
7
|
import { useReversedColors } from '../utils/ReversedColors/ReversedColors.mjs';
|
|
7
8
|
import { mergeClassNames } from '../utils/mergeClassNames.mjs';
|
|
8
9
|
import { OverlayArrow } from './OverlayArrow.mjs';
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import { __assign } from 'tslib';
|
|
2
2
|
import React, { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
|
-
|
|
3
|
+
import { useDebouncedCallback } from 'use-debounce';
|
|
4
|
+
var DEFAULT_DEBOUNCE_MS = 500;
|
|
4
5
|
/**
|
|
5
|
-
* Tailwind CSS default container query breakpoints
|
|
6
|
+
* Tailwind CSS default container query breakpoints in pixels
|
|
6
7
|
* These match the default values from @tailwindcss/container-queries plugin
|
|
7
8
|
*/
|
|
8
9
|
var DEFAULT_BREAKPOINTS = {
|
|
9
|
-
'xs':
|
|
10
|
-
|
|
11
|
-
'
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
'
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
// 672px
|
|
21
|
-
'3xl': '48rem',
|
|
22
|
-
// 768px
|
|
23
|
-
'4xl': '56rem',
|
|
24
|
-
// 896px
|
|
25
|
-
'5xl': '64rem',
|
|
26
|
-
// 1024px
|
|
27
|
-
'6xl': '72rem',
|
|
28
|
-
// 1152px
|
|
29
|
-
'7xl': '80rem' // 1280px
|
|
10
|
+
'xs': 320,
|
|
11
|
+
'sm': 384,
|
|
12
|
+
'md': 448,
|
|
13
|
+
'lg': 512,
|
|
14
|
+
'xl': 576,
|
|
15
|
+
'2xl': 672,
|
|
16
|
+
'3xl': 768,
|
|
17
|
+
'4xl': 896,
|
|
18
|
+
'5xl': 1024,
|
|
19
|
+
'6xl': 1152,
|
|
20
|
+
'7xl': 1280
|
|
30
21
|
};
|
|
31
22
|
/**
|
|
32
23
|
* Convert rem/px values to pixels for comparison
|
|
@@ -161,15 +152,6 @@ var useContainerQueries = function (propQueries) {
|
|
|
161
152
|
}
|
|
162
153
|
};
|
|
163
154
|
}
|
|
164
|
-
// Parse all breakpoints to pixel values for comparison
|
|
165
|
-
var breakpointsPx = useMemo(function () {
|
|
166
|
-
return Object.entries(DEFAULT_BREAKPOINTS).reduce(function (acc, _a) {
|
|
167
|
-
var key = _a[0],
|
|
168
|
-
value = _a[1];
|
|
169
|
-
acc[key] = parseBreakpointValue(value);
|
|
170
|
-
return acc;
|
|
171
|
-
}, {});
|
|
172
|
-
}, []);
|
|
173
155
|
// Parse custom queries
|
|
174
156
|
var customQueriesPx = useMemo(function () {
|
|
175
157
|
return Object.entries(propQueries).reduce(function (acc, _a) {
|
|
@@ -185,6 +167,10 @@ var useContainerQueries = function (propQueries) {
|
|
|
185
167
|
setContainerWidth = _a[1];
|
|
186
168
|
// ResizeObserver ref
|
|
187
169
|
var resizeObserverRef = useRef(null);
|
|
170
|
+
// Debounced width update
|
|
171
|
+
var debouncedSetContainerWidth = useDebouncedCallback(function (width) {
|
|
172
|
+
setContainerWidth(width);
|
|
173
|
+
}, DEFAULT_DEBOUNCE_MS);
|
|
188
174
|
// Callback ref for the container element
|
|
189
175
|
var containerRef = useCallback(function (node) {
|
|
190
176
|
// Cleanup previous observer
|
|
@@ -200,15 +186,15 @@ var useContainerQueries = function (propQueries) {
|
|
|
200
186
|
var entry = entries_1[_i];
|
|
201
187
|
// Use borderBoxSize for more accurate measurements
|
|
202
188
|
var width_1 = (_c = (_b = (_a = entry.borderBoxSize) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.inlineSize) !== null && _c !== void 0 ? _c : entry.contentRect.width;
|
|
203
|
-
|
|
189
|
+
debouncedSetContainerWidth(width_1);
|
|
204
190
|
}
|
|
205
191
|
});
|
|
206
192
|
resizeObserverRef.current.observe(node);
|
|
207
|
-
// Set initial width
|
|
193
|
+
// Set initial width immediately (no debounce for initial render)
|
|
208
194
|
var width = node.getBoundingClientRect().width;
|
|
209
195
|
setContainerWidth(width);
|
|
210
196
|
}
|
|
211
|
-
}, []);
|
|
197
|
+
}, [debouncedSetContainerWidth]);
|
|
212
198
|
// Cleanup on unmount
|
|
213
199
|
useEffect(function () {
|
|
214
200
|
return function () {
|
|
@@ -220,19 +206,19 @@ var useContainerQueries = function (propQueries) {
|
|
|
220
206
|
// Calculate breakpoint matches based on container width
|
|
221
207
|
var breakpointMatches = useMemo(function () {
|
|
222
208
|
return {
|
|
223
|
-
isXs: containerWidth >=
|
|
224
|
-
isSm: containerWidth >=
|
|
225
|
-
isMd: containerWidth >=
|
|
226
|
-
isLg: containerWidth >=
|
|
227
|
-
isXl: containerWidth >=
|
|
228
|
-
is2xl: containerWidth >=
|
|
229
|
-
is3xl: containerWidth >=
|
|
230
|
-
is4xl: containerWidth >=
|
|
231
|
-
is5xl: containerWidth >=
|
|
232
|
-
is6xl: containerWidth >=
|
|
233
|
-
is7xl: containerWidth >=
|
|
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']
|
|
234
220
|
};
|
|
235
|
-
}, [containerWidth
|
|
221
|
+
}, [containerWidth]);
|
|
236
222
|
// Calculate custom query matches
|
|
237
223
|
var customMatches = useMemo(function () {
|
|
238
224
|
return Object.entries(customQueriesPx).reduce(function (acc, _a) {
|
|
@@ -244,7 +230,7 @@ var useContainerQueries = function (propQueries) {
|
|
|
244
230
|
}, [containerWidth, customQueriesPx]);
|
|
245
231
|
// Helper function to check if container is at exact breakpoint (not larger)
|
|
246
232
|
var isExactBreakpoint = useCallback(function (breakpoint) {
|
|
247
|
-
var sortedBreakpoints = Object.entries(
|
|
233
|
+
var sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(function (_a, _b) {
|
|
248
234
|
var a = _a[1];
|
|
249
235
|
var b = _b[1];
|
|
250
236
|
return a - b;
|
|
@@ -254,10 +240,10 @@ var useContainerQueries = function (propQueries) {
|
|
|
254
240
|
return key === breakpoint;
|
|
255
241
|
});
|
|
256
242
|
var nextBreakpoint = sortedBreakpoints[currentIndex + 1];
|
|
257
|
-
var minWidth =
|
|
243
|
+
var minWidth = DEFAULT_BREAKPOINTS[breakpoint];
|
|
258
244
|
var maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity;
|
|
259
245
|
return containerWidth >= minWidth && containerWidth < maxWidth;
|
|
260
|
-
}, [containerWidth
|
|
246
|
+
}, [containerWidth]);
|
|
261
247
|
// Create helper components for Tailwind breakpoints
|
|
262
248
|
var components = useMemo(function () {
|
|
263
249
|
return __assign({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaizen/components",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-useContainerQuery-20251123222018",
|
|
4
4
|
"description": "Kaizen component library",
|
|
5
5
|
"author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
|
|
6
6
|
"homepage": "https://cultureamp.design",
|
|
@@ -135,6 +135,8 @@ describe('useContainerQueries()', () => {
|
|
|
135
135
|
// Trigger resize to 400px (sm breakpoint is 384px)
|
|
136
136
|
await act(async () => {
|
|
137
137
|
resizeObserverInstance?.trigger(400)
|
|
138
|
+
// Wait for debounce (500ms + buffer)
|
|
139
|
+
await new Promise((resolve) => setTimeout(resolve, 550))
|
|
138
140
|
})
|
|
139
141
|
|
|
140
142
|
expect(screen.queryByRole('button', { name: /Small query boolean/i })).toBeInTheDocument()
|
|
@@ -145,6 +147,8 @@ describe('useContainerQueries()', () => {
|
|
|
145
147
|
// Trigger resize to 500px (md breakpoint is 448px)
|
|
146
148
|
await act(async () => {
|
|
147
149
|
resizeObserverInstance?.trigger(500)
|
|
150
|
+
// Wait for debounce (500ms + buffer)
|
|
151
|
+
await new Promise((resolve) => setTimeout(resolve, 550))
|
|
148
152
|
})
|
|
149
153
|
|
|
150
154
|
expect(screen.queryByRole('button', { name: /Small query boolean/i })).toBeInTheDocument()
|
|
@@ -179,6 +183,8 @@ describe('useContainerQueries()', () => {
|
|
|
179
183
|
// Trigger resize to 450px (compact is 400px)
|
|
180
184
|
await act(async () => {
|
|
181
185
|
resizeObserverInstance?.trigger(450)
|
|
186
|
+
// Wait for debounce (500ms + buffer)
|
|
187
|
+
await new Promise((resolve) => setTimeout(resolve, 550))
|
|
182
188
|
})
|
|
183
189
|
|
|
184
190
|
expect(screen.queryByRole('button', { name: /Compact query boolean/i })).toBeInTheDocument()
|
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
2
|
import React, { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
|
|
3
|
+
import { useDebouncedCallback } from 'use-debounce'
|
|
3
4
|
|
|
4
5
|
type Props = Record<string, string>
|
|
5
6
|
type GenericChildrenType = { children?: ReactNode }
|
|
6
7
|
|
|
8
|
+
const DEFAULT_DEBOUNCE_MS = 500
|
|
9
|
+
|
|
7
10
|
/**
|
|
8
|
-
* Tailwind CSS default container query breakpoints
|
|
11
|
+
* Tailwind CSS default container query breakpoints in pixels
|
|
9
12
|
* These match the default values from @tailwindcss/container-queries plugin
|
|
10
13
|
*/
|
|
11
14
|
const DEFAULT_BREAKPOINTS = {
|
|
12
|
-
'xs':
|
|
13
|
-
'sm':
|
|
14
|
-
'md':
|
|
15
|
-
'lg':
|
|
16
|
-
'xl':
|
|
17
|
-
'2xl':
|
|
18
|
-
'3xl':
|
|
19
|
-
'4xl':
|
|
20
|
-
'5xl':
|
|
21
|
-
'6xl':
|
|
22
|
-
'7xl':
|
|
15
|
+
'xs': 320,
|
|
16
|
+
'sm': 384,
|
|
17
|
+
'md': 448,
|
|
18
|
+
'lg': 512,
|
|
19
|
+
'xl': 576,
|
|
20
|
+
'2xl': 672,
|
|
21
|
+
'3xl': 768,
|
|
22
|
+
'4xl': 896,
|
|
23
|
+
'5xl': 1024,
|
|
24
|
+
'6xl': 1152,
|
|
25
|
+
'7xl': 1280,
|
|
23
26
|
} as const
|
|
24
27
|
|
|
25
28
|
/**
|
|
@@ -167,19 +170,6 @@ export const useContainerQueries = (
|
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
|
|
170
|
-
// Parse all breakpoints to pixel values for comparison
|
|
171
|
-
const breakpointsPx = useMemo(
|
|
172
|
-
() =>
|
|
173
|
-
Object.entries(DEFAULT_BREAKPOINTS).reduce(
|
|
174
|
-
(acc, [key, value]) => {
|
|
175
|
-
acc[key] = parseBreakpointValue(value)
|
|
176
|
-
return acc
|
|
177
|
-
},
|
|
178
|
-
{} as Record<string, number>,
|
|
179
|
-
),
|
|
180
|
-
[],
|
|
181
|
-
)
|
|
182
|
-
|
|
183
173
|
// Parse custom queries
|
|
184
174
|
const customQueriesPx = useMemo(
|
|
185
175
|
() =>
|
|
@@ -199,31 +189,39 @@ export const useContainerQueries = (
|
|
|
199
189
|
// ResizeObserver ref
|
|
200
190
|
const resizeObserverRef = useRef<ResizeObserver | null>(null)
|
|
201
191
|
|
|
192
|
+
// Debounced width update
|
|
193
|
+
const debouncedSetContainerWidth = useDebouncedCallback((width: number) => {
|
|
194
|
+
setContainerWidth(width)
|
|
195
|
+
}, DEFAULT_DEBOUNCE_MS)
|
|
196
|
+
|
|
202
197
|
// Callback ref for the container element
|
|
203
|
-
const containerRef = useCallback(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
resizeObserverRef.current
|
|
207
|
-
|
|
208
|
-
|
|
198
|
+
const containerRef = useCallback(
|
|
199
|
+
(node: HTMLElement | null) => {
|
|
200
|
+
// Cleanup previous observer
|
|
201
|
+
if (resizeObserverRef.current) {
|
|
202
|
+
resizeObserverRef.current.disconnect()
|
|
203
|
+
resizeObserverRef.current = null
|
|
204
|
+
}
|
|
209
205
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
206
|
+
if (node) {
|
|
207
|
+
// Create new ResizeObserver
|
|
208
|
+
resizeObserverRef.current = new ResizeObserver((entries) => {
|
|
209
|
+
for (const entry of entries) {
|
|
210
|
+
// Use borderBoxSize for more accurate measurements
|
|
211
|
+
const width = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width
|
|
212
|
+
debouncedSetContainerWidth(width)
|
|
213
|
+
}
|
|
214
|
+
})
|
|
219
215
|
|
|
220
|
-
|
|
216
|
+
resizeObserverRef.current.observe(node)
|
|
221
217
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
218
|
+
// Set initial width immediately (no debounce for initial render)
|
|
219
|
+
const width = node.getBoundingClientRect().width
|
|
220
|
+
setContainerWidth(width)
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
[debouncedSetContainerWidth],
|
|
224
|
+
)
|
|
227
225
|
|
|
228
226
|
// Cleanup on unmount
|
|
229
227
|
useEffect(
|
|
@@ -238,19 +236,19 @@ export const useContainerQueries = (
|
|
|
238
236
|
// Calculate breakpoint matches based on container width
|
|
239
237
|
const breakpointMatches = useMemo(
|
|
240
238
|
() => ({
|
|
241
|
-
isXs: containerWidth >=
|
|
242
|
-
isSm: containerWidth >=
|
|
243
|
-
isMd: containerWidth >=
|
|
244
|
-
isLg: containerWidth >=
|
|
245
|
-
isXl: containerWidth >=
|
|
246
|
-
is2xl: containerWidth >=
|
|
247
|
-
is3xl: containerWidth >=
|
|
248
|
-
is4xl: containerWidth >=
|
|
249
|
-
is5xl: containerWidth >=
|
|
250
|
-
is6xl: containerWidth >=
|
|
251
|
-
is7xl: containerWidth >=
|
|
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'],
|
|
252
250
|
}),
|
|
253
|
-
[containerWidth
|
|
251
|
+
[containerWidth],
|
|
254
252
|
)
|
|
255
253
|
|
|
256
254
|
// Calculate custom query matches
|
|
@@ -268,17 +266,17 @@ export const useContainerQueries = (
|
|
|
268
266
|
|
|
269
267
|
// Helper function to check if container is at exact breakpoint (not larger)
|
|
270
268
|
const isExactBreakpoint = useCallback(
|
|
271
|
-
(breakpoint: keyof typeof
|
|
272
|
-
const sortedBreakpoints = Object.entries(
|
|
269
|
+
(breakpoint: keyof typeof DEFAULT_BREAKPOINTS): boolean => {
|
|
270
|
+
const sortedBreakpoints = Object.entries(DEFAULT_BREAKPOINTS).sort(([, a], [, b]) => a - b)
|
|
273
271
|
const currentIndex = sortedBreakpoints.findIndex(([key]) => key === breakpoint)
|
|
274
272
|
const nextBreakpoint = sortedBreakpoints[currentIndex + 1]
|
|
275
273
|
|
|
276
|
-
const minWidth =
|
|
274
|
+
const minWidth = DEFAULT_BREAKPOINTS[breakpoint]
|
|
277
275
|
const maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity
|
|
278
276
|
|
|
279
277
|
return containerWidth >= minWidth && containerWidth < maxWidth
|
|
280
278
|
},
|
|
281
|
-
[containerWidth
|
|
279
|
+
[containerWidth],
|
|
282
280
|
)
|
|
283
281
|
|
|
284
282
|
// Create helper components for Tailwind breakpoints
|