@designbasekorea/ui 0.2.37 → 0.2.39

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/index.js CHANGED
@@ -11124,6 +11124,8 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11124
11124
  const [activeTabId, setActiveTabId] = React.useState(selectedId ?? defaultSelectedId ?? items[0]?.id ?? '');
11125
11125
  const [focusedTabId, setFocusedTabId] = React.useState('');
11126
11126
  const [isDragging, setIsDragging] = React.useState(false);
11127
+ const [isMouseDown, setIsMouseDown] = React.useState(false);
11128
+ const [showRightGradient, setShowRightGradient] = React.useState(false);
11127
11129
  const tabListRef = React.useRef(null);
11128
11130
  const tabRefs = React.useRef(new Map());
11129
11131
  const dragStartRef = React.useRef(null);
@@ -11134,6 +11136,29 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11134
11136
  setActiveTabId(selectedId);
11135
11137
  }
11136
11138
  }, [selectedId]);
11139
+ // 스크롤 가능 여부 감지
11140
+ React.useEffect(() => {
11141
+ const checkScrollable = () => {
11142
+ if (tabListRef.current) {
11143
+ const isScrollable = tabListRef.current.scrollWidth > tabListRef.current.clientWidth;
11144
+ const isScrolledToEnd = tabListRef.current.scrollLeft + tabListRef.current.clientWidth >=
11145
+ tabListRef.current.scrollWidth - 5; // 5px 여유
11146
+ setShowRightGradient(isScrollable && !isScrolledToEnd);
11147
+ }
11148
+ };
11149
+ checkScrollable();
11150
+ window.addEventListener('resize', checkScrollable);
11151
+ const listElement = tabListRef.current;
11152
+ if (listElement) {
11153
+ listElement.addEventListener('scroll', checkScrollable);
11154
+ }
11155
+ return () => {
11156
+ window.removeEventListener('resize', checkScrollable);
11157
+ if (listElement) {
11158
+ listElement.removeEventListener('scroll', checkScrollable);
11159
+ }
11160
+ };
11161
+ }, [items]);
11137
11162
  // 키보드 네비게이션
11138
11163
  const handleKeyDown = React.useCallback((event, currentTabId) => {
11139
11164
  const currentIndex = items.findIndex(item => item.id === currentTabId);
@@ -11228,6 +11253,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11228
11253
  x: e.pageX - tabListRef.current.offsetLeft,
11229
11254
  scrollLeft: tabListRef.current.scrollLeft
11230
11255
  };
11256
+ setIsMouseDown(true);
11231
11257
  }, [orientation]);
11232
11258
  const handleMouseMove = React.useCallback((e) => {
11233
11259
  if (!dragStartRef.current || !tabListRef.current)
@@ -11251,11 +11277,13 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11251
11277
  }, [isDragging]);
11252
11278
  const handleMouseUp = React.useCallback(() => {
11253
11279
  setIsDragging(false);
11280
+ setIsMouseDown(false);
11254
11281
  dragStartRef.current = null;
11255
11282
  clickStartRef.current = null;
11256
11283
  }, []);
11257
11284
  const handleMouseLeave = React.useCallback(() => {
11258
11285
  setIsDragging(false);
11286
+ setIsMouseDown(false);
11259
11287
  dragStartRef.current = null;
11260
11288
  clickStartRef.current = null;
11261
11289
  }, []);
@@ -11274,6 +11302,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11274
11302
  x: touch.pageX - tabListRef.current.offsetLeft,
11275
11303
  scrollLeft: tabListRef.current.scrollLeft
11276
11304
  };
11305
+ setIsMouseDown(true);
11277
11306
  }, [orientation]);
11278
11307
  const handleTouchMove = React.useCallback((e) => {
11279
11308
  if (!dragStartRef.current || !tabListRef.current)
@@ -11299,12 +11328,13 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11299
11328
  }, [isDragging]);
11300
11329
  const handleTouchEnd = React.useCallback(() => {
11301
11330
  setIsDragging(false);
11331
+ setIsMouseDown(false);
11302
11332
  dragStartRef.current = null;
11303
11333
  clickStartRef.current = null;
11304
11334
  }, []);
11305
11335
  // 드래그 이벤트 리스너 등록/해제
11306
11336
  React.useEffect(() => {
11307
- if (isDragging) {
11337
+ if (isMouseDown) {
11308
11338
  document.addEventListener('mousemove', handleMouseMove);
11309
11339
  document.addEventListener('mouseup', handleMouseUp);
11310
11340
  document.addEventListener('mouseleave', handleMouseLeave);
@@ -11318,7 +11348,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11318
11348
  document.removeEventListener('touchmove', handleTouchMove);
11319
11349
  document.removeEventListener('touchend', handleTouchEnd);
11320
11350
  };
11321
- }, [isDragging, handleMouseMove, handleMouseUp, handleMouseLeave, handleTouchMove, handleTouchEnd]);
11351
+ }, [isMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, handleTouchMove, handleTouchEnd]);
11322
11352
  const activeTab = items.find(item => item.id === activeTabId);
11323
11353
  items.findIndex(item => item.id === activeTabId);
11324
11354
  const classes = clsx('designbase-tabs', `designbase-tabs--${orientation}`, `designbase-tabs--${size}`, `designbase-tabs--${variant}`, {
@@ -11327,6 +11357,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11327
11357
  const tabListClasses = clsx('designbase-tabs__list', `designbase-tabs__list--${orientation}`, {
11328
11358
  'designbase-tabs__list--full-width': fullWidth,
11329
11359
  'designbase-tabs__list--dragging': isDragging,
11360
+ 'designbase-tabs__list--show-gradient': showRightGradient,
11330
11361
  });
11331
11362
  return (jsxRuntime.jsxs("div", { className: classes, ...props, children: [jsxRuntime.jsx("div", { ref: tabListRef, className: tabListClasses, role: "tablist", "aria-orientation": orientation, "aria-label": "\uD0ED \uBAA9\uB85D", onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, children: items.map((item, index) => {
11332
11363
  const isSelected = item.id === activeTabId;
@@ -11336,6 +11367,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11336
11367
  'designbase-tabs__tab--selected': isSelected,
11337
11368
  'designbase-tabs__tab--focused': isFocused,
11338
11369
  'designbase-tabs__tab--disabled': isDisabled,
11370
+ 'designbase-tabs__tab--dragging': isDragging,
11339
11371
  });
11340
11372
  return (jsxRuntime.jsxs("button", { ref: (el) => {
11341
11373
  if (el) {
@@ -11344,7 +11376,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11344
11376
  else {
11345
11377
  tabRefs.current.delete(item.id);
11346
11378
  }
11347
- }, className: tabClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, "aria-controls": `panel-${item.id}`, id: `tab-${item.id}`, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onClick: () => handleTabSelect(item.id), onKeyDown: (e) => handleKeyDown(e, item.id), onFocus: () => handleTabFocus(item.id), onBlur: handleTabBlur, children: [item.icon && (jsxRuntime.jsx("span", { className: "designbase-tabs__tab-icon", children: jsxRuntime.jsx(item.icon, { size: size === 's' ? 16 : size === 'l' ? 20 : 18 }) })), jsxRuntime.jsx("span", { className: "designbase-tabs__tab-label", children: item.label })] }, item.id));
11379
+ }, className: tabClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, "aria-controls": `panel-${item.id}`, id: `tab-${item.id}`, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onClick: () => handleTabSelect(item.id), onKeyDown: (e) => handleKeyDown(e, item.id), onFocus: () => handleTabFocus(item.id), onBlur: handleTabBlur, children: [item.icon && (jsxRuntime.jsx("span", { className: "designbase-tabs__tab-icon", children: jsxRuntime.jsx(item.icon, { size: size === 's' ? 16 : size === 'l' ? 20 : 18 }) })), jsxRuntime.jsx("span", { className: "designbase-tabs__tab-label", children: item.label })] }, item.id));
11348
11380
  }) }), activeTab && (jsxRuntime.jsx("div", { className: "designbase-tabs__panel", role: "tabpanel", id: `panel-${activeTab.id}`, "aria-labelledby": `tab-${activeTab.id}`, tabIndex: 0, children: activeTab.content }))] }));
11349
11381
  };
11350
11382
  Tabs.displayName = 'Tabs';