@bento-core/tab 1.0.0-c3dc.2 → 1.0.0-c3dc.4

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 (3) hide show
  1. package/dist/Tabs.js +46 -22
  2. package/package.json +1 -1
  3. package/src/Tabs.js +66 -33
package/dist/Tabs.js CHANGED
@@ -44,16 +44,25 @@ const TabItems = _ref => {
44
44
  const [currentGroup, setCurrentGroup] = (0, _react.useState)(0);
45
45
  const [showMorePopup, setShowMorePopup] = (0, _react.useState)(false);
46
46
  const [moreButtonAnchor, setMoreButtonAnchor] = (0, _react.useState)(null);
47
- const [windowWidth, setWindowWidth] = (0, _react.useState)(typeof window !== 'undefined' ? window.innerWidth : getDefaultWindowWidth(responsiveBreakpoints));
47
+ const [containerWidth, setContainerWidth] = (0, _react.useState)(getDefaultWindowWidth(responsiveBreakpoints));
48
+ const containerRef = (0, _react.useRef)(null);
48
49
 
49
50
  // Calculate tab limit based on screen width breakpoints
51
+ // We are now using the div container width instead of window width
52
+ // This is to support the facet kickout feature so that the tabs respond
53
+ // to the available space in the container div
54
+ // These breakpoints are calculated by multiplying the width of each tab
55
+ // including the padding/margin (203px)
56
+ // and counting the more button as a tab (203px)
57
+ // We will have enough space for tabs + more button + empty tab space
58
+ // e.g. 2 tabs: (203 * 2) + 203 + 203 = 812px
50
59
  const getTabLimitByWidth = width => {
51
60
  if (!responsiveBreakpoints) {
52
61
  // Fallback to original hardcoded values if no config provided
53
- if (width < 1250) return 2;
54
- if (width < 1400) return 3;
55
- if (width < 1550) return 4;
56
- if (width < 1700) return 5;
62
+ if (width < 812) return 2;
63
+ if (width < 1015) return 3;
64
+ if (width < 1281) return 4;
65
+ if (width < 1421) return 5;
57
66
  return 6; // >= 1700px
58
67
  }
59
68
 
@@ -71,21 +80,26 @@ const TabItems = _ref => {
71
80
  };
72
81
 
73
82
  // Grouping logic with responsive breakpoints
74
- const tabLimit = enableGrouping ? getTabLimitByWidth(windowWidth) : maxVisibleTabs;
83
+ const tabLimit = enableGrouping ? getTabLimitByWidth(containerWidth) : maxVisibleTabs;
75
84
  const shouldShowMoreButton = enableGrouping && tabItems.length > tabLimit;
76
85
 
77
- // Window resize listener for responsive breakpoints
86
+ // ResizeObserver to monitor container div width for responsive breakpoints
78
87
  (0, _react.useEffect)(() => {
79
- if (!enableGrouping || typeof window === 'undefined') {
88
+ if (!enableGrouping || !containerRef.current) {
80
89
  return undefined;
81
90
  }
82
- const handleResize = () => {
83
- const newWidth = window.innerWidth;
84
- setWindowWidth(newWidth);
85
- };
86
- window.addEventListener('resize', handleResize);
91
+ const resizeObserver = new ResizeObserver(entries => {
92
+ if (entries.length > 0) {
93
+ const newWidth = entries[0].contentRect.width;
94
+ setContainerWidth(newWidth);
95
+ }
96
+ });
97
+ resizeObserver.observe(containerRef.current);
98
+
99
+ // Set initial width
100
+ setContainerWidth(containerRef.current.offsetWidth);
87
101
  return () => {
88
- window.removeEventListener('resize', handleResize);
102
+ resizeObserver.disconnect();
89
103
  };
90
104
  }, [enableGrouping]);
91
105
 
@@ -123,18 +137,24 @@ const TabItems = _ref => {
123
137
 
124
138
  // Add tabs after visible range
125
139
  for (let i = visibleEnd; i < tabItems.length; i += 1) {
126
- hiddenTabsWithIndex.push({
127
- tab: tabItems[i],
128
- originalIndex: i
129
- });
140
+ const tab = tabItems[i];
141
+ if (tab) {
142
+ hiddenTabsWithIndex.push({
143
+ tab,
144
+ originalIndex: i
145
+ });
146
+ }
130
147
  }
131
148
 
132
149
  // Add tabs before visible range (wrap-around)
133
150
  for (let i = 0; i < visibleStart; i += 1) {
134
- hiddenTabsWithIndex.push({
135
- tab: tabItems[i],
136
- originalIndex: i
137
- });
151
+ const tab = tabItems[i];
152
+ if (tab) {
153
+ hiddenTabsWithIndex.push({
154
+ tab,
155
+ originalIndex: i
156
+ });
157
+ }
138
158
  }
139
159
  return hiddenTabsWithIndex;
140
160
  }, [enableGrouping, shouldShowMoreButton, currentGroup, tabLimit, tabItems]);
@@ -227,6 +247,7 @@ const TabItems = _ref => {
227
247
  return /*#__PURE__*/_react.default.createElement(_core.ThemeProvider, {
228
248
  theme: themeConfig
229
249
  }, /*#__PURE__*/_react.default.createElement("div", {
250
+ ref: containerRef,
230
251
  style: {
231
252
  position: 'relative'
232
253
  }
@@ -265,6 +286,9 @@ const TabItems = _ref => {
265
286
  tab,
266
287
  originalIndex
267
288
  } = _ref3;
289
+ if (!tab || !tab.name) {
290
+ return null;
291
+ }
268
292
  return /*#__PURE__*/_react.default.createElement(_core.ListItem, {
269
293
  key: originalIndex,
270
294
  button: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bento-core/tab",
3
- "version": "1.0.0-c3dc.2",
3
+ "version": "1.0.0-c3dc.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/Tabs.js CHANGED
@@ -1,4 +1,9 @@
1
- import React, { useState, useEffect, useMemo } from 'react';
1
+ import React, {
2
+ useState,
3
+ useEffect,
4
+ useMemo,
5
+ useRef,
6
+ } from 'react';
2
7
  import {
3
8
  Tab,
4
9
  Tabs,
@@ -41,16 +46,27 @@ const TabItems = ({
41
46
  const [currentGroup, setCurrentGroup] = useState(0);
42
47
  const [showMorePopup, setShowMorePopup] = useState(false);
43
48
  const [moreButtonAnchor, setMoreButtonAnchor] = useState(null);
44
- const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : getDefaultWindowWidth(responsiveBreakpoints));
49
+ const [containerWidth, setContainerWidth] = useState(
50
+ getDefaultWindowWidth(responsiveBreakpoints),
51
+ );
52
+ const containerRef = useRef(null);
45
53
 
46
54
  // Calculate tab limit based on screen width breakpoints
55
+ // We are now using the div container width instead of window width
56
+ // This is to support the facet kickout feature so that the tabs respond
57
+ // to the available space in the container div
58
+ // These breakpoints are calculated by multiplying the width of each tab
59
+ // including the padding/margin (203px)
60
+ // and counting the more button as a tab (203px)
61
+ // We will have enough space for tabs + more button + empty tab space
62
+ // e.g. 2 tabs: (203 * 2) + 203 + 203 = 812px
47
63
  const getTabLimitByWidth = (width) => {
48
64
  if (!responsiveBreakpoints) {
49
65
  // Fallback to original hardcoded values if no config provided
50
- if (width < 1250) return 2;
51
- if (width < 1400) return 3;
52
- if (width < 1550) return 4;
53
- if (width < 1700) return 5;
66
+ if (width < 812) return 2;
67
+ if (width < 1015) return 3;
68
+ if (width < 1281) return 4;
69
+ if (width < 1421) return 5;
54
70
  return 6; // >= 1700px
55
71
  }
56
72
 
@@ -65,23 +81,29 @@ const TabItems = ({
65
81
  };
66
82
 
67
83
  // Grouping logic with responsive breakpoints
68
- const tabLimit = enableGrouping ? getTabLimitByWidth(windowWidth) : maxVisibleTabs;
84
+ const tabLimit = enableGrouping ? getTabLimitByWidth(containerWidth) : maxVisibleTabs;
69
85
  const shouldShowMoreButton = enableGrouping && tabItems.length > tabLimit;
70
86
 
71
- // Window resize listener for responsive breakpoints
87
+ // ResizeObserver to monitor container div width for responsive breakpoints
72
88
  useEffect(() => {
73
- if (!enableGrouping || typeof window === 'undefined') {
89
+ if (!enableGrouping || !containerRef.current) {
74
90
  return undefined;
75
91
  }
76
92
 
77
- const handleResize = () => {
78
- const newWidth = window.innerWidth;
79
- setWindowWidth(newWidth);
80
- };
93
+ const resizeObserver = new ResizeObserver((entries) => {
94
+ if (entries.length > 0) {
95
+ const newWidth = entries[0].contentRect.width;
96
+ setContainerWidth(newWidth);
97
+ }
98
+ });
99
+
100
+ resizeObserver.observe(containerRef.current);
101
+
102
+ // Set initial width
103
+ setContainerWidth(containerRef.current.offsetWidth);
81
104
 
82
- window.addEventListener('resize', handleResize);
83
105
  return () => {
84
- window.removeEventListener('resize', handleResize);
106
+ resizeObserver.disconnect();
85
107
  };
86
108
  }, [enableGrouping]);
87
109
 
@@ -121,12 +143,18 @@ const TabItems = ({
121
143
 
122
144
  // Add tabs after visible range
123
145
  for (let i = visibleEnd; i < tabItems.length; i += 1) {
124
- hiddenTabsWithIndex.push({ tab: tabItems[i], originalIndex: i });
146
+ const tab = tabItems[i];
147
+ if (tab) {
148
+ hiddenTabsWithIndex.push({ tab, originalIndex: i });
149
+ }
125
150
  }
126
151
 
127
152
  // Add tabs before visible range (wrap-around)
128
153
  for (let i = 0; i < visibleStart; i += 1) {
129
- hiddenTabsWithIndex.push({ tab: tabItems[i], originalIndex: i });
154
+ const tab = tabItems[i];
155
+ if (tab) {
156
+ hiddenTabsWithIndex.push({ tab, originalIndex: i });
157
+ }
130
158
  }
131
159
 
132
160
  return hiddenTabsWithIndex;
@@ -224,7 +252,7 @@ const TabItems = ({
224
252
  const themeConfig = createTheme({ overrides: { ...defaultTheme(), ...customTheme } });
225
253
  return (
226
254
  <ThemeProvider theme={themeConfig}>
227
- <div style={{ position: 'relative' }}>
255
+ <div ref={containerRef} style={{ position: 'relative' }}>
228
256
  <Tabs
229
257
  onChange={(event, value) => {
230
258
  // Convert relative position to actual tab index when grouping is enabled
@@ -257,21 +285,26 @@ const TabItems = ({
257
285
  style={{ marginTop: '10px' }}
258
286
  >
259
287
  <List className="popover-list">
260
- {popupTabs.map(({ tab, originalIndex }) => (
261
- <ListItem
262
- key={originalIndex}
263
- button
264
- onClick={() => handlePopupTabClick(originalIndex)}
265
- className="popover-list-item"
266
- >
267
- <span className="popover-tab-name">
268
- {tab.name}
269
- </span>
270
- <span className="popover-tab-count">
271
- {tab.count || ''}
272
- </span>
273
- </ListItem>
274
- ))}
288
+ {popupTabs.map(({ tab, originalIndex }) => {
289
+ if (!tab || !tab.name) {
290
+ return null;
291
+ }
292
+ return (
293
+ <ListItem
294
+ key={originalIndex}
295
+ button
296
+ onClick={() => handlePopupTabClick(originalIndex)}
297
+ className="popover-list-item"
298
+ >
299
+ <span className="popover-tab-name">
300
+ {tab.name}
301
+ </span>
302
+ <span className="popover-tab-count">
303
+ {tab.count || ''}
304
+ </span>
305
+ </ListItem>
306
+ );
307
+ })}
275
308
  </List>
276
309
  </Popover>
277
310
  )}