@designbasekorea/ui 0.2.38 → 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.esm.js CHANGED
@@ -11122,6 +11122,8 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11122
11122
  const [activeTabId, setActiveTabId] = useState(selectedId ?? defaultSelectedId ?? items[0]?.id ?? '');
11123
11123
  const [focusedTabId, setFocusedTabId] = useState('');
11124
11124
  const [isDragging, setIsDragging] = useState(false);
11125
+ const [isMouseDown, setIsMouseDown] = useState(false);
11126
+ const [showRightGradient, setShowRightGradient] = useState(false);
11125
11127
  const tabListRef = useRef(null);
11126
11128
  const tabRefs = useRef(new Map());
11127
11129
  const dragStartRef = useRef(null);
@@ -11132,6 +11134,29 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11132
11134
  setActiveTabId(selectedId);
11133
11135
  }
11134
11136
  }, [selectedId]);
11137
+ // 스크롤 가능 여부 감지
11138
+ useEffect(() => {
11139
+ const checkScrollable = () => {
11140
+ if (tabListRef.current) {
11141
+ const isScrollable = tabListRef.current.scrollWidth > tabListRef.current.clientWidth;
11142
+ const isScrolledToEnd = tabListRef.current.scrollLeft + tabListRef.current.clientWidth >=
11143
+ tabListRef.current.scrollWidth - 5; // 5px 여유
11144
+ setShowRightGradient(isScrollable && !isScrolledToEnd);
11145
+ }
11146
+ };
11147
+ checkScrollable();
11148
+ window.addEventListener('resize', checkScrollable);
11149
+ const listElement = tabListRef.current;
11150
+ if (listElement) {
11151
+ listElement.addEventListener('scroll', checkScrollable);
11152
+ }
11153
+ return () => {
11154
+ window.removeEventListener('resize', checkScrollable);
11155
+ if (listElement) {
11156
+ listElement.removeEventListener('scroll', checkScrollable);
11157
+ }
11158
+ };
11159
+ }, [items]);
11135
11160
  // 키보드 네비게이션
11136
11161
  const handleKeyDown = useCallback((event, currentTabId) => {
11137
11162
  const currentIndex = items.findIndex(item => item.id === currentTabId);
@@ -11226,6 +11251,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11226
11251
  x: e.pageX - tabListRef.current.offsetLeft,
11227
11252
  scrollLeft: tabListRef.current.scrollLeft
11228
11253
  };
11254
+ setIsMouseDown(true);
11229
11255
  }, [orientation]);
11230
11256
  const handleMouseMove = useCallback((e) => {
11231
11257
  if (!dragStartRef.current || !tabListRef.current)
@@ -11249,11 +11275,13 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11249
11275
  }, [isDragging]);
11250
11276
  const handleMouseUp = useCallback(() => {
11251
11277
  setIsDragging(false);
11278
+ setIsMouseDown(false);
11252
11279
  dragStartRef.current = null;
11253
11280
  clickStartRef.current = null;
11254
11281
  }, []);
11255
11282
  const handleMouseLeave = useCallback(() => {
11256
11283
  setIsDragging(false);
11284
+ setIsMouseDown(false);
11257
11285
  dragStartRef.current = null;
11258
11286
  clickStartRef.current = null;
11259
11287
  }, []);
@@ -11272,6 +11300,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11272
11300
  x: touch.pageX - tabListRef.current.offsetLeft,
11273
11301
  scrollLeft: tabListRef.current.scrollLeft
11274
11302
  };
11303
+ setIsMouseDown(true);
11275
11304
  }, [orientation]);
11276
11305
  const handleTouchMove = useCallback((e) => {
11277
11306
  if (!dragStartRef.current || !tabListRef.current)
@@ -11297,12 +11326,13 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11297
11326
  }, [isDragging]);
11298
11327
  const handleTouchEnd = useCallback(() => {
11299
11328
  setIsDragging(false);
11329
+ setIsMouseDown(false);
11300
11330
  dragStartRef.current = null;
11301
11331
  clickStartRef.current = null;
11302
11332
  }, []);
11303
11333
  // 드래그 이벤트 리스너 등록/해제
11304
11334
  useEffect(() => {
11305
- if (isDragging) {
11335
+ if (isMouseDown) {
11306
11336
  document.addEventListener('mousemove', handleMouseMove);
11307
11337
  document.addEventListener('mouseup', handleMouseUp);
11308
11338
  document.addEventListener('mouseleave', handleMouseLeave);
@@ -11316,7 +11346,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11316
11346
  document.removeEventListener('touchmove', handleTouchMove);
11317
11347
  document.removeEventListener('touchend', handleTouchEnd);
11318
11348
  };
11319
- }, [isDragging, handleMouseMove, handleMouseUp, handleMouseLeave, handleTouchMove, handleTouchEnd]);
11349
+ }, [isMouseDown, handleMouseMove, handleMouseUp, handleMouseLeave, handleTouchMove, handleTouchEnd]);
11320
11350
  const activeTab = items.find(item => item.id === activeTabId);
11321
11351
  items.findIndex(item => item.id === activeTabId);
11322
11352
  const classes = clsx('designbase-tabs', `designbase-tabs--${orientation}`, `designbase-tabs--${size}`, `designbase-tabs--${variant}`, {
@@ -11325,6 +11355,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11325
11355
  const tabListClasses = clsx('designbase-tabs__list', `designbase-tabs__list--${orientation}`, {
11326
11356
  'designbase-tabs__list--full-width': fullWidth,
11327
11357
  'designbase-tabs__list--dragging': isDragging,
11358
+ 'designbase-tabs__list--show-gradient': showRightGradient,
11328
11359
  });
11329
11360
  return (jsxs("div", { className: classes, ...props, children: [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) => {
11330
11361
  const isSelected = item.id === activeTabId;
@@ -11334,6 +11365,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11334
11365
  'designbase-tabs__tab--selected': isSelected,
11335
11366
  'designbase-tabs__tab--focused': isFocused,
11336
11367
  'designbase-tabs__tab--disabled': isDisabled,
11368
+ 'designbase-tabs__tab--dragging': isDragging,
11337
11369
  });
11338
11370
  return (jsxs("button", { ref: (el) => {
11339
11371
  if (el) {
@@ -11342,7 +11374,7 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
11342
11374
  else {
11343
11375
  tabRefs.current.delete(item.id);
11344
11376
  }
11345
- }, 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 && (jsx("span", { className: "designbase-tabs__tab-icon", children: jsx(item.icon, { size: size === 's' ? 16 : size === 'l' ? 20 : 18 }) })), jsx("span", { className: "designbase-tabs__tab-label", children: item.label })] }, item.id));
11377
+ }, 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 && (jsx("span", { className: "designbase-tabs__tab-icon", children: jsx(item.icon, { size: size === 's' ? 16 : size === 'l' ? 20 : 18 }) })), jsx("span", { className: "designbase-tabs__tab-label", children: item.label })] }, item.id));
11346
11378
  }) }), activeTab && (jsx("div", { className: "designbase-tabs__panel", role: "tabpanel", id: `panel-${activeTab.id}`, "aria-labelledby": `tab-${activeTab.id}`, tabIndex: 0, children: activeTab.content }))] }));
11347
11379
  };
11348
11380
  Tabs.displayName = 'Tabs';