@designbasekorea/ui 0.5.5 → 0.5.6

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.umd.js CHANGED
@@ -4451,7 +4451,7 @@
4451
4451
  });
4452
4452
  Checkbox.displayName = 'Checkbox';
4453
4453
 
4454
- const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = icons.SearchIcon, clearIcon: ClearIconComponent = icons.CloseIcon, enableRecentSearches = false, recentSearchesKey = 'searchbar-recent-searches', suggestedSearches = [], suggestionRollingInterval = 5000, onChange, onSearch, onFocus, onBlur, onKeyDown, className, ...rest }) => {
4454
+ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = icons.SearchIcon, clearIcon: ClearIconComponent = icons.CloseIcon, enableRecentSearches = false, recentSearchesKey = 'searchbar-recent-searches', suggestedSearches = [], suggestionRollingInterval = 5000, onChange, onSearch, onFocus, onBlur, onKeyDown, showShortcut = false, shortcutLabel = '⌘K', className, ...rest }) => {
4455
4455
  const [internalValue, setInternalValue] = React.useState(defaultValue);
4456
4456
  const [recentSearches, setRecentSearches] = React.useState([]);
4457
4457
  const [showRecentSearches, setShowRecentSearches] = React.useState(false);
@@ -4596,7 +4596,8 @@
4596
4596
  const currentPlaceholder = suggestedSearches.length > 0 && !currentValue && currentValue === ''
4597
4597
  ? suggestedSearches[currentSuggestion]
4598
4598
  : placeholder;
4599
- return (jsxRuntime.jsxs("div", { className: classes, role: "search", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__container", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__search-icon", children: jsxRuntime.jsx(SearchIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }), jsxRuntime.jsx("input", { ref: inputRef, type: "text", className: inputClasses, value: currentValue, placeholder: currentPlaceholder, disabled: disabled, readOnly: readOnly, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, "aria-label": "\uAC80\uC0C9\uC5B4 \uC785\uB825", ...rest }), currentValue && currentValue.length > 0 && !disabled && !readOnly && (jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-button", onClick: handleClear, "aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30", children: jsxRuntime.jsx(ClearIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }))] }), showRecentSearches && recentSearches.length > 0 && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-searches", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-header", children: [jsxRuntime.jsx("span", { className: "designbase-search-bar__recent-title", children: "\uCD5C\uADFC \uAC80\uC0C9\uC5B4" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-all-button", onClick: handleClearAllRecentSearches, "aria-label": "\uBAA8\uB4E0 \uCD5C\uADFC \uAC80\uC0C9\uC5B4 \uC0AD\uC81C", children: "\uC804\uCCB4 \uC0AD\uC81C" })] }), jsxRuntime.jsx("div", { className: "designbase-search-bar__recent-list", children: recentSearches.map((searchTerm, index) => (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-item", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-search-button", onClick: () => handleRecentSearchClick(searchTerm), children: searchTerm }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-remove-button", onClick: () => handleRemoveRecentSearch(searchTerm), "aria-label": `${searchTerm} 삭제`, children: jsxRuntime.jsx(icons.CloseIcon, { size: 16 }) })] }, index))) })] })), suggestedSearches.length > 0 && isFocused && !currentValue && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__suggestions", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-header", children: jsxRuntime.jsx("span", { className: "designbase-search-bar__suggestions-title", children: "\uCD94\uCC9C \uAC80\uC0C9\uC5B4" }) }), jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-list", children: suggestedSearches.map((suggestion, index) => (jsxRuntime.jsx("button", { type: "button", className: clsx('designbase-search-bar__suggestion-item', {
4599
+ const shortcutBadgeSize = size === 'l' ? 'm' : 's';
4600
+ return (jsxRuntime.jsxs("div", { className: classes, role: "search", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__container", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__search-icon", children: jsxRuntime.jsx(SearchIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }), jsxRuntime.jsx("input", { ref: inputRef, type: "text", className: inputClasses, value: currentValue, placeholder: currentPlaceholder, disabled: disabled, readOnly: readOnly, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, "aria-label": "\uAC80\uC0C9\uC5B4 \uC785\uB825", ...rest }), showShortcut && !currentValue && !disabled && !readOnly && (jsxRuntime.jsx(Badge, { className: "designbase-search-bar__shortcut-badge", size: shortcutBadgeSize, variant: "secondary", style: "text", "aria-hidden": "true", children: shortcutLabel })), currentValue && currentValue.length > 0 && !disabled && !readOnly && (jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-button", onClick: handleClear, "aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30", children: jsxRuntime.jsx(ClearIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }))] }), showRecentSearches && recentSearches.length > 0 && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-searches", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-header", children: [jsxRuntime.jsx("span", { className: "designbase-search-bar__recent-title", children: "\uCD5C\uADFC \uAC80\uC0C9\uC5B4" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-all-button", onClick: handleClearAllRecentSearches, "aria-label": "\uBAA8\uB4E0 \uCD5C\uADFC \uAC80\uC0C9\uC5B4 \uC0AD\uC81C", children: "\uC804\uCCB4 \uC0AD\uC81C" })] }), jsxRuntime.jsx("div", { className: "designbase-search-bar__recent-list", children: recentSearches.map((searchTerm, index) => (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-item", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-search-button", onClick: () => handleRecentSearchClick(searchTerm), children: searchTerm }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-remove-button", onClick: () => handleRemoveRecentSearch(searchTerm), "aria-label": `${searchTerm} 삭제`, children: jsxRuntime.jsx(icons.CloseIcon, { size: 16 }) })] }, index))) })] })), suggestedSearches.length > 0 && isFocused && !currentValue && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__suggestions", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-header", children: jsxRuntime.jsx("span", { className: "designbase-search-bar__suggestions-title", children: "\uCD94\uCC9C \uAC80\uC0C9\uC5B4" }) }), jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-list", children: suggestedSearches.map((suggestion, index) => (jsxRuntime.jsx("button", { type: "button", className: clsx('designbase-search-bar__suggestion-item', {
4600
4601
  'designbase-search-bar__suggestion-item--active': index === currentSuggestion
4601
4602
  }), onClick: () => handleSuggestionClick(suggestion), children: suggestion }, index))) })] }))] }));
4602
4603
  };
@@ -8596,12 +8597,11 @@
8596
8597
  })), currentIndex: selectedImageIndex, isOpen: true, onOpenChange: handleLightboxClose, onImageChange: handleLightboxNavigate }))] }));
8597
8598
  };
8598
8599
 
8599
- const List = ({ items, size = 'm', variant = 'default', itemType = 'default', layout = 'vertical', selectable = false, multiple = false, selectedItems = [], draggable = false, spacing = 'm', alignment = 'start', onItemClick, onItemSelect, onItemDrag, emptyState, loading = false, loadingCount = 3, className, }) => {
8600
+ const List = ({ items, size = 'm', variant = 'navigation', itemType = 'default', layout = 'vertical', selectable = false, multiple = false, selectedItems = [], draggable = false, spacing = 's', alignment = 'start', showLeadingIcon = true, showDescription = false, showMeta = false, showBadge = true, showArrow = true, clickableArea = 'item', onItemClick, onItemSelect, onItemDrag, emptyState, loading = false, loadingCount = 3, className, }) => {
8600
8601
  const [internalSelectedItems, setInternalSelectedItems] = React.useState(selectedItems);
8601
8602
  const [draggedItem, setDraggedItem] = React.useState(null);
8602
- // 아이콘 크기 계산 (m이 기본값)
8603
8603
  const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
8604
- // 외부에서 선택된 아이템이 변경되면 내부 상태 업데이트
8604
+ const shouldShowArrow = showArrow;
8605
8605
  React.useEffect(() => {
8606
8606
  setInternalSelectedItems(selectedItems);
8607
8607
  }, [selectedItems]);
@@ -8612,7 +8612,7 @@
8612
8612
  let newSelectedItems;
8613
8613
  if (multiple) {
8614
8614
  if (internalSelectedItems.includes(item.id)) {
8615
- newSelectedItems = internalSelectedItems.filter(id => id !== item.id);
8615
+ newSelectedItems = internalSelectedItems.filter((id) => id !== item.id);
8616
8616
  }
8617
8617
  else {
8618
8618
  newSelectedItems = [...internalSelectedItems, item.id];
@@ -8626,6 +8626,12 @@
8626
8626
  }
8627
8627
  onItemClick?.(item, index);
8628
8628
  };
8629
+ const handleItemKeyDown = (e, item, index) => {
8630
+ if (e.key === 'Enter' || e.key === ' ') {
8631
+ e.preventDefault();
8632
+ handleItemClick(item, index);
8633
+ }
8634
+ };
8629
8635
  const handleItemDragStart = (e, itemId) => {
8630
8636
  if (!draggable)
8631
8637
  return;
@@ -8648,9 +8654,7 @@
8648
8654
  const handleItemDragEnd = () => {
8649
8655
  setDraggedItem(null);
8650
8656
  };
8651
- const isItemSelected = (itemId) => {
8652
- return internalSelectedItems.includes(itemId);
8653
- };
8657
+ const isItemSelected = (itemId) => internalSelectedItems.includes(itemId);
8654
8658
  const renderBadge = (badge) => {
8655
8659
  if (!badge)
8656
8660
  return null;
@@ -8669,17 +8673,38 @@
8669
8673
  const renderItem = (item, index) => {
8670
8674
  const isSelected = isItemSelected(item.id);
8671
8675
  const isDragging = draggedItem === item.id;
8676
+ const isClickable = Boolean(onItemClick || selectable);
8677
+ const hasDescription = showDescription && Boolean(item.description);
8678
+ const hasMeta = showMeta && Boolean(item.meta?.length);
8679
+ const hasSecondaryInfo = hasDescription || hasMeta;
8680
+ const hasLeadingVisual = Boolean(item.image || (showLeadingIcon && item.icon));
8681
+ const hasTrailing = Boolean((showBadge && item.badge) ||
8682
+ item.actions?.length ||
8683
+ shouldShowArrow ||
8684
+ draggable);
8672
8685
  const itemClasses = clsx('designbase-list__item', `designbase-list__item--size-${size}`, `designbase-list__item--variant-${variant}`, `designbase-list__item--type-${itemType}`, `designbase-list__item--layout-${layout}`, `designbase-list__item--spacing-${spacing}`, `designbase-list__item--alignment-${alignment}`, {
8673
8686
  'designbase-list__item--selected': isSelected,
8674
8687
  'designbase-list__item--disabled': item.disabled,
8675
8688
  'designbase-list__item--dragging': isDragging,
8676
- 'designbase-list__item--clickable': onItemClick || selectable,
8689
+ 'designbase-list__item--clickable': isClickable,
8677
8690
  'designbase-list__item--draggable': draggable,
8691
+ 'designbase-list__item--with-leading': hasLeadingVisual,
8692
+ 'designbase-list__item--with-secondary': hasSecondaryInfo,
8693
+ 'designbase-list__item--with-trailing': hasTrailing,
8678
8694
  });
8679
- return (jsxRuntime.jsxs("div", { className: itemClasses, onClick: () => handleItemClick(item, index), draggable: draggable, onDragStart: (e) => handleItemDragStart(e, item.id), onDragOver: handleItemDragOver, onDrop: (e) => handleItemDrop(e, item.id), onDragEnd: handleItemDragEnd, role: selectable ? 'button' : undefined, tabIndex: selectable ? 0 : undefined, "aria-selected": selectable ? isSelected : undefined, children: [selectable && (jsxRuntime.jsx("div", { className: "designbase-list__item-checkbox", children: jsxRuntime.jsx("input", { type: multiple ? 'checkbox' : 'radio', checked: isSelected, onChange: () => handleItemClick(item, index), disabled: item.disabled }) })), item.icon && (jsxRuntime.jsx("div", { className: "designbase-list__item-icon", children: React.isValidElement(item.icon) ? (React.cloneElement(item.icon, {
8680
- size: iconSize,
8681
- color: 'currentColor'
8682
- })) : item.icon })), item.image && (jsxRuntime.jsx("div", { className: "designbase-list__item-image", children: jsxRuntime.jsx("img", { src: item.image, alt: item.title }) })), jsxRuntime.jsxs("div", { className: "designbase-list__item-content", children: [jsxRuntime.jsxs("div", { className: "designbase-list__item-header", children: [jsxRuntime.jsx("h4", { className: "designbase-list__item-title", children: item.title }), item.badge && renderBadge(item.badge)] }), item.description && (jsxRuntime.jsx("p", { className: "designbase-list__item-description", children: item.description })), item.meta && renderMeta(item.meta)] }), item.actions && renderActions(item.actions), draggable && (jsxRuntime.jsx("div", { className: "designbase-list__item-drag-handle", children: "\u22EE\u22EE" }))] }, item.id));
8695
+ const itemIsInteractive = clickableArea === 'item' && isClickable && !item.disabled;
8696
+ const contentIsInteractive = clickableArea === 'content' && isClickable && !item.disabled;
8697
+ return (jsxRuntime.jsxs("div", { className: itemClasses, onClick: itemIsInteractive ? () => handleItemClick(item, index) : undefined, onKeyDown: itemIsInteractive ? (e) => handleItemKeyDown(e, item, index) : undefined, draggable: draggable, onDragStart: (e) => handleItemDragStart(e, item.id), onDragOver: handleItemDragOver, onDrop: (e) => handleItemDrop(e, item.id), onDragEnd: handleItemDragEnd, role: itemIsInteractive ? 'button' : undefined, tabIndex: itemIsInteractive ? 0 : undefined, "aria-selected": selectable ? isSelected : undefined, children: [selectable && (jsxRuntime.jsx("div", { className: "designbase-list__item-checkbox", onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx("input", { type: multiple ? 'checkbox' : 'radio', checked: isSelected, onChange: (e) => {
8698
+ e.stopPropagation();
8699
+ handleItemClick(item, index);
8700
+ }, disabled: item.disabled }) })), showLeadingIcon && item.icon && !item.image && (jsxRuntime.jsx("div", { className: "designbase-list__item-icon", children: React.isValidElement(item.icon)
8701
+ ? React.cloneElement(item.icon, {
8702
+ size: iconSize,
8703
+ color: 'currentColor',
8704
+ })
8705
+ : item.icon })), item.image && (jsxRuntime.jsx("div", { className: "designbase-list__item-image", children: jsxRuntime.jsx("img", { src: item.image, alt: item.title }) })), jsxRuntime.jsxs("div", { className: clsx('designbase-list__item-content', {
8706
+ 'designbase-list__item-content--clickable': contentIsInteractive,
8707
+ }), onClick: contentIsInteractive ? () => handleItemClick(item, index) : undefined, onKeyDown: contentIsInteractive ? (e) => handleItemKeyDown(e, item, index) : undefined, role: contentIsInteractive ? 'button' : undefined, tabIndex: contentIsInteractive ? 0 : undefined, children: [jsxRuntime.jsx("div", { className: "designbase-list__item-header", children: jsxRuntime.jsx("h4", { className: "designbase-list__item-title", children: item.title }) }), hasDescription && jsxRuntime.jsx("p", { className: "designbase-list__item-description", children: item.description }), hasMeta && renderMeta(item.meta)] }), (showBadge && item.badge) || item.actions || shouldShowArrow || draggable ? (jsxRuntime.jsxs("div", { className: "designbase-list__item-trailing", children: [showBadge && item.badge && renderBadge(item.badge), item.actions && renderActions(item.actions), shouldShowArrow && (jsxRuntime.jsx("div", { className: "designbase-list__item-arrow", "aria-hidden": "true", children: jsxRuntime.jsx(icons.ChevronRightIcon, { size: 16 }) })), draggable && jsxRuntime.jsx("div", { className: "designbase-list__item-drag-handle", children: "\u22EE\u22EE" })] })) : null] }, item.id));
8683
8708
  };
8684
8709
  const renderLoadingSkeleton = () => {
8685
8710
  return Array.from({ length: loadingCount }, (_, index) => (jsxRuntime.jsx("div", { className: "designbase-list__item designbase-list__item--loading", children: jsxRuntime.jsxs("div", { className: "designbase-list__item-skeleton", children: [jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-icon" }), jsxRuntime.jsxs("div", { className: "designbase-list__item-skeleton-content", children: [jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-title" }), jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-description" })] })] }) }, index)));
@@ -8691,12 +8716,12 @@
8691
8716
  'designbase-list--loading': loading,
8692
8717
  }, className);
8693
8718
  if (loading) {
8694
- return (jsxRuntime.jsx("div", { className: classes, children: renderLoadingSkeleton() }));
8719
+ return jsxRuntime.jsx("div", { className: classes, children: renderLoadingSkeleton() });
8695
8720
  }
8696
8721
  if (items.length === 0 && emptyState) {
8697
8722
  return (jsxRuntime.jsx("div", { className: classes, children: jsxRuntime.jsx("div", { className: "designbase-list__empty", children: emptyState }) }));
8698
8723
  }
8699
- return (jsxRuntime.jsx("div", { className: classes, children: items.map((item, index) => renderItem(item, index)) }));
8724
+ return jsxRuntime.jsx("div", { className: classes, children: items.map((item, index) => renderItem(item, index)) });
8700
8725
  };
8701
8726
 
8702
8727
  const DesignBaseLogo = ({ width = 193, height = 40, color, className, }) => {
@@ -8784,6 +8809,77 @@
8784
8809
  };
8785
8810
  Logo.displayName = 'Logo';
8786
8811
 
8812
+ const Marquee = ({ children, items, direction = 'left', duration = 20, speed = 1, size = 'm', variant = 'default', bordered, pauseOnHover = true, fadeEdges = false, fadeWidth = 48, edgePadding, gap = 24, alignY = 'center', className, ariaLabel = 'Scrolling content', }) => {
8813
+ const containerRef = React.useRef(null);
8814
+ const baseGroupRef = React.useRef(null);
8815
+ const [containerWidth, setContainerWidth] = React.useState(0);
8816
+ const [baseGroupWidth, setBaseGroupWidth] = React.useState(0);
8817
+ const resolvedItems = React.useMemo(() => ((items && items.length > 0) ? items : (children ? [children] : [])), [items, children]);
8818
+ if (resolvedItems.length === 0) {
8819
+ return null;
8820
+ }
8821
+ const resolvedSpeed = Number.isFinite(speed) && speed > 0 ? speed : 1;
8822
+ const resolvedDuration = Math.max(duration, 1) / resolvedSpeed;
8823
+ const resolvedFadeWidth = Math.max(fadeWidth, 0);
8824
+ const resolvedEdgePadding = edgePadding !== undefined
8825
+ ? Math.max(edgePadding, 0)
8826
+ : (fadeEdges ? resolvedFadeWidth : 0);
8827
+ const resolvedGap = Math.max(gap, 0);
8828
+ React.useEffect(() => {
8829
+ const updateSize = () => {
8830
+ const nextContainerWidth = Math.ceil(containerRef.current?.clientWidth ?? 0);
8831
+ const nextBaseGroupWidth = Math.ceil(baseGroupRef.current?.scrollWidth ?? 0);
8832
+ setContainerWidth((prev) => (prev !== nextContainerWidth ? nextContainerWidth : prev));
8833
+ setBaseGroupWidth((prev) => (prev !== nextBaseGroupWidth ? nextBaseGroupWidth : prev));
8834
+ };
8835
+ updateSize();
8836
+ const observer = new ResizeObserver(updateSize);
8837
+ if (containerRef.current)
8838
+ observer.observe(containerRef.current);
8839
+ if (baseGroupRef.current)
8840
+ observer.observe(baseGroupRef.current);
8841
+ const images = baseGroupRef.current?.querySelectorAll('img') ?? [];
8842
+ images.forEach((img) => {
8843
+ img.addEventListener('load', updateSize);
8844
+ img.addEventListener('error', updateSize);
8845
+ });
8846
+ return () => {
8847
+ observer.disconnect();
8848
+ images.forEach((img) => {
8849
+ img.removeEventListener('load', updateSize);
8850
+ img.removeEventListener('error', updateSize);
8851
+ });
8852
+ };
8853
+ }, [resolvedItems, resolvedGap, size, fadeEdges, resolvedEdgePadding]);
8854
+ const duplicateCount = React.useMemo(() => {
8855
+ if (baseGroupWidth <= 0)
8856
+ return 1;
8857
+ return Math.max(1, Math.ceil(containerWidth / baseGroupWidth));
8858
+ }, [containerWidth, baseGroupWidth]);
8859
+ const isReady = baseGroupWidth > 0;
8860
+ const classes = clsx('designbase-marquee', `designbase-marquee--size-${size}`, `designbase-marquee--variant-${variant}`, `designbase-marquee--align-${alignY}`, {
8861
+ 'designbase-marquee--pause-on-hover': pauseOnHover,
8862
+ 'designbase-marquee--fade-edges': fadeEdges,
8863
+ 'designbase-marquee--right': direction === 'right',
8864
+ 'designbase-marquee--bordered': bordered ?? variant === 'outlined',
8865
+ 'designbase-marquee--ready': isReady,
8866
+ }, className);
8867
+ const style = {
8868
+ '--db-marquee-duration': `${resolvedDuration}s`,
8869
+ // 그룹간 간격까지 포함해 이동 거리를 맞춰야 루프 경계 점프가 사라짐
8870
+ '--db-marquee-shift': `${baseGroupWidth + resolvedGap}px`,
8871
+ '--db-marquee-gap': `${resolvedGap}px`,
8872
+ '--db-marquee-fade-width': `${resolvedFadeWidth}px`,
8873
+ '--db-marquee-edge-padding': `${resolvedEdgePadding}px`,
8874
+ };
8875
+ const screenReaderText = (items && items.length > 0)
8876
+ ? items.filter((item) => typeof item === 'string').join(' • ') || ariaLabel
8877
+ : (typeof children === 'string' ? children : ariaLabel);
8878
+ const renderGroup = (key, ref) => (jsxRuntime.jsx("div", { className: "designbase-marquee__group", "aria-hidden": "true", ref: ref, children: resolvedItems.map((item, index) => (jsxRuntime.jsx("div", { className: "designbase-marquee__item", children: item }, `${key}-${index}`))) }, key));
8879
+ return (jsxRuntime.jsxs("div", { className: classes, style: style, role: "region", "aria-label": ariaLabel, ref: containerRef, children: [jsxRuntime.jsx("span", { className: "designbase-marquee__sr-only", children: screenReaderText }), jsxRuntime.jsxs("div", { className: "designbase-marquee__track", children: [renderGroup('base', baseGroupRef), Array.from({ length: duplicateCount }).map((_, index) => renderGroup(`dup-${index}`))] })] }));
8880
+ };
8881
+ Marquee.displayName = 'Marquee';
8882
+
8787
8883
  const MarkdownEditor = ({ size = 'm', variant = 'default', mode = 'preview', // 기본값을 preview로 변경
8788
8884
  theme = 'light', value = '', placeholder = '마크다운을 입력하세요...', minHeight = 200, maxHeight = 600, autoHeight = false, readonly = false, disabled = false, showToolbar = true, toolbarItems = [], showStatus = true, showWordCount = true, showLineCount = true, autoSave = false, autoSaveInterval = 30000, // 30초
8789
8885
  onFileUpload, onChange, onSave, onFocus, onBlur, className, }) => {
@@ -12595,6 +12691,7 @@
12595
12691
  exports.List = List;
12596
12692
  exports.Logo = Logo;
12597
12693
  exports.MarkdownEditor = MarkdownEditor;
12694
+ exports.Marquee = Marquee;
12598
12695
  exports.Masonry = Masonry;
12599
12696
  exports.MenuItem = MenuItem;
12600
12697
  exports.Modal = Modal;