@kaizen/components 0.0.0-canary-container-query-titleblock-20251105031251 → 0.0.0-canary-useContainerQueries-20251121043854

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.
Files changed (64) hide show
  1. package/dist/cjs/index.cjs +2 -0
  2. package/dist/cjs/src/SingleSelect/SingleSelect.cjs +0 -2
  3. package/dist/cjs/src/utils/useContainerQueries.cjs +334 -0
  4. package/dist/esm/index.mjs +1 -0
  5. package/dist/esm/src/SingleSelect/SingleSelect.mjs +0 -2
  6. package/dist/esm/src/utils/useContainerQueries.mjs +326 -0
  7. package/dist/styles.css +1 -1
  8. package/dist/types/SingleSelect/SingleSelect.d.ts +0 -2
  9. package/dist/types/utils/index.d.ts +1 -0
  10. package/dist/types/utils/useContainerQueries.d.ts +91 -0
  11. package/locales/ar.json +3 -3
  12. package/locales/bg.json +3 -3
  13. package/locales/cs.json +3 -3
  14. package/locales/cy.json +3 -3
  15. package/locales/da.json +3 -3
  16. package/locales/de.json +3 -3
  17. package/locales/el.json +3 -3
  18. package/locales/en-GB.json +3 -3
  19. package/locales/es-419.json +3 -3
  20. package/locales/es.json +3 -3
  21. package/locales/et.json +3 -3
  22. package/locales/fi.json +3 -3
  23. package/locales/fr-CA.json +3 -3
  24. package/locales/fr.json +3 -3
  25. package/locales/he.json +3 -3
  26. package/locales/hi.json +3 -3
  27. package/locales/ht.json +3 -3
  28. package/locales/hu.json +3 -3
  29. package/locales/id.json +3 -3
  30. package/locales/it.json +3 -3
  31. package/locales/ja.json +3 -3
  32. package/locales/km-KH.json +3 -3
  33. package/locales/ko.json +3 -3
  34. package/locales/lt.json +3 -3
  35. package/locales/lv.json +3 -3
  36. package/locales/mi.json +3 -3
  37. package/locales/ms.json +3 -3
  38. package/locales/nb.json +3 -3
  39. package/locales/nl.json +3 -3
  40. package/locales/pl.json +3 -3
  41. package/locales/pt-BR.json +3 -3
  42. package/locales/pt.json +3 -3
  43. package/locales/ro.json +3 -3
  44. package/locales/ru.json +3 -3
  45. package/locales/si-LK.json +3 -3
  46. package/locales/sk.json +2 -2
  47. package/locales/sr.json +3 -3
  48. package/locales/sv.json +3 -3
  49. package/locales/th.json +3 -3
  50. package/locales/tl.json +3 -3
  51. package/locales/tr.json +3 -3
  52. package/locales/uk.json +3 -3
  53. package/locales/vi.json +3 -3
  54. package/locales/zh-TW.json +3 -3
  55. package/locales/zh.json +3 -3
  56. package/package.json +1 -1
  57. package/src/SingleSelect/SingleSelect.tsx +0 -2
  58. package/src/SingleSelect/_docs/SingleSelect--api-specification.mdx +1 -3
  59. package/src/SingleSelect/_docs/SingleSelect--usage-guidelines.mdx +1 -3
  60. package/src/SingleSelect/_docs/SingleSelect.stickersheet.stories.tsx +1 -1
  61. package/src/SingleSelect/_docs/SingleSelect.stories.tsx +1 -1
  62. package/src/utils/index.ts +1 -0
  63. package/src/utils/useContainerQueries.spec.tsx +242 -0
  64. package/src/utils/useContainerQueries.tsx +333 -0
@@ -172,6 +172,7 @@ var ToggleSwitchField = require('./src/ToggleSwitch/ToggleSwitchField/ToggleSwit
172
172
  var Tooltip = require('./src/Tooltip/Tooltip.cjs');
173
173
  var TooltipTrigger = require('./src/Tooltip/TooltipTrigger.cjs');
174
174
  var useMediaQueries = require('./src/utils/useMediaQueries.cjs');
175
+ var useContainerQueries = require('./src/utils/useContainerQueries.cjs');
175
176
  var hostedAssets = require('./src/utils/hostedAssets.cjs');
176
177
  var ReversedColors = require('./src/utils/ReversedColors/ReversedColors.cjs');
177
178
  var VisuallyHidden = require('./src/VisuallyHidden/VisuallyHidden.cjs');
@@ -573,6 +574,7 @@ exports.Tooltip = Tooltip.Tooltip;
573
574
  exports.TooltipTrigger = TooltipTrigger.TooltipTrigger;
574
575
  exports.subtractOnePixel = useMediaQueries.subtractOnePixel;
575
576
  exports.useMediaQueries = useMediaQueries.useMediaQueries;
577
+ exports.useContainerQueries = useContainerQueries.useContainerQueries;
576
578
  exports.assetUrl = hostedAssets.assetUrl;
577
579
  exports.ReversedColors = ReversedColors.ReversedColors;
578
580
  exports.useReversedColors = ReversedColors.useReversedColors;
@@ -31,8 +31,6 @@ var React__default = /*#__PURE__*/_interopDefault(React);
31
31
  var classnames__default = /*#__PURE__*/_interopDefault(classnames);
32
32
 
33
33
  /**
34
- * @deprecated SingleSelect is deprecated in v3 and will be replaced in v4.
35
- *
36
34
  * {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3081896474/Select Guidance} |
37
35
  * {@link https://cultureamp.design/?path=/docs/components-select--docs Storybook}
38
36
  */
@@ -0,0 +1,334 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var React = require('react');
5
+ function _interopDefault(e) {
6
+ return e && e.__esModule ? e : {
7
+ default: e
8
+ };
9
+ }
10
+ var React__default = /*#__PURE__*/_interopDefault(React);
11
+
12
+ /**
13
+ * Tailwind CSS default container query breakpoints
14
+ * These match the default values from @tailwindcss/container-queries plugin
15
+ */
16
+ var DEFAULT_BREAKPOINTS = {
17
+ 'xs': '20rem',
18
+ // 320px
19
+ 'sm': '24rem',
20
+ // 384px
21
+ 'md': '28rem',
22
+ // 448px
23
+ 'lg': '32rem',
24
+ // 512px
25
+ 'xl': '36rem',
26
+ // 576px
27
+ '2xl': '42rem',
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
38
+ };
39
+ /**
40
+ * Convert rem/px values to pixels for comparison
41
+ */
42
+ var parseBreakpointValue = function (value) {
43
+ if (value.endsWith('rem')) {
44
+ return parseFloat(value) * 16; // Assuming 1rem = 16px
45
+ }
46
+ if (value.endsWith('px')) {
47
+ return parseFloat(value);
48
+ }
49
+ return parseFloat(value);
50
+ };
51
+ /**
52
+ * A React hook for responding to container size changes using Tailwind CSS container query breakpoints.
53
+ *
54
+ * This hook uses ResizeObserver to detect when a container element crosses breakpoint thresholds,
55
+ * enabling component-level responsive behavior independent of viewport size.
56
+ *
57
+ * @param propQueries - Optional custom container size queries in the format { queryName: 'minWidth' }
58
+ * Example: { large: '600px', extraLarge: '48rem' }
59
+ *
60
+ * @returns An object containing:
61
+ * - containerRef: A ref to attach to your container element
62
+ * - queries: Boolean flags for each breakpoint (isXs, isSm, isMd, etc.) and custom queries
63
+ * - components: React components for conditional rendering (XsOnly, SmOrLarger, etc.)
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * const MyComponent = () => {
68
+ * const { containerRef, queries, components } = useContainerQueries()
69
+ * const { MdOrLarger } = components
70
+ *
71
+ * return (
72
+ * <div ref={containerRef}>
73
+ * {queries.isSm && <p>Small container</p>}
74
+ * <MdOrLarger>
75
+ * <p>Medium or larger container</p>
76
+ * </MdOrLarger>
77
+ * </div>
78
+ * )
79
+ * }
80
+ * ```
81
+ *
82
+ * @example With custom queries
83
+ * ```tsx
84
+ * const { containerRef, queries, components } = useContainerQueries({
85
+ * compact: '400px',
86
+ * spacious: '800px',
87
+ * })
88
+ * const { Compact, Spacious } = components
89
+ *
90
+ * return (
91
+ * <div ref={containerRef}>
92
+ * <Compact><p>Compact view</p></Compact>
93
+ * <Spacious><p>Spacious view</p></Spacious>
94
+ * </div>
95
+ * )
96
+ * ```
97
+ */
98
+ var useContainerQueries = function (propQueries) {
99
+ if (propQueries === void 0) {
100
+ propQueries = {};
101
+ }
102
+ // SSR support - return safe defaults when window is undefined
103
+ if (typeof window === 'undefined') {
104
+ return {
105
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
106
+ containerRef: function () {},
107
+ queries: {
108
+ isXs: false,
109
+ isSm: false,
110
+ isMd: false,
111
+ isLg: false,
112
+ isXl: false,
113
+ is2xl: false,
114
+ is3xl: false,
115
+ is4xl: false,
116
+ is5xl: false,
117
+ is6xl: false,
118
+ is7xl: true // Default to largest for SSR
119
+ },
120
+ components: {
121
+ 'XsOnly': function () {
122
+ return React__default.default.createElement(React__default.default.Fragment, null);
123
+ },
124
+ 'SmOnly': function () {
125
+ return React__default.default.createElement(React__default.default.Fragment, null);
126
+ },
127
+ 'MdOnly': function () {
128
+ return React__default.default.createElement(React__default.default.Fragment, null);
129
+ },
130
+ 'LgOnly': function () {
131
+ return React__default.default.createElement(React__default.default.Fragment, null);
132
+ },
133
+ 'XlOnly': function () {
134
+ return React__default.default.createElement(React__default.default.Fragment, null);
135
+ },
136
+ '2xlOnly': function () {
137
+ return React__default.default.createElement(React__default.default.Fragment, null);
138
+ },
139
+ '3xlOnly': function () {
140
+ return React__default.default.createElement(React__default.default.Fragment, null);
141
+ },
142
+ '4xlOnly': function () {
143
+ return React__default.default.createElement(React__default.default.Fragment, null);
144
+ },
145
+ '5xlOnly': function () {
146
+ return React__default.default.createElement(React__default.default.Fragment, null);
147
+ },
148
+ '6xlOnly': function () {
149
+ return React__default.default.createElement(React__default.default.Fragment, null);
150
+ },
151
+ '7xlOnly': function (props) {
152
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
153
+ },
154
+ 'XsOrLarger': function (props) {
155
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
156
+ },
157
+ 'SmOrLarger': function (props) {
158
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
159
+ },
160
+ 'MdOrLarger': function (props) {
161
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
162
+ },
163
+ 'LgOrLarger': function (props) {
164
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
165
+ },
166
+ 'XlOrLarger': function (props) {
167
+ return React__default.default.createElement(React__default.default.Fragment, null, props.children);
168
+ }
169
+ }
170
+ };
171
+ }
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
+ // Parse custom queries
182
+ var customQueriesPx = React.useMemo(function () {
183
+ return Object.entries(propQueries).reduce(function (acc, _a) {
184
+ var key = _a[0],
185
+ value = _a[1];
186
+ acc[key] = parseBreakpointValue(value);
187
+ return acc;
188
+ }, {});
189
+ }, [propQueries]);
190
+ // State to track container width
191
+ var _a = React.useState(0),
192
+ containerWidth = _a[0],
193
+ setContainerWidth = _a[1];
194
+ // ResizeObserver ref
195
+ var resizeObserverRef = React.useRef(null);
196
+ // Callback ref for the container element
197
+ var containerRef = React.useCallback(function (node) {
198
+ // Cleanup previous observer
199
+ if (resizeObserverRef.current) {
200
+ resizeObserverRef.current.disconnect();
201
+ resizeObserverRef.current = null;
202
+ }
203
+ if (node) {
204
+ // Create new ResizeObserver
205
+ resizeObserverRef.current = new ResizeObserver(function (entries) {
206
+ var _a, _b, _c;
207
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
208
+ var entry = entries_1[_i];
209
+ // Use borderBoxSize for more accurate measurements
210
+ 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
+ setContainerWidth(width_1);
212
+ }
213
+ });
214
+ resizeObserverRef.current.observe(node);
215
+ // Set initial width
216
+ var width = node.getBoundingClientRect().width;
217
+ setContainerWidth(width);
218
+ }
219
+ }, []);
220
+ // Cleanup on unmount
221
+ React.useEffect(function () {
222
+ return function () {
223
+ if (resizeObserverRef.current) {
224
+ resizeObserverRef.current.disconnect();
225
+ }
226
+ };
227
+ }, []);
228
+ // Calculate breakpoint matches based on container width
229
+ var breakpointMatches = React.useMemo(function () {
230
+ return {
231
+ isXs: containerWidth >= breakpointsPx.xs,
232
+ isSm: containerWidth >= breakpointsPx.sm,
233
+ isMd: containerWidth >= breakpointsPx.md,
234
+ isLg: containerWidth >= breakpointsPx.lg,
235
+ isXl: containerWidth >= breakpointsPx.xl,
236
+ is2xl: containerWidth >= breakpointsPx['2xl'],
237
+ is3xl: containerWidth >= breakpointsPx['3xl'],
238
+ is4xl: containerWidth >= breakpointsPx['4xl'],
239
+ is5xl: containerWidth >= breakpointsPx['5xl'],
240
+ is6xl: containerWidth >= breakpointsPx['6xl'],
241
+ is7xl: containerWidth >= breakpointsPx['7xl']
242
+ };
243
+ }, [containerWidth, breakpointsPx]);
244
+ // Calculate custom query matches
245
+ var customMatches = React.useMemo(function () {
246
+ return Object.entries(customQueriesPx).reduce(function (acc, _a) {
247
+ var key = _a[0],
248
+ value = _a[1];
249
+ acc[key] = containerWidth >= value;
250
+ return acc;
251
+ }, {});
252
+ }, [containerWidth, customQueriesPx]);
253
+ // Helper function to check if container is at exact breakpoint (not larger)
254
+ var isExactBreakpoint = React.useCallback(function (breakpoint) {
255
+ var sortedBreakpoints = Object.entries(breakpointsPx).sort(function (_a, _b) {
256
+ var a = _a[1];
257
+ var b = _b[1];
258
+ return a - b;
259
+ });
260
+ var currentIndex = sortedBreakpoints.findIndex(function (_a) {
261
+ var key = _a[0];
262
+ return key === breakpoint;
263
+ });
264
+ var nextBreakpoint = sortedBreakpoints[currentIndex + 1];
265
+ var minWidth = breakpointsPx[breakpoint];
266
+ var maxWidth = nextBreakpoint ? nextBreakpoint[1] : Infinity;
267
+ return containerWidth >= minWidth && containerWidth < maxWidth;
268
+ }, [containerWidth, breakpointsPx]);
269
+ // Create helper components for Tailwind breakpoints
270
+ var components = React.useMemo(function () {
271
+ return tslib.__assign({
272
+ 'XsOnly': function (props) {
273
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('xs') && props.children);
274
+ },
275
+ 'SmOnly': function (props) {
276
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('sm') && props.children);
277
+ },
278
+ 'MdOnly': function (props) {
279
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('md') && props.children);
280
+ },
281
+ 'LgOnly': function (props) {
282
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('lg') && props.children);
283
+ },
284
+ 'XlOnly': function (props) {
285
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('xl') && props.children);
286
+ },
287
+ '2xlOnly': function (props) {
288
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('2xl') && props.children);
289
+ },
290
+ '3xlOnly': function (props) {
291
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('3xl') && props.children);
292
+ },
293
+ '4xlOnly': function (props) {
294
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('4xl') && props.children);
295
+ },
296
+ '5xlOnly': function (props) {
297
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('5xl') && props.children);
298
+ },
299
+ '6xlOnly': function (props) {
300
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('6xl') && props.children);
301
+ },
302
+ '7xlOnly': function (props) {
303
+ return React__default.default.createElement(React__default.default.Fragment, null, isExactBreakpoint('7xl') && props.children);
304
+ },
305
+ 'XsOrLarger': function (props) {
306
+ return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isXs && props.children);
307
+ },
308
+ 'SmOrLarger': function (props) {
309
+ return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isSm && props.children);
310
+ },
311
+ 'MdOrLarger': function (props) {
312
+ return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isMd && props.children);
313
+ },
314
+ 'LgOrLarger': function (props) {
315
+ return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isLg && props.children);
316
+ },
317
+ 'XlOrLarger': function (props) {
318
+ return React__default.default.createElement(React__default.default.Fragment, null, breakpointMatches.isXl && props.children);
319
+ }
320
+ }, Object.keys(customQueriesPx).reduce(function (acc, key) {
321
+ var componentName = key.charAt(0).toUpperCase() + key.slice(1);
322
+ acc[componentName] = function (props) {
323
+ return React__default.default.createElement(React__default.default.Fragment, null, customMatches[key] && props.children);
324
+ };
325
+ return acc;
326
+ }, {}));
327
+ }, [breakpointMatches, customMatches, isExactBreakpoint, customQueriesPx]);
328
+ return {
329
+ containerRef: containerRef,
330
+ queries: tslib.__assign(tslib.__assign({}, breakpointMatches), customMatches),
331
+ components: components
332
+ };
333
+ };
334
+ exports.useContainerQueries = useContainerQueries;
@@ -177,6 +177,7 @@ export { ToggleSwitchField } from './src/ToggleSwitch/ToggleSwitchField/ToggleSw
177
177
  export { Tooltip } from './src/Tooltip/Tooltip.mjs';
178
178
  export { TooltipTrigger } from './src/Tooltip/TooltipTrigger.mjs';
179
179
  export { subtractOnePixel, useMediaQueries } from './src/utils/useMediaQueries.mjs';
180
+ export { useContainerQueries } from './src/utils/useContainerQueries.mjs';
180
181
  export { assetUrl } from './src/utils/hostedAssets.mjs';
181
182
  export { ReversedColors, useReversedColors } from './src/utils/ReversedColors/ReversedColors.mjs';
182
183
  export { VisuallyHidden } from './src/VisuallyHidden/VisuallyHidden.mjs';
@@ -22,8 +22,6 @@ import { transformSelectItemToCollectionElement } from './utils/transformSelectI
22
22
  import styles from './SingleSelect.module.scss.mjs';
23
23
 
24
24
  /**
25
- * @deprecated SingleSelect is deprecated in v3 and will be replaced in v4.
26
- *
27
25
  * {@link https://cultureamp.atlassian.net/wiki/spaces/DesignSystem/pages/3081896474/Select Guidance} |
28
26
  * {@link https://cultureamp.design/?path=/docs/components-select--docs Storybook}
29
27
  */