@designbasekorea/ui 0.5.6 → 0.6.1

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
@@ -4603,7 +4603,7 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
4603
4603
  };
4604
4604
  SearchBar.displayName = 'SearchBar';
4605
4605
 
4606
- const Select = ({ value, defaultValue, options, label, placeholder = '선택하세요', multiple = false, searchable = false, disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, size = 'm', fullWidth = false, dropdownWidth = 'auto', position = 'bottom', maxHeight = 200, showClearButton = true, useMobileBottomSheet = false, className, onChange, onFocus, onBlur, ...props }) => {
4606
+ const Select = ({ value, defaultValue, options, label, placeholder = '선택하세요', multiple = false, searchable = false, disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, size = 'm', fullWidth = false, dropdownWidth = 'auto', position = 'bottom', maxHeight = 200, showClearButton = false, useMobileBottomSheet = false, className, onChange, onFocus, onBlur, ...props }) => {
4607
4607
  const [isOpen, setIsOpen] = useState(false);
4608
4608
  const [selectedValue, setSelectedValue] = useState(value ?? defaultValue ?? (multiple ? [] : ''));
4609
4609
  const [searchTerm, setSearchTerm] = useState('');
@@ -5925,7 +5925,7 @@ const rgbToHsl = (r, g, b) => {
5925
5925
  return { h, s: s * 100, l: l * 100 };
5926
5926
  };
5927
5927
  /* ----------------------- 컴포넌트 ----------------------- */
5928
- const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left', value, defaultValue = '#006FFF', showInput = true, showAlpha = true, showFormatSelector = true, showCopyButton = true, showEyedropper = true, disabled = false, readonly = false, onChangeFormat = 'hex', fireOnInit = false, changeDebounceMs = 0, emitDuringDrag = true, onChange, onApply, onCancel, className, }) => {
5928
+ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-start', value, defaultValue = '#006FFF', showInput = true, showAlpha = true, showFormatSelector = true, showCopyButton = true, showEyedropper = true, disabled = false, readonly = false, onChangeFormat = 'hex', fireOnInit = false, changeDebounceMs = 0, emitDuringDrag = true, onChange, onApply, onCancel, className, }) => {
5929
5929
  /** 초기 HSV — StrictMode에서도 안전하도록 lazy init */
5930
5930
  const initialHex = (isHex(value) ? normalizeHex(value) : normalizeHex(defaultValue)) || '#006FFF';
5931
5931
  const initialRgb = hexToRgb(initialHex) || { r: 0, g: 111, b: 255 };
@@ -6299,14 +6299,14 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
6299
6299
  const Trigger = (jsxs("div", { className: "designbase-color-picker__trigger", onClick: () => !disabled && !readonly && (type === 'modal' ? handleModalOpen() : setIsOpen(v => !v)), children: [jsx("div", { className: "designbase-color-picker__color-display", children: jsx("div", { className: "designbase-color-picker__color-box", style: {
6300
6300
  backgroundColor: showAlpha ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a / 100})` : hex
6301
6301
  } }) }), showInput && (jsx("input", { type: "text", value: colorInput, onChange: (e) => setColorInput(e.target.value), onKeyDown: onColorKeyDown, onBlur: onColorBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-color-picker__input", placeholder: "#000000" })), showInput && showCopyButton && (jsx("button", { type: "button", className: "designbase-color-picker__copy-button-inline", onClick: (e) => { e.stopPropagation(); onCopy(); }, disabled: disabled, "aria-label": "Copy color value", children: isCopied ? jsx(DoneIcon$1, { size: 14 }) : jsx(CopyIcon, { size: 14 }) })), jsx("button", { type: "button", className: "designbase-color-picker__toggle", disabled: disabled, "aria-label": "Toggle color picker", children: jsx(ChevronDownIcon, { size: 16 }) })] }));
6302
- const Selector = (jsxs("div", { className: "designbase-color-picker__selector", children: [jsx("div", { className: "designbase-color-picker__color-area", children: jsx("div", { ref: areaRef, className: "designbase-color-picker__color-field", style: areaBackground, onMouseDown: onAreaMouseDown, onMouseMove: onAreaMouseMove, onMouseUp: onAreaMouseUp, onMouseLeave: onAreaLeave, onTouchStart: onAreaTouchStart, onTouchMove: onAreaTouchMove, onTouchEnd: onAreaTouchEnd, children: jsx("div", { className: "designbase-color-picker__color-pointer", style: { left: `${s}%`, top: `${100 - v}%`, backgroundColor: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` } }) }) }), jsxs("div", { className: "designbase-color-picker__controls", children: [showEyedropper && isEyedropperAvailable && (jsx(Button, { variant: "tertiary", size: "m", iconOnly: true, onClick: onEyedrop, "aria-label": "Eyedropper tool", children: jsx(EyedropperIcon, {}) })), jsxs("div", { className: "designbase-color-picker__slider-container", children: [jsx("div", { className: "designbase-color-picker__hue-slider", children: jsx("input", { type: "range", min: 0, max: 360, value: h, onChange: onHueChange, className: "designbase-color-picker__slider designbase-color-picker__slider--hue", style: hueTrackStyle }) }), showAlpha && (jsx("div", { className: "designbase-color-picker__alpha-slider", children: jsx("input", { type: "range", min: 0, max: 100, value: a, onChange: onAlphaChange, className: "designbase-color-picker__slider designbase-color-picker__slider--alpha", style: alphaTrackStyle }) }))] })] }), jsxs("div", { className: "designbase-color-picker__value-display", children: [showFormatSelector && (jsx(Select, { value: format, onChange: (v) => setFormat(v), showClearButton: false, options: [
6302
+ const Selector = (jsxs("div", { className: "designbase-color-picker__selector", children: [jsx("div", { className: "designbase-color-picker__color-area", children: jsx("div", { ref: areaRef, className: "designbase-color-picker__color-field", style: areaBackground, onMouseDown: onAreaMouseDown, onMouseMove: onAreaMouseMove, onMouseUp: onAreaMouseUp, onMouseLeave: onAreaLeave, onTouchStart: onAreaTouchStart, onTouchMove: onAreaTouchMove, onTouchEnd: onAreaTouchEnd, children: jsx("div", { className: "designbase-color-picker__color-pointer", style: { left: `${s}%`, top: `${100 - v}%`, backgroundColor: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` } }) }) }), jsxs("div", { className: "designbase-color-picker__controls", children: [showEyedropper && isEyedropperAvailable && (jsx(Button, { variant: "tertiary", size: size === 's' ? 's' : 'm', iconOnly: true, onClick: onEyedrop, "aria-label": "Eyedropper tool", children: jsx(EyedropperIcon, {}) })), jsxs("div", { className: "designbase-color-picker__slider-container", children: [jsx("div", { className: "designbase-color-picker__hue-slider", children: jsx("input", { type: "range", min: 0, max: 360, value: h, onChange: onHueChange, className: "designbase-color-picker__slider designbase-color-picker__slider--hue", style: hueTrackStyle }) }), showAlpha && (jsx("div", { className: "designbase-color-picker__alpha-slider", children: jsx("input", { type: "range", min: 0, max: 100, value: a, onChange: onAlphaChange, className: "designbase-color-picker__slider designbase-color-picker__slider--alpha", style: alphaTrackStyle }) }))] })] }), jsxs("div", { className: "designbase-color-picker__value-display", children: [showFormatSelector && (jsx(Select, { value: format, onChange: (v) => setFormat(v), showClearButton: false, options: [
6303
6303
  { label: 'HEX', value: 'hex' },
6304
6304
  { label: 'RGB', value: 'rgb' },
6305
6305
  { label: 'RGBA', value: 'rgba' },
6306
6306
  { label: 'HSL', value: 'hsl' },
6307
6307
  { label: 'HSLA', value: 'hsla' },
6308
- ], size: "s", position: "top" })), jsx(Input, { type: "text", value: colorInput, onChange: setColorInput, onKeyDown: onColorKeyDown, onBlur: onColorBlur, placeholder: "#000000", size: "s", className: "designbase-color-picker__value-input" }), showAlpha && (jsxs("div", { className: "designbase-color-picker__alpha-input-wrap", children: [jsx(Input, { type: "text", inputMode: "numeric", value: alphaInput, onChange: (value) => setAlphaInput(value.replace(/[^\d]/g, '').slice(0, 3)), onKeyDown: onAlphaInputKeyDown, onBlur: onAlphaInputBlur, placeholder: "100", size: "s", className: "designbase-color-picker__alpha-input", "aria-label": "Alpha percent" }), jsx("span", { className: "designbase-color-picker__alpha-suffix", children: "%" })] })), showCopyButton && (jsx(Button, { variant: "tertiary", size: "m", iconOnly: true, onClick: onCopy, "aria-label": "Copy color value", children: isCopied ? jsx(DoneIcon$1, {}) : jsx(CopyIcon, {}) }))] })] }));
6309
- return (jsxs("div", { ref: pickerRef, className: classes, children: [Trigger, type === 'dropdown' && isOpen && (jsx("div", { className: "designbase-color-picker__dropdown", onClick: (e) => e.stopPropagation(), children: Selector })), type === 'modal' && (jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC0C9\uC0C1 \uC120\uD0DD", size: "s", children: [jsx(ModalBody, { children: Selector }), jsx(ModalFooter, { children: jsxs("div", { style: { display: 'flex', gap: 8, justifyContent: 'flex-end' }, children: [jsx(Button, { variant: "tertiary", size: "m", onClick: handleModalCancel, children: "\uCDE8\uC18C" }), jsx(Button, { variant: "primary", size: "m", onClick: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
6308
+ ], size: "s", position: "top" })), jsx(Input, { type: "text", value: colorInput, onChange: setColorInput, onKeyDown: onColorKeyDown, onBlur: onColorBlur, placeholder: "#000000", size: "s", className: "designbase-color-picker__value-input" }), showAlpha && (jsxs("div", { className: "designbase-color-picker__alpha-input-wrap", children: [jsx(Input, { type: "text", inputMode: "numeric", value: alphaInput, onChange: (value) => setAlphaInput(value.replace(/[^\d]/g, '').slice(0, 3)), onKeyDown: onAlphaInputKeyDown, onBlur: onAlphaInputBlur, placeholder: "100", size: "s", className: "designbase-color-picker__alpha-input", "aria-label": "Alpha percent" }), jsx("span", { className: "designbase-color-picker__alpha-suffix", children: "%" })] })), showCopyButton && (jsx(Button, { variant: "tertiary", size: size === 's' ? 's' : 'm', iconOnly: true, onClick: onCopy, "aria-label": "Copy color value", children: isCopied ? jsx(DoneIcon$1, {}) : jsx(CopyIcon, {}) }))] })] }));
6309
+ return (jsxs("div", { ref: pickerRef, className: classes, children: [Trigger, type === 'dropdown' && isOpen && (jsx("div", { className: clsx("designbase-color-picker__dropdown", `designbase-color-picker__dropdown--${position}`), onClick: (e) => e.stopPropagation(), children: Selector })), type === 'modal' && (jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC0C9\uC0C1 \uC120\uD0DD", size: "s", children: [jsx(ModalBody, { children: Selector }), jsx(ModalFooter, { children: jsxs("div", { style: { display: 'flex', gap: 8, justifyContent: 'flex-end' }, children: [jsx(Button, { variant: "tertiary", size: "m", onClick: handleModalCancel, children: "\uCDE8\uC18C" }), jsx(Button, { variant: "primary", size: "m", onClick: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
6310
6310
  };
6311
6311
  ColorPicker.displayName = 'ColorPicker';
6312
6312
 
@@ -6671,7 +6671,7 @@ const ContextMenu = ({ items, open, x, y, onClose, className, }) => {
6671
6671
  };
6672
6672
  ContextMenu.displayName = 'ContextMenu';
6673
6673
 
6674
- const DatePicker = ({ mode = 'single', type = 'dropdown', value, defaultValue, onChange, minDate, maxDate, events = [], showOutsideDays = true, startOfWeek = 'sunday', size = 'm', variant = 'default', highlightWeekends = true, highlightHolidays = false, today = new Date(), locale = 'ko-KR', format = 'yyyy-MM-dd', className, disabled = false, readonly = false,
6674
+ const DatePicker = ({ mode = 'single', type = 'dropdown', value, defaultValue, onChange, minDate, maxDate, events = [], showOutsideDays = true, startOfWeek = 'sunday', size = 'm', variant = 'default', highlightWeekends = true, highlightHolidays = false, today = new Date(), locale = 'ko-KR', format = 'yyyy-MM-dd', className, disabled = false, readonly = false, dropdownPosition = 'bottom-start',
6675
6675
  // 인라인 모드
6676
6676
  inline = false, }) => {
6677
6677
  // 아이콘 크기 계산 (m이 기본값)
@@ -7011,7 +7011,7 @@ inline = false, }) => {
7011
7011
  'designbase-date-picker--readonly': readonly,
7012
7012
  'designbase-date-picker--open': isOpen,
7013
7013
  }, className);
7014
- return (jsxs("div", { ref: pickerRef, className: classes, children: [jsxs("div", { className: "designbase-date-picker__trigger", children: [jsx("button", { type: "button", className: "designbase-date-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsx(CalendarIcon, { size: 16 }) }), jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-date-picker__input", placeholder: "\uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694", "aria-label": "\uB0A0\uC9DC \uC785\uB825" }), jsx("button", { type: "button", className: "designbase-date-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsx(ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsx("div", { className: "designbase-date-picker__dropdown", role: "dialog", "aria-modal": "false", children: renderCalendar(false) })), type === 'modal' && (jsx(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uB0A0\uC9DC \uC120\uD0DD", size: "s", children: renderCalendar(true) }))] }));
7014
+ return (jsxs("div", { ref: pickerRef, className: classes, children: [jsxs("div", { className: "designbase-date-picker__trigger", children: [jsx("button", { type: "button", className: "designbase-date-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsx(CalendarIcon, { size: 16 }) }), jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-date-picker__input", placeholder: "\uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694", "aria-label": "\uB0A0\uC9DC \uC785\uB825" }), jsx("button", { type: "button", className: "designbase-date-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsx(ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsx("div", { className: clsx("designbase-date-picker__dropdown", `designbase-date-picker__dropdown--${dropdownPosition}`), role: "dialog", "aria-modal": "false", children: renderCalendar(false) })), type === 'modal' && (jsx(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uB0A0\uC9DC \uC120\uD0DD", size: "s", children: renderCalendar(true) }))] }));
7015
7015
  };
7016
7016
 
7017
7017
  const Drawer = ({ isOpen, onClose, title, children, position = 'right', size = 'm', showCloseButton = true, closeOnBackdropClick = true, closeOnEscape = true, animationDuration = 300, showOverlay = true, overlayClosable = true, className, style, zIndex = 1000, trapFocus = true, id, ...props }) => {
@@ -7621,7 +7621,7 @@ const Textarea = forwardRef(({ label, placeholder, defaultValue, value, size = '
7621
7621
  Textarea.displayName = 'Textarea';
7622
7622
 
7623
7623
  const ITEM_HEIGHT = 40;
7624
- const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:00', format = '24h', minuteStep = 1, disabled = false, readonly = false, onChange, className, }) => {
7624
+ const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:00', format = '24h', minuteStep = 1, disabled = false, readonly = false, dropdownPosition = 'bottom-start', onChange, className, }) => {
7625
7625
  const [selectedTime, setSelectedTime] = useState(value || defaultValue);
7626
7626
  const [isOpen, setIsOpen] = useState(false);
7627
7627
  const [inputValue, setInputValue] = useState(value || defaultValue);
@@ -7860,7 +7860,7 @@ const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:0
7860
7860
  }, children: "\uC120\uD0DD" }) }))] }));
7861
7861
  };
7862
7862
  const classes = clsx('designbase-time-picker', `designbase-time-picker--${size}`, { 'designbase-time-picker--disabled': disabled, 'designbase-time-picker--readonly': readonly, 'designbase-time-picker--open': isOpen }, className);
7863
- return (jsxs("div", { ref: pickerRef, className: classes, children: [jsxs("div", { className: "designbase-time-picker__trigger", children: [jsx("button", { type: "button", className: "designbase-time-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsx(ClockIcon, { size: 16 }) }), jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-time-picker__input", placeholder: is12h ? (showSeconds ? '12:00:00 PM' : '12:00 PM') : (showSeconds ? '12:00:00' : '12:00'), "aria-label": "\uC2DC\uAC04 \uC785\uB825" }), jsx("button", { type: "button", className: "designbase-time-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsx(ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsx("div", { className: "designbase-time-picker__dropdown", role: "dialog", "aria-modal": "false", children: renderTimeSelector(false) })), type === 'modal' && (jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC2DC\uAC04 \uC120\uD0DD", size: "s", children: [renderTimeSelector(true), jsx(ModalFooter, { children: jsxs("div", { className: "designbase-time-picker__modal-footer", children: [jsx(Button, { variant: "secondary", size: "m", onPress: handleModalCancel, children: "\uCDE8\uC18C" }), jsx(Button, { variant: "primary", size: "m", onPress: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
7863
+ return (jsxs("div", { ref: pickerRef, className: classes, children: [jsxs("div", { className: "designbase-time-picker__trigger", children: [jsx("button", { type: "button", className: "designbase-time-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsx(ClockIcon, { size: 16 }) }), jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-time-picker__input", placeholder: is12h ? (showSeconds ? '12:00:00 PM' : '12:00 PM') : (showSeconds ? '12:00:00' : '12:00'), "aria-label": "\uC2DC\uAC04 \uC785\uB825" }), jsx("button", { type: "button", className: "designbase-time-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsx(ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsx("div", { className: clsx("designbase-time-picker__dropdown", `designbase-time-picker__dropdown--${dropdownPosition}`), role: "dialog", "aria-modal": "false", children: renderTimeSelector(false) })), type === 'modal' && (jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC2DC\uAC04 \uC120\uD0DD", size: "s", children: [renderTimeSelector(true), jsx(ModalFooter, { children: jsxs("div", { className: "designbase-time-picker__modal-footer", children: [jsx(Button, { variant: "secondary", size: "m", onPress: handleModalCancel, children: "\uCDE8\uC18C" }), jsx(Button, { variant: "primary", size: "m", onPress: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
7864
7864
  };
7865
7865
  TimePicker.displayName = 'TimePicker';
7866
7866
 
@@ -8255,6 +8255,32 @@ const HeroFeature = ({ title, subtitle, description, image, imageAlt, background
8255
8255
  return (jsxs("section", { className: classes, style: containerStyle, children: [renderBackground(), renderOverlay(), jsxs("div", { className: "designbase-hero-feature__container", children: [jsxs("div", { className: "designbase-hero-feature__content", children: [icon && (jsx("div", { className: "designbase-hero-feature__icon", children: icon })), renderBadge(), jsx("h1", { className: "designbase-hero-feature__title", children: title }), subtitle && (jsx("h2", { className: "designbase-hero-feature__subtitle", children: subtitle })), description && (jsx("p", { className: "designbase-hero-feature__description", children: description })), renderButtons(), renderStats()] }), variant === 'split' && renderImage()] }), variant !== 'split' && renderImage()] }));
8256
8256
  };
8257
8257
 
8258
+ /**
8259
+ * ImagePlaceholder 컴포넌트
8260
+ *
8261
+ * 이미지가 없거나 업로드 전 대기 상태일 때 격자 패턴과 라벨을 보여주는 자리표시자입니다.
8262
+ */
8263
+ const ImagePlaceholder = ({ className, style, label, showLabel = false, patternSize = 20, patternColor = '#f3f3f3', backgroundColor = '#e7e7e7', width = '100%', height, aspectRatio, hoverEffect = false, onClick, }) => {
8264
+ const rootStyle = {
8265
+ width,
8266
+ height,
8267
+ aspectRatio,
8268
+ ...style,
8269
+ };
8270
+ const patternStyle = {
8271
+ '--db-placeholder-bg': backgroundColor,
8272
+ '--db-placeholder-pattern': patternColor,
8273
+ '--db-placeholder-size': `${patternSize}px`,
8274
+ '--db-placeholder-half-size': `${patternSize / 2}px`,
8275
+ };
8276
+ const classes = clsx('designbase-image-placeholder', {
8277
+ 'designbase-image-placeholder--hover': hoverEffect,
8278
+ 'designbase-image-placeholder--clickable': !!onClick,
8279
+ }, className);
8280
+ return (jsxs("div", { className: classes, style: rootStyle, onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, children: [jsx("div", { className: "designbase-image-placeholder__pattern", style: patternStyle }), showLabel && label && (jsx("div", { className: "designbase-image-placeholder__label-wrap", children: jsx("span", { className: "designbase-image-placeholder__label", children: label }) }))] }));
8281
+ };
8282
+ ImagePlaceholder.displayName = 'ImagePlaceholder';
8283
+
8258
8284
  const Lightbox = ({ images, currentIndex = 0, size = 'l', isOpen, onOpenChange, onImageChange, enableZoom = true, enableRotate = true, enableDownload = true, enableFullscreen = true, enableKeyboard = true, enableWheelZoom = true, showThumbnails = true, showCounter = true, showCloseButton = true, showNavigationButtons = true, showToolbar = true, closeOnBackdropClick = true, closeOnEscape = true, className, }) => {
8259
8285
  const [internalCurrentIndex, setInternalCurrentIndex] = useState(currentIndex);
8260
8286
  const [zoomLevel, setZoomLevel] = useState(1);
@@ -9354,6 +9380,17 @@ const OnboardingModal = ({ steps, currentStep = 0, isOpen, onClose, onStepChange
9354
9380
  };
9355
9381
  OnboardingModal.displayName = 'OnboardingModal';
9356
9382
 
9383
+ /**
9384
+ * PageHeader 컴포넌트
9385
+ *
9386
+ * 브레드크럼, 타이틀, 서브타이틀, 설명 및 액션(버튼, 탭 등)을 포함하는 페이지 헤더 섹션입니다.
9387
+ */
9388
+ const PageHeader = ({ title, description, subtitle, breadcrumbs, actions, align = 'center', className, }) => {
9389
+ const classes = clsx('designbase-page-header', `designbase-page-header--${align}`, className);
9390
+ return (jsxs("div", { className: classes, children: [breadcrumbs && breadcrumbs.length > 0 && (jsx("div", { className: "designbase-page-header__breadcrumbs", children: jsx(Breadcrumbs, { items: breadcrumbs, size: "s" }) })), jsxs("div", { className: "designbase-page-header__content", children: [jsx("h1", { className: "designbase-page-header__title", children: title }), subtitle && (jsx("h2", { className: "designbase-page-header__subtitle", children: subtitle })), description && (jsx("div", { className: "designbase-page-header__description", children: description }))] }), actions && (jsx("div", { className: "designbase-page-header__actions", children: actions }))] }));
9391
+ };
9392
+ PageHeader.displayName = 'PageHeader';
9393
+
9357
9394
  const Tutorial = ({ steps, currentStep = 0, isActive, onStart, onEnd, onStepChange, onNext, onPrev, indicatorType = 'numbers', indicatorSize = 'm', closeIcon: CloseIconComponent = CloseIcon, prevIcon: PrevIconComponent = ChevronLeftIcon, nextIcon: NextIconComponent = ChevronRightIcon, className, ...props }) => {
9358
9395
  const [internalStep, setInternalStep] = useState(currentStep);
9359
9396
  const [targetElement, setTargetElement] = useState(null);
@@ -10038,7 +10075,7 @@ const Progress = ({ value, max = 100, size = 'm', variant = 'default', type = 'l
10038
10075
  return (jsx("div", { className: classes, children: type === 'linear' ? renderLinearProgress() : renderCircularProgress() }));
10039
10076
  };
10040
10077
 
10041
- const ProgressStep = ({ items, size = 'm', layout = 'vertical', currentStep = 0, clickable = false, fullWidth = false, disabled = false, className, style, onStepClick, }) => {
10078
+ const ProgressStep = ({ items, size = 'm', layout = 'horizontal', currentStep = 0, clickable = false, fullWidth = false, disabled = false, className, style, onStepClick, }) => {
10042
10079
  const handleStepClick = (item, index) => {
10043
10080
  if (disabled || item.disabled || !clickable)
10044
10081
  return;
@@ -10076,7 +10113,7 @@ const ProgressStep = ({ items, size = 'm', layout = 'vertical', currentStep = 0,
10076
10113
  e.preventDefault();
10077
10114
  handleStepClick(item, index);
10078
10115
  }
10079
- }, children: [status === 'active' && (jsx("div", { className: "designbase-progress-step__pulse" })), item.icon ? (jsx("div", { className: "designbase-progress-step__icon", children: item.icon })) : (jsx("span", { className: "designbase-progress-step__number", children: index + 1 }))] }), !isLast && (jsx("div", { className: connectorClasses }))] }), jsxs("div", { className: "designbase-progress-step__content", children: [jsxs("div", { className: "designbase-progress-step__header", children: [jsx("h3", { className: "designbase-progress-step__title", children: item.title }), item.timestamp && (jsx("span", { className: "designbase-progress-step__timestamp", children: item.timestamp }))] }), item.description && (jsx("p", { className: "designbase-progress-step__description", children: item.description }))] })] }, item.id));
10116
+ }, children: [status === 'active' && (jsx("div", { className: "designbase-progress-step__pulse" })), item.icon ? (jsx("div", { className: "designbase-progress-step__icon", children: item.icon })) : (jsx("div", { className: "designbase-progress-step__icon", children: status === 'completed' ? (jsx(DoneIcon$1, { size: size === 's' ? 12 : size === 'l' ? 20 : 16 })) : status === 'error' ? (jsx(WarningFilledIcon, { size: size === 's' ? 12 : size === 'l' ? 20 : 16 })) : (jsx("span", { className: "designbase-progress-step__number", children: index + 1 })) }))] }), !isLast && (jsx("div", { className: connectorClasses }))] }), jsxs("div", { className: "designbase-progress-step__content", children: [jsx("div", { className: "designbase-progress-step__header", children: jsx("h3", { className: "designbase-progress-step__title", children: item.title }) }), item.description && (jsx("p", { className: "designbase-progress-step__description", children: item.description })), item.timestamp && (jsx("span", { className: "designbase-progress-step__timestamp", children: item.timestamp }))] })] }, item.id));
10080
10117
  }) }));
10081
10118
  };
10082
10119
 
@@ -12182,6 +12219,28 @@ const Toolbar = ({ items, size = 'm', variant = 'default', position = 'top', ful
12182
12219
  return (jsx("div", { className: classes, children: jsxs("div", { className: "designbase-toolbar__content", children: [Object.entries(groupedItems).map(([groupName, groupItems], groupIndex) => (jsxs("div", { className: "designbase-toolbar__group", children: [groupItems.map(renderItem), groupIndex < Object.keys(groupedItems).length - 1 && (jsx("div", { className: "designbase-toolbar__group-separator" }))] }, groupName))), children && (jsx("div", { className: "designbase-toolbar__children", children: children }))] }) }));
12183
12220
  };
12184
12221
 
12222
+ /**
12223
+ * TopBanner 컴포넌트
12224
+ *
12225
+ * 페이지 최상단에 위치하여 공지사항이나 프로모션을 안내하는 슬림한 배너입니다.
12226
+ */
12227
+ const TopBanner = ({ badgeText, content, image, linkText, onLinkPress, onClose, variant = 'primary', fixed = false, className, }) => {
12228
+ const [isVisible, setIsVisible] = useState(true);
12229
+ if (!isVisible)
12230
+ return null;
12231
+ const handleClose = () => {
12232
+ setIsVisible(false);
12233
+ onClose?.();
12234
+ };
12235
+ const isDarkBg = variant === 'primary' || variant === 'dark';
12236
+ const classes = clsx('designbase-top-banner', `designbase-top-banner--${variant}`, {
12237
+ 'designbase-top-banner--fixed': fixed,
12238
+ 'designbase-top-banner--has-image': !!image,
12239
+ }, className);
12240
+ return (jsx("div", { className: classes, role: "alert", children: jsxs("div", { className: "designbase-top-banner__container", children: [jsxs("div", { className: "designbase-top-banner__content", children: [image && (jsx("div", { className: "designbase-top-banner__image-wrapper", children: jsx("img", { src: image, alt: "", className: "designbase-top-banner__image" }) })), badgeText && (jsx(Badge, { size: "s", variant: isDarkBg ? 'secondary' : 'primary', style: "text", className: "designbase-top-banner__badge", children: badgeText })), jsx("span", { className: "designbase-top-banner__text", children: content }), linkText && (jsx(Button, { className: "designbase-top-banner__link", variant: isDarkBg ? 'secondary' : 'ghost', size: "s", onPress: onLinkPress, endIcon: ChevronRightIcon, children: linkText }))] }), jsx(Button, { className: "designbase-top-banner__close", variant: "ghost", size: "m", iconOnly: true, onPress: handleClose, "aria-label": "\uB2EB\uAE30", children: jsx(CloseIcon, {}) })] }) }));
12241
+ };
12242
+ TopBanner.displayName = 'TopBanner';
12243
+
12185
12244
  const VideoPlayer = ({ src, poster, title, description, size = 'm', variant = 'default', theme = 'auto', autoPlay = false, loop = false, muted = false, showControls = true, enableFullscreen = true, enableKeyboard = true, enableTouch = true, showProgress = true, showTime = true, showVolume = true, showSettings = false, playlist = [], currentIndex = 0, autoPause = true, playbackRates = [0.5, 0.75, 1, 1.25, 1.5, 2], defaultPlaybackRate = 1, qualities = [], defaultQuality = '', subtitles = [], defaultSubtitle = '', onPlay, onPause, onEnded, onTimeUpdate, onVolumeChange, onFullscreenChange, onPlaylistChange, onPlaybackRateChange, onQualityChange, onSubtitleChange, onError, className, }) => {
12186
12245
  const videoRef = useRef(null);
12187
12246
  const containerRef = useRef(null);
@@ -12634,5 +12693,5 @@ const YouTubePlayer = ({ videoId, title, description, size = 'm', variant = 'def
12634
12693
  };
12635
12694
  YouTubePlayer.displayName = 'YouTubePlayer';
12636
12695
 
12637
- export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Marquee, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Testimonial, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, Tutorial, VideoPlayer, YouTubePlayer, useToast };
12696
+ export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, ImagePlaceholder, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Marquee, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, PageHeader, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Testimonial, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, TopBanner, Tutorial, VideoPlayer, YouTubePlayer, useToast };
12638
12697
  //# sourceMappingURL=index.esm.js.map