@designbasekorea/ui 0.5.1 → 0.5.2

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
@@ -4,6 +4,7 @@ var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
5
  var icons = require('@designbasekorea/icons');
6
6
  var $4AOtR$reactdom = require('react-dom');
7
+ var theme = require('@designbasekorea/theme');
7
8
 
8
9
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
9
10
 
@@ -2995,44 +2996,71 @@ const drawStars = (ctx, width, height, starsRef, options) => {
2995
2996
  };
2996
2997
  const drawWaves = (ctx, width, height, options) => {
2997
2998
  const { colors, offset, speedFactor } = options;
2998
- offset.current += 0.02 * speedFactor;
2999
+ offset.current += 0.005 * speedFactor; // Slower, smoother movement
2999
3000
  colors.forEach((color, i) => {
3001
+ const rgb = hexToRgb$1(color);
3002
+ const gradient = ctx.createLinearGradient(0, 0, 0, height);
3003
+ // Gradient from color to transparent for depth
3004
+ gradient.addColorStop(0, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
3005
+ gradient.addColorStop(0.5, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.5)`);
3006
+ gradient.addColorStop(1, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.8)`);
3007
+ ctx.fillStyle = gradient;
3000
3008
  ctx.beginPath();
3001
3009
  ctx.moveTo(0, height);
3002
- const freq = 0.003 + i * 0.001;
3003
- const amp = 30 + i * 20;
3004
- const phase = offset.current + i * 2;
3005
- for (let x = 0; x <= width; x += 10) {
3006
- const y = height / 2 +
3007
- Math.sin(x * freq + phase) * amp +
3008
- Math.sin(x * 0.001 + phase * 0.5) * 50;
3010
+ // Organic wave generation
3011
+ for (let x = 0; x <= width; x += 5) {
3012
+ const freq1 = 0.002 + i * 0.0005;
3013
+ const freq2 = 0.005 + i * 0.001;
3014
+ const phase = offset.current + i * 1.5;
3015
+ // Combine two sine waves for more natural look
3016
+ const y1 = Math.sin(x * freq1 + phase) * (40 + i * 15);
3017
+ const y2 = Math.sin(x * freq2 + phase * 1.2) * (20 + i * 5);
3018
+ const y = height / 1.5 + y1 + y2 + (i * 30); // Base height + waves + layering offset
3009
3019
  ctx.lineTo(x, y);
3010
3020
  }
3011
3021
  ctx.lineTo(width, height);
3012
3022
  ctx.lineTo(0, height);
3013
3023
  ctx.closePath();
3014
- ctx.fillStyle = color;
3024
+ // Add subtle blur for "dreamy" effect
3025
+ // Note: filter can be expensive, use sparingly.
3026
+ // If performance is an issue, remove this toggle or reduce canvas size.
3027
+ // ctx.filter = 'blur(4px)';
3028
+ ctx.globalAlpha = 0.6; // Base transparency
3015
3029
  ctx.fill();
3030
+ ctx.globalAlpha = 1.0;
3031
+ // ctx.filter = 'none';
3016
3032
  });
3017
3033
  };
3018
3034
  const drawPulse = (ctx, width, height, options) => {
3019
3035
  const { colors, time, intensity } = options;
3020
3036
  const centerX = width / 2;
3021
3037
  const centerY = height / 2;
3022
- const maxRadius = Math.max(width, height) * 0.8;
3023
- const intensityMap = { subtle: 0.5, medium: 1, vivid: 1.5 };
3038
+ const maxRadius = Math.max(width, height) * 0.6; // Slightly reduced max radius to keep it contained
3039
+ const intensityMap = { subtle: 0.8, medium: 1.2, vivid: 1.8 }; // Increased base intensity
3024
3040
  const factor = intensityMap[intensity];
3025
3041
  colors.forEach((color, i) => {
3026
- const t = time * 0.02 * factor + (i * (Math.PI * 2)) / colors.length;
3027
- const radius = (Math.sin(t) * 0.2 + 0.5) * maxRadius;
3028
- const alpha = (Math.sin(t + Math.PI) * 0.2 + 0.3) * factor;
3042
+ // Offset time for each color layer
3043
+ const t = time * 0.002 * factor + (i * (Math.PI / 1.5));
3044
+ // Breathing effect for radius
3045
+ const radius = (Math.sin(t) * 0.15 + 0.6) * maxRadius;
3046
+ // Breathing effect for opacity
3047
+ const alpha = (Math.sin(t + Math.PI / 2) * 0.3 + 0.5) * factor; // Higher base alpha (0.2->0.8 range)
3048
+ // Clamp alpha max to 1
3049
+ const safeAlpha = Math.min(Math.max(alpha, 0), 1);
3050
+ if (safeAlpha <= 0.01)
3051
+ return;
3029
3052
  const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
3030
3053
  const rgb = hexToRgb$1(color);
3054
+ // Harder center, softer edge
3031
3055
  gradient.addColorStop(0, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
3032
- gradient.addColorStop(0.5, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha * 0.5})`);
3056
+ gradient.addColorStop(0.2, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${safeAlpha * 0.2})`);
3057
+ gradient.addColorStop(0.6, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${safeAlpha * 0.6})`);
3033
3058
  gradient.addColorStop(1, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
3034
3059
  ctx.fillStyle = gradient;
3060
+ // Use globalCompositeOperation to blend nicely
3061
+ ctx.globalCompositeOperation = 'screen';
3035
3062
  ctx.fillRect(0, 0, width, height);
3063
+ ctx.globalCompositeOperation = 'source-over';
3036
3064
  });
3037
3065
  };
3038
3066
 
@@ -3324,63 +3352,132 @@ const AnimationBackground = ({ type = 'gradient', theme = 'dark', intensity = 's
3324
3352
  }, children: content }), showGrid && (jsxRuntime.jsx(GridOverlay, { size: gridSize, color: effectiveGridColor, opacity: gridOpacity })), children && (jsxRuntime.jsx("div", { className: "designbase-animation-background__content", style: { position: 'relative', zIndex: 10, width: '100%', height: '100%' }, children: children }))] }));
3325
3353
  };
3326
3354
 
3327
- const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, delay = 0, direction = 'left', size = 'm', color = 'primary', customColor, weight = 'normal', align = 'left', gradientColors = ['#667eea', '#764ba2'], waveColors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57'], glowColor = '#667eea', clickable = false, disabled = false, className, onClick, }) => {
3355
+ const AnimationText = ({ children, trigger = 'mount', type = 'fade', speed = 1000, repeat = 1, delay = 0, direction = 'left', size = 'm', color = 'primary', customColor, weight = 'normal', align = 'left', gradientColors = ['#667eea', '#764ba2'], waveColors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57'], glowColor = '#667eea', clickable = false, disabled = false, className, onClick, }) => {
3328
3356
  const [isVisible, setIsVisible] = React.useState(false);
3329
- const [currentIndex, setCurrentIndex] = React.useState(0);
3330
3357
  const [isAnimating, setIsAnimating] = React.useState(false);
3358
+ // Initialize with full text unless it's a mount trigger for typing/decode
3359
+ const [displayText, setDisplayText] = React.useState((type === 'decode' || type === 'typing') && trigger === 'mount' ? '' : children);
3360
+ const [currentRepeat, setCurrentRepeat] = React.useState(0);
3331
3361
  const textRef = React.useRef(null);
3332
- React.useRef(null);
3333
- // 타이핑 애니메이션을 위한 상태
3334
- const [displayText, setDisplayText] = React.useState('');
3362
+ const observerRef = React.useRef(null);
3363
+ // Initial trigger logic
3335
3364
  React.useEffect(() => {
3336
- if (delay > 0) {
3365
+ if (trigger === 'mount') {
3337
3366
  const timer = setTimeout(() => {
3338
3367
  setIsVisible(true);
3368
+ startAnimation();
3339
3369
  }, delay);
3340
3370
  return () => clearTimeout(timer);
3341
3371
  }
3342
- else {
3343
- setIsVisible(true);
3372
+ else if (trigger === 'in-view' && textRef.current) {
3373
+ observerRef.current = new IntersectionObserver((entries) => {
3374
+ if (entries[0].isIntersecting) {
3375
+ setTimeout(() => {
3376
+ setIsVisible(true);
3377
+ startAnimation();
3378
+ }, delay);
3379
+ observerRef.current?.disconnect();
3380
+ }
3381
+ });
3382
+ observerRef.current.observe(textRef.current);
3383
+ return () => observerRef.current?.disconnect();
3344
3384
  }
3345
- }, [delay]);
3346
- // 타이핑 애니메이션
3385
+ }, [trigger, delay]);
3386
+ // Update initial text visibility when props change
3347
3387
  React.useEffect(() => {
3348
- if (type === 'typing' && isVisible) {
3349
- setDisplayText('');
3350
- setCurrentIndex(0);
3351
- const typeInterval = setInterval(() => {
3352
- setCurrentIndex(prev => {
3353
- if (prev >= children.length) {
3354
- clearInterval(typeInterval);
3355
- return prev;
3356
- }
3357
- setDisplayText(children.slice(0, prev + 1));
3358
- return prev + 1;
3359
- });
3360
- }, speed / children.length);
3361
- return () => clearInterval(typeInterval);
3388
+ if ((type === 'typing' || type === 'decode') && trigger === 'mount') ;
3389
+ else {
3390
+ // For hover/click, ensure text is visible when not animating
3391
+ if (!isAnimating) {
3392
+ setDisplayText(children);
3393
+ }
3362
3394
  }
3363
- }, [type, isVisible, children, speed]);
3364
- // 반복 애니메이션
3365
- React.useEffect(() => {
3366
- if (repeat > 0 && type !== 'typing') {
3367
- let repeatCount = 0;
3368
- const repeatAnimation = () => {
3369
- setIsAnimating(true);
3370
- setTimeout(() => {
3395
+ }, [children, type, trigger]);
3396
+ const startAnimation = () => {
3397
+ setIsAnimating(true);
3398
+ setCurrentRepeat(0);
3399
+ if (type === 'typing') {
3400
+ startTyping(0);
3401
+ }
3402
+ else if (type === 'decode') {
3403
+ startDecoding(0);
3404
+ }
3405
+ };
3406
+ const startTyping = (iteration) => {
3407
+ setDisplayText('');
3408
+ let currentIndex = 0;
3409
+ const interval = setInterval(() => {
3410
+ if (currentIndex >= children.length) {
3411
+ clearInterval(interval);
3412
+ // Repetition logic
3413
+ if (repeat === 0 || iteration < repeat - 1) {
3414
+ setTimeout(() => {
3415
+ startTyping(iteration + 1);
3416
+ }, 500);
3417
+ }
3418
+ else {
3371
3419
  setIsAnimating(false);
3372
- repeatCount++;
3373
- if (repeatCount < repeat) {
3374
- setTimeout(repeatAnimation, speed);
3375
- }
3376
- }, speed);
3377
- };
3378
- if (isVisible) {
3379
- setTimeout(repeatAnimation, speed);
3420
+ }
3421
+ return;
3380
3422
  }
3423
+ setDisplayText(children.slice(0, currentIndex + 1));
3424
+ currentIndex++;
3425
+ }, speed / children.length);
3426
+ };
3427
+ const startDecoding = (iteration) => {
3428
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+';
3429
+ let iterations = 0;
3430
+ const interval = setInterval(() => {
3431
+ setDisplayText(children.split('').map((char, index) => {
3432
+ if (index < iterations) {
3433
+ return children[index];
3434
+ }
3435
+ return characters[Math.floor(Math.random() * characters.length)];
3436
+ }).join(''));
3437
+ if (iterations >= children.length) {
3438
+ clearInterval(interval);
3439
+ setDisplayText(children);
3440
+ // Repetition logic
3441
+ if (repeat === 0 || iteration < repeat - 1) {
3442
+ setTimeout(() => {
3443
+ startDecoding(iteration + 1);
3444
+ }, 500);
3445
+ }
3446
+ else {
3447
+ setIsAnimating(false);
3448
+ }
3449
+ }
3450
+ iterations += 1 / 3;
3451
+ }, 30);
3452
+ };
3453
+ const handleMouseEnter = () => {
3454
+ if (trigger === 'hover') {
3455
+ setIsVisible(true);
3456
+ startAnimation();
3381
3457
  }
3382
- }, [repeat, type, speed, isVisible]);
3458
+ };
3459
+ const handleMouseLeave = () => {
3460
+ if (trigger === 'hover') {
3461
+ setIsVisible(false);
3462
+ setIsAnimating(false);
3463
+ if (type === 'typing' || type === 'decode') {
3464
+ setDisplayText(children);
3465
+ }
3466
+ }
3467
+ };
3383
3468
  const handleClick = () => {
3469
+ if (trigger === 'click') {
3470
+ setIsVisible(!isVisible);
3471
+ if (isVisible) {
3472
+ setIsAnimating(false);
3473
+ if (type === 'typing' || type === 'decode') {
3474
+ setDisplayText(children);
3475
+ }
3476
+ }
3477
+ else {
3478
+ startAnimation();
3479
+ }
3480
+ }
3384
3481
  if (clickable && !disabled && onClick) {
3385
3482
  onClick();
3386
3483
  }
@@ -3397,14 +3494,6 @@ const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, dela
3397
3494
  }
3398
3495
  return {};
3399
3496
  };
3400
- const getWaveStyle = () => {
3401
- if (type === 'wave') {
3402
- return {
3403
- '--wave-colors': waveColors.join(', '),
3404
- };
3405
- }
3406
- return {};
3407
- };
3408
3497
  const getGlowStyle = () => {
3409
3498
  if (type === 'glow') {
3410
3499
  return {
@@ -3413,26 +3502,52 @@ const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, dela
3413
3502
  }
3414
3503
  return {};
3415
3504
  };
3416
- const classes = classNames('designbase-animation-text', `designbase-animation-text--${type}`, `designbase-animation-text--${size}`, `designbase-animation-text--${color}`, `designbase-animation-text--${weight}`, `designbase-animation-text--${align}`, `designbase-animation-text--${direction}`, {
3505
+ // For typing, the class should be applied to the inner element to handle caret correctly with ghost element
3506
+ const containerClasses = classNames('designbase-animation-text',
3507
+ // Exclude typing logic from outer container to prevent caret on full-width ghost container
3508
+ type !== 'typing' && `designbase-animation-text--${type}`, `designbase-animation-text--${size}`, `designbase-animation-text--${color}`, `designbase-animation-text--${weight}`, `designbase-animation-text--${align}`, `designbase-animation-text--${direction}`, {
3417
3509
  'designbase-animation-text--visible': isVisible,
3418
3510
  'designbase-animation-text--animating': isAnimating,
3419
- 'designbase-animation-text--clickable': clickable,
3511
+ 'designbase-animation-text--clickable': clickable || trigger === 'click',
3420
3512
  'designbase-animation-text--disabled': disabled,
3421
3513
  }, className);
3422
3514
  const style = {
3423
3515
  ...getGradientStyle(),
3424
- ...getWaveStyle(),
3425
3516
  ...getGlowStyle(),
3426
3517
  '--db-animation-speed': `${speed}ms`,
3427
3518
  '--db-text-custom': customColor,
3519
+ '--db-wave-colors': waveColors.join(', '),
3520
+ '--db-animation-iteration-count': repeat === 0 ? 'infinite' : repeat,
3428
3521
  };
3429
- const renderText = () => {
3430
- if (type === 'typing') {
3431
- return displayText;
3432
- }
3433
- return children;
3434
- };
3435
- return (jsxRuntime.jsx("div", { ref: textRef, className: classes, style: style, onClick: handleClick, children: renderText() }));
3522
+ const renderContent = () => {
3523
+ if (type === 'wave' || type === 'shake') {
3524
+ if (!isVisible && !isAnimating)
3525
+ return children;
3526
+ return children.split('').map((char, index) => (jsxRuntime.jsx("span", { style: {
3527
+ animationDelay: `${index * 0.05}s`,
3528
+ display: 'inline-block'
3529
+ }, children: char === ' ' ? '\u00A0' : char }, index)));
3530
+ }
3531
+ return displayText;
3532
+ };
3533
+ return (jsxRuntime.jsxs("div", { ref: textRef, className: containerClasses, style: style, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [jsxRuntime.jsx("span", { "aria-hidden": "true", style: {
3534
+ visibility: 'hidden',
3535
+ pointerEvents: 'none',
3536
+ userSelect: 'none',
3537
+ whiteSpace: type === 'typing' ? 'pre-wrap' : undefined
3538
+ }, children: children }), jsxRuntime.jsx("span", { className: classNames({
3539
+ 'designbase-animation-text--typing': type === 'typing',
3540
+ 'designbase-animation-text--animating': isAnimating && type === 'typing' // Ensure animating class is passed for typing caret
3541
+ }), style: {
3542
+ position: 'absolute',
3543
+ top: 0,
3544
+ left: 0,
3545
+ // For typing, we want width to be auto so caret follows text
3546
+ // For others, width 100% matches ghost element
3547
+ width: type === 'typing' ? 'auto' : '100%',
3548
+ height: '100%',
3549
+ whiteSpace: type === 'typing' ? 'pre-wrap' : undefined // Ensure pre-wrap behavior matches
3550
+ }, children: renderContent() })] }));
3436
3551
  };
3437
3552
 
3438
3553
  const AudioPlayer = ({ src, title, artist, album, albumArt, size = 'm', variant = 'default', theme = 'auto', autoPlay = false, loop = false, muted = false, showControls = true, enableKeyboard = 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, repeatMode = 'none', shuffle = false, onPlay, onPause, onEnded, onTimeUpdate, onVolumeChange, onPlaylistChange, onPlaybackRateChange, onRepeatModeChange, onShuffleChange, onError, className, }) => {
@@ -4194,6 +4309,7 @@ SegmentControl.displayName = 'SegmentControl';
4194
4309
 
4195
4310
  const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true, closeOnEscape = true, children, className, overlayClassName, }) => {
4196
4311
  const modalRef = React.useRef(null);
4312
+ const titleId = React.useId();
4197
4313
  // 아이콘 크기 계산 (m이 기본값)
4198
4314
  const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
4199
4315
  // Prevent scrolling while modal is open
@@ -4225,11 +4341,11 @@ const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true,
4225
4341
  return null;
4226
4342
  const modalClasses = clsx('designbase-modal', `designbase-modal--${size}`, className);
4227
4343
  const overlayClasses = clsx('designbase-modal__overlay', overlayClassName);
4228
- return (jsxRuntime.jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxRuntime.jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? 'modal-title' : undefined, children: [title && (jsxRuntime.jsx(ModalHeader, { title: title, showCloseButton: true, onClose: onClose, iconSize: iconSize })), jsxRuntime.jsx("div", { className: "designbase-modal__content", children: children })] }) }));
4344
+ return (jsxRuntime.jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxRuntime.jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, children: [title && (jsxRuntime.jsx(ModalHeader, { title: title, titleId: titleId, showCloseButton: true, onClose: onClose, iconSize: iconSize })), jsxRuntime.jsx("div", { className: "designbase-modal__content", children: children })] }) }));
4229
4345
  };
4230
- const ModalHeader = ({ title, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
4346
+ const ModalHeader = ({ title, titleId, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
4231
4347
  const classes = clsx('designbase-modal__header', className);
4232
- return (jsxRuntime.jsxs("div", { className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntime.jsx("h2", { id: "modal-title", className: "designbase-modal__title", children: title })), children] }), showCloseButton && onClose && (jsxRuntime.jsx("button", { type: "button", onClick: onClose, "aria-label": "\uBAA8\uB2EC \uB2EB\uAE30", className: "designbase-modal__close-button", children: jsxRuntime.jsx(icons.CloseIcon, { size: iconSize, color: "currentColor" }) }))] }));
4348
+ return (jsxRuntime.jsxs("div", { className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntime.jsx("h2", { id: titleId || 'modal-title', className: "designbase-modal__title", children: title })), children] }), showCloseButton && onClose && (jsxRuntime.jsx("button", { type: "button", onClick: onClose, "aria-label": "\uBAA8\uB2EC \uB2EB\uAE30", className: "designbase-modal__close-button", children: jsxRuntime.jsx(icons.CloseIcon, { size: iconSize, color: "currentColor" }) }))] }));
4233
4349
  };
4234
4350
  const ModalBody = ({ className, children, }) => {
4235
4351
  const classes = clsx('designbase-modal__body', className);
@@ -4492,6 +4608,7 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
4492
4608
  const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? (multiple ? [] : ''));
4493
4609
  const [searchTerm, setSearchTerm] = React.useState('');
4494
4610
  const [focusedIndex, setFocusedIndex] = React.useState(-1);
4611
+ const labelId = React.useId();
4495
4612
  const containerRef = React.useRef(null);
4496
4613
  const inputRef = React.useRef(null);
4497
4614
  const dropdownRef = React.useRef(null);
@@ -4651,7 +4768,7 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
4651
4768
  const filteredOptions = getFilteredOptions();
4652
4769
  const selectedLabels = getSelectedLabels();
4653
4770
  const hasValue = multiple ? selectedValue.length > 0 : selectedValue !== '';
4654
- return (jsxRuntime.jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxRuntime.jsxs("label", { className: "designbase-select__label", children: [label, required && jsxRuntime.jsx("span", { className: "designbase-select__required", children: "*" })] })), jsxRuntime.jsxs("div", { className: triggerClasses, onClick: handleToggle, onFocus: onFocus, onBlur: onBlur, tabIndex: disabled || readOnly ? -1 : 0, role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-labelledby": label ? 'select-label' : undefined, ...props, children: [jsxRuntime.jsx("div", { className: "designbase-select__value", children: multiple ? (jsxRuntime.jsx("div", { className: "designbase-select__tags", ref: tagsContainerRef, children: selectedValue.map((value) => {
4771
+ return (jsxRuntime.jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxRuntime.jsxs("label", { id: labelId, className: "designbase-select__label", children: [label, required && jsxRuntime.jsx("span", { className: "designbase-select__required", children: "*" })] })), jsxRuntime.jsxs("div", { className: triggerClasses, onClick: handleToggle, onFocus: onFocus, onBlur: onBlur, tabIndex: disabled || readOnly ? -1 : 0, role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-labelledby": label ? labelId : undefined, ...props, children: [jsxRuntime.jsx("div", { className: "designbase-select__value", children: multiple ? (jsxRuntime.jsx("div", { className: "designbase-select__tags", ref: tagsContainerRef, children: selectedValue.map((value) => {
4655
4772
  const option = options.find(opt => opt.value === value);
4656
4773
  return (jsxRuntime.jsxs("span", { className: "designbase-select__tag", children: [jsxRuntime.jsx("span", { className: "designbase-select__tag-label", children: option?.label || value }), jsxRuntime.jsx("button", { type: "button", className: "designbase-select__tag-remove", onClick: (e) => {
4657
4774
  e.stopPropagation();
@@ -5271,7 +5388,7 @@ const Card = React.forwardRef(function Card({ title, subtitle, description, chil
5271
5388
  return null;
5272
5389
  return (jsxRuntime.jsx("div", { className: "designbase-card__actions", children: actions.map((action, index) => {
5273
5390
  const ActionIcon = action.icon;
5274
- return (jsxRuntime.jsx(Button, { variant: action.variant || 'primary', size: action.size || 's', onClick: () => handleActionClick(action, index), disabled: action.disabled || disabled, loading: !!action.loading, icon: ActionIcon, children: action.label }, index));
5391
+ return (jsxRuntime.jsx(Button, { variant: action.variant || 'primary', size: action.size || 's', onClick: () => handleActionClick(action, index), disabled: action.disabled || disabled, loading: !!action.loading, startIcon: ActionIcon, children: action.label }, index));
5275
5392
  }) }));
5276
5393
  };
5277
5394
  const renderContent = () => (jsxRuntime.jsxs("div", { className: "designbase-card__content", children: [renderIcon(), (title || subtitle) && (jsxRuntime.jsxs("div", { className: "designbase-card__header", children: [title && jsxRuntime.jsx("h3", { className: "designbase-card__title", children: title }), subtitle && jsxRuntime.jsx("p", { className: "designbase-card__subtitle", children: subtitle })] })), description && jsxRuntime.jsx("p", { className: "designbase-card__description", children: description }), children && jsxRuntime.jsx("div", { className: "designbase-card__body", children: children }), renderTags(), renderMeta(), renderActions()] }));
@@ -10899,7 +11016,7 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
10899
11016
  }
10900
11017
  };
10901
11018
 
10902
- const Sidebar = ({ size = 'm', variant = 'default', position = 'left', logo, onLogoClick, items = [], onItemClick, userProfile, userMenuItems = [], onUserMenuItemClick, collapsed = false, onToggle, collapsible = true, fixed = false, fullHeight = false, shadow = false, className, ...props }) => {
11019
+ const Sidebar = ({ size = 'm', variant = 'default', position = 'left', showLogo = false, logo, onLogoClick, items = [], onItemClick, userProfile, userMenuItems = [], onUserMenuItemClick, collapsed = false, onToggle, collapsible = true, fixed = false, fullHeight = false, shadow = false, className, ...props }) => {
10903
11020
  const [expandedItems, setExpandedItems] = React.useState([]);
10904
11021
  const handleToggle = () => {
10905
11022
  if (onToggle) {
@@ -10940,24 +11057,24 @@ const Sidebar = ({ size = 'm', variant = 'default', position = 'left', logo, onL
10940
11057
  const hasChildren = item.children && item.children.length > 0;
10941
11058
  return (jsxRuntime.jsx("li", { className: "designbase-sidebar__item", children: jsxRuntime.jsx(MenuItem, { ...item, type: "block", style: "accordion", depth: level, expanded: isExpanded, expandable: hasChildren, onClick: () => handleItemClick(item), onChildClick: (child) => handleItemClick(child) }) }, item.id));
10942
11059
  };
10943
- return (jsxRuntime.jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxRuntime.jsxs("div", { className: "designbase-sidebar__container", children: [jsxRuntime.jsxs("div", { className: "designbase-sidebar__header", children: [jsxRuntime.jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, onKeyDown: (e) => {
11060
+ return (jsxRuntime.jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxRuntime.jsxs("div", { className: "designbase-sidebar__container", children: [showLogo && (jsxRuntime.jsxs("div", { className: "designbase-sidebar__header", children: [jsxRuntime.jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, onKeyDown: (e) => {
10944
11061
  if (onLogoClick && (e.key === 'Enter' || e.key === ' ')) {
10945
11062
  e.preventDefault();
10946
11063
  onLogoClick();
10947
11064
  }
10948
11065
  }, children: logo || jsxRuntime.jsx(Logo, { size: "s" }) }), collapsible && (jsxRuntime.jsx(Button, { variant: "ghost", size: "s", iconOnly: true, className: "designbase-sidebar__toggle", onPress: handleToggle, "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: jsxRuntime.jsx(icons.ChevronLeftIcon, { className: clsx('designbase-sidebar__toggle-icon', {
10949
11066
  'designbase-sidebar__toggle-icon--collapsed': collapsed,
10950
- }) }) }))] }), jsxRuntime.jsx("nav", { className: "designbase-sidebar__nav", children: jsxRuntime.jsx("ul", { className: "designbase-sidebar__nav-list", children: items.map((item) => renderSidebarItem(item)) }) }), userProfile && !collapsed && (jsxRuntime.jsxs("div", { className: "designbase-sidebar__user", children: [jsxRuntime.jsxs("div", { className: "designbase-sidebar__user-info", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
11067
+ }) }) }))] })), jsxRuntime.jsx("nav", { className: "designbase-sidebar__nav", children: jsxRuntime.jsx("ul", { className: "designbase-sidebar__nav-list", children: items.map((item) => renderSidebarItem(item)) }) }), userProfile && !collapsed && (jsxRuntime.jsxs("div", { className: "designbase-sidebar__user", children: [jsxRuntime.jsxs("div", { className: "designbase-sidebar__user-info", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
10951
11068
  if (e.key === 'Enter' || e.key === ' ') {
10952
11069
  e.preventDefault();
10953
11070
  onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
10954
11071
  }
10955
- }, style: { cursor: 'pointer' }, children: [userProfile.avatar ? (jsxRuntime.jsx("img", { src: userProfile.avatar, alt: userProfile.name, className: "designbase-sidebar__user-avatar" })) : (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-avatar-placeholder", children: userProfile.name.charAt(0).toUpperCase() })), jsxRuntime.jsxs("div", { className: "designbase-sidebar__user-details", children: [jsxRuntime.jsx("div", { className: "designbase-sidebar__user-name", children: userProfile.name }), userProfile.email && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-email", children: userProfile.email })), userProfile.role && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-role", children: userProfile.role }))] })] }), userMenuItems.length > 0 && (jsxRuntime.jsx("ul", { className: "designbase-sidebar__user-menu", children: userMenuItems.map((item) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(MenuItem, { id: item.id, label: item.label, href: item.href, icon: item.icon, disabled: item.disabled, type: "block", style: "accordion", onClick: () => handleUserMenuItemClick(item) }) }, item.id))) }))] })), userProfile && collapsed && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-collapsed", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
11072
+ }, style: { cursor: 'pointer' }, children: [jsxRuntime.jsx(Avatar, { src: userProfile.avatar, initials: userProfile.name, alt: userProfile.name, size: "s", className: "designbase-sidebar__user-avatar" }), jsxRuntime.jsxs("div", { className: "designbase-sidebar__user-details", children: [jsxRuntime.jsx("div", { className: "designbase-sidebar__user-name", children: userProfile.name }), userProfile.email && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-email", children: userProfile.email })), userProfile.role && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-role", children: userProfile.role }))] })] }), userMenuItems.length > 0 && (jsxRuntime.jsx("ul", { className: "designbase-sidebar__user-menu", children: userMenuItems.map((item) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(MenuItem, { id: item.id, label: item.label, href: item.href, icon: item.icon, disabled: item.disabled, type: "block", style: "accordion", onClick: () => handleUserMenuItemClick(item) }) }, item.id))) }))] })), userProfile && collapsed && (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-collapsed", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
10956
11073
  if (e.key === 'Enter' || e.key === ' ') {
10957
11074
  e.preventDefault();
10958
11075
  onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
10959
11076
  }
10960
- }, style: { cursor: 'pointer' }, children: userProfile.avatar ? (jsxRuntime.jsx("img", { src: userProfile.avatar, alt: userProfile.name, className: "designbase-sidebar__user-avatar-collapsed" })) : (jsxRuntime.jsx("div", { className: "designbase-sidebar__user-avatar-placeholder-collapsed", children: userProfile.name.charAt(0).toUpperCase() })) }))] }) }));
11077
+ }, style: { cursor: 'pointer' }, children: jsxRuntime.jsx(Avatar, { src: userProfile.avatar, initials: userProfile.name, alt: userProfile.name, size: "s", className: "designbase-sidebar__user-avatar-collapsed" }) }))] }) }));
10961
11078
  };
10962
11079
  Sidebar.displayName = 'Sidebar';
10963
11080
 
@@ -12392,25 +12509,18 @@ const YouTubePlayer = ({ videoId, title, description, size = 'm', variant = 'def
12392
12509
  };
12393
12510
  YouTubePlayer.displayName = 'YouTubePlayer';
12394
12511
 
12395
- /**
12396
- * Designbase UI 컴포넌트 라이브러리 메인 엔트리 포인트
12397
- *
12398
- * 목적: 모든 UI 컴포넌트와 타입을 내보냄
12399
- * 기능: Tree-shaking 가능한 개별 컴포넌트 내보내기
12400
- * 사용법: import { Button, Input } from '@designbasekorea/ui'
12401
- */
12402
- // 테마 CSS 자동 로드 (로컬 복사본 사용)
12403
- // 테마 관련 유틸리티 재내보내기
12404
- const setTheme = (theme) => {
12405
- console.log('setTheme called with:', theme);
12406
- };
12407
- const getTheme = () => {
12408
- return 'light';
12409
- };
12410
- const toggleTheme = () => {
12411
- console.log('toggleTheme called');
12412
- };
12413
-
12512
+ Object.defineProperty(exports, 'getTheme', {
12513
+ enumerable: true,
12514
+ get: function () { return theme.getTheme; }
12515
+ });
12516
+ Object.defineProperty(exports, 'setTheme', {
12517
+ enumerable: true,
12518
+ get: function () { return theme.setTheme; }
12519
+ });
12520
+ Object.defineProperty(exports, 'toggleTheme', {
12521
+ enumerable: true,
12522
+ get: function () { return theme.toggleTheme; }
12523
+ });
12414
12524
  exports.Accordion = Accordion;
12415
12525
  exports.AdBanner = AdBanner;
12416
12526
  exports.Alert = Alert;
@@ -12503,8 +12613,5 @@ exports.Tooltip = Tooltip;
12503
12613
  exports.Tutorial = Tutorial;
12504
12614
  exports.VideoPlayer = VideoPlayer;
12505
12615
  exports.YouTubePlayer = YouTubePlayer;
12506
- exports.getTheme = getTheme;
12507
- exports.setTheme = setTheme;
12508
- exports.toggleTheme = toggleTheme;
12509
12616
  exports.useToast = useToast;
12510
12617
  //# sourceMappingURL=index.js.map