@designbasekorea/ui 0.5.1 → 0.5.4
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/README.md +100 -59
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +216 -107
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +227 -109
- package/dist/index.js.map +1 -1
- package/dist/index.umd.css +1 -1
- package/dist/index.umd.css.map +1 -1
- package/dist/index.umd.js +230 -113
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
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.
|
|
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
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
const
|
|
3007
|
-
|
|
3008
|
-
|
|
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
|
-
|
|
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.
|
|
3023
|
-
const intensityMap = { subtle: 0.
|
|
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
|
-
|
|
3027
|
-
const
|
|
3028
|
-
|
|
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.
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
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' &&
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
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
|
-
}, [
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
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
|
-
|
|
3373
|
-
|
|
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
|
-
}
|
|
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
|
-
|
|
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
|
|
3430
|
-
if (type === '
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
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,12 @@ 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 ?
|
|
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, }) => {
|
|
4347
|
+
const fallbackTitleId = React.useId();
|
|
4231
4348
|
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:
|
|
4349
|
+
return (jsxRuntime.jsxs("div", { className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntime.jsx("h2", { id: titleId || fallbackTitleId, 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
4350
|
};
|
|
4234
4351
|
const ModalBody = ({ className, children, }) => {
|
|
4235
4352
|
const classes = clsx('designbase-modal__body', className);
|
|
@@ -4492,6 +4609,11 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
|
|
|
4492
4609
|
const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? (multiple ? [] : ''));
|
|
4493
4610
|
const [searchTerm, setSearchTerm] = React.useState('');
|
|
4494
4611
|
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
|
4612
|
+
const selectId = React.useId();
|
|
4613
|
+
const labelId = `${selectId}-label`;
|
|
4614
|
+
const listboxId = `${selectId}-listbox`;
|
|
4615
|
+
const helperTextId = `${selectId}-helper-text`;
|
|
4616
|
+
const errorTextId = `${selectId}-error-text`;
|
|
4495
4617
|
const containerRef = React.useRef(null);
|
|
4496
4618
|
const inputRef = React.useRef(null);
|
|
4497
4619
|
const dropdownRef = React.useRef(null);
|
|
@@ -4651,23 +4773,29 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
|
|
|
4651
4773
|
const filteredOptions = getFilteredOptions();
|
|
4652
4774
|
const selectedLabels = getSelectedLabels();
|
|
4653
4775
|
const hasValue = multiple ? selectedValue.length > 0 : selectedValue !== '';
|
|
4654
|
-
|
|
4776
|
+
const activeDescendantId = focusedIndex >= 0 ? `${selectId}-option-${focusedIndex}` : undefined;
|
|
4777
|
+
const describedBy = error && errorMessage
|
|
4778
|
+
? errorTextId
|
|
4779
|
+
: helperText
|
|
4780
|
+
? helperTextId
|
|
4781
|
+
: undefined;
|
|
4782
|
+
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-controls": listboxId, "aria-activedescendant": activeDescendantId, "aria-labelledby": label ? labelId : undefined, "aria-describedby": describedBy, "aria-invalid": error, ...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
4783
|
const option = options.find(opt => opt.value === value);
|
|
4656
4784
|
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
4785
|
e.stopPropagation();
|
|
4658
4786
|
handleRemoveValue(value);
|
|
4659
4787
|
}, children: jsxRuntime.jsx(icons.CloseIcon, { size: 12 }) })] }, value));
|
|
4660
|
-
}) })) : (jsxRuntime.jsx("span", { className: "designbase-select__single-value", children: selectedLabels || placeholder })) }), jsxRuntime.jsxs("div", { className: "designbase-select__indicators", children: [showClearButton && hasValue && !disabled && !readOnly && (jsxRuntime.jsx("button", { type: "button", className: "designbase-select__clear-button", onClick: handleClearAll, "aria-label": "\uBAA8\uB4E0 \uAC12 \uC9C0\uC6B0\uAE30", children: jsxRuntime.jsx(icons.CloseIcon, { size: 16 }) })), jsxRuntime.jsx("div", { className: "designbase-select__chevron", children: isOpen ? jsxRuntime.jsx(icons.ChevronUpIcon, { size: 16 }) : jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] })] }), jsxRuntime.jsxs("div", { className: dropdownClasses, ref: dropdownRef, children: [searchable && (jsxRuntime.jsx("div", { className: "designbase-select__search", onMouseDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx(SearchBar, { value: searchTerm, onChange: (value) => setSearchTerm(value), onSearch: (val) => setSearchTerm(val), placeholder: "\uC635\uC158 \uAC80\uC0C9", size: size, variant: "outlined", fullWidth: true, onFocus: (e) => e.stopPropagation(), onBlur: (e) => e.stopPropagation() }) })), jsxRuntime.jsx("div", { className: "designbase-select__options", style: { maxHeight: `${maxHeight}px` }, role: "listbox", children: filteredOptions.length === 0 ? (jsxRuntime.jsx("div", { className: "designbase-select__no-options", children: searchTerm ? '검색 결과가 없습니다.' : '옵션이 없습니다.' })) : (filteredOptions.map((option, index) => {
|
|
4788
|
+
}) })) : (jsxRuntime.jsx("span", { className: "designbase-select__single-value", children: selectedLabels || placeholder })) }), jsxRuntime.jsxs("div", { className: "designbase-select__indicators", children: [showClearButton && hasValue && !disabled && !readOnly && (jsxRuntime.jsx("button", { type: "button", className: "designbase-select__clear-button", onClick: handleClearAll, "aria-label": "\uBAA8\uB4E0 \uAC12 \uC9C0\uC6B0\uAE30", children: jsxRuntime.jsx(icons.CloseIcon, { size: 16 }) })), jsxRuntime.jsx("div", { className: "designbase-select__chevron", children: isOpen ? jsxRuntime.jsx(icons.ChevronUpIcon, { size: 16 }) : jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] })] }), jsxRuntime.jsxs("div", { className: dropdownClasses, ref: dropdownRef, children: [searchable && (jsxRuntime.jsx("div", { className: "designbase-select__search", onMouseDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx(SearchBar, { value: searchTerm, onChange: (value) => setSearchTerm(value), onSearch: (val) => setSearchTerm(val), placeholder: "\uC635\uC158 \uAC80\uC0C9", size: size, variant: "outlined", fullWidth: true, onFocus: (e) => e.stopPropagation(), onBlur: (e) => e.stopPropagation() }) })), jsxRuntime.jsx("div", { className: "designbase-select__options", style: { maxHeight: `${maxHeight}px` }, id: listboxId, role: "listbox", children: filteredOptions.length === 0 ? (jsxRuntime.jsx("div", { className: "designbase-select__no-options", children: searchTerm ? '검색 결과가 없습니다.' : '옵션이 없습니다.' })) : (filteredOptions.map((option, index) => {
|
|
4661
4789
|
const isSelected = multiple
|
|
4662
4790
|
? selectedValue.includes(option.value)
|
|
4663
4791
|
: selectedValue === option.value;
|
|
4664
4792
|
const isFocused = index === focusedIndex;
|
|
4665
|
-
return (jsxRuntime.jsxs("div", { className: clsx('designbase-select__option', {
|
|
4793
|
+
return (jsxRuntime.jsxs("div", { id: `${selectId}-option-${index}`, className: clsx('designbase-select__option', {
|
|
4666
4794
|
'designbase-select__option--selected': isSelected,
|
|
4667
4795
|
'designbase-select__option--focused': isFocused,
|
|
4668
4796
|
'designbase-select__option--disabled': option.disabled,
|
|
4669
4797
|
}), onClick: () => handleOptionSelect(option), role: "option", "aria-selected": isSelected, children: [multiple && (jsxRuntime.jsx("div", { className: "designbase-select__checkbox", children: jsxRuntime.jsx(Checkbox, { isSelected: isSelected, isDisabled: option.disabled, size: "s", hasLabel: false, onChange: () => handleOptionSelect(option) }) })), jsxRuntime.jsx("span", { className: "designbase-select__option-label", children: option.label })] }, option.value));
|
|
4670
|
-
})) })] }), helperText && !error && (jsxRuntime.jsx("p", { className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsxRuntime.jsx("p", { className: "designbase-select__error-message", children: errorMessage }))] }));
|
|
4798
|
+
})) })] }), helperText && !error && (jsxRuntime.jsx("p", { id: helperTextId, className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsxRuntime.jsx("p", { id: errorTextId, className: "designbase-select__error-message", children: errorMessage }))] }));
|
|
4671
4799
|
};
|
|
4672
4800
|
Select.displayName = 'Select';
|
|
4673
4801
|
|
|
@@ -5271,7 +5399,7 @@ const Card = React.forwardRef(function Card({ title, subtitle, description, chil
|
|
|
5271
5399
|
return null;
|
|
5272
5400
|
return (jsxRuntime.jsx("div", { className: "designbase-card__actions", children: actions.map((action, index) => {
|
|
5273
5401
|
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,
|
|
5402
|
+
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
5403
|
}) }));
|
|
5276
5404
|
};
|
|
5277
5405
|
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 +11027,7 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
|
|
|
10899
11027
|
}
|
|
10900
11028
|
};
|
|
10901
11029
|
|
|
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 }) => {
|
|
11030
|
+
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
11031
|
const [expandedItems, setExpandedItems] = React.useState([]);
|
|
10904
11032
|
const handleToggle = () => {
|
|
10905
11033
|
if (onToggle) {
|
|
@@ -10940,24 +11068,24 @@ const Sidebar = ({ size = 'm', variant = 'default', position = 'left', logo, onL
|
|
|
10940
11068
|
const hasChildren = item.children && item.children.length > 0;
|
|
10941
11069
|
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
11070
|
};
|
|
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) => {
|
|
11071
|
+
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
11072
|
if (onLogoClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
10945
11073
|
e.preventDefault();
|
|
10946
11074
|
onLogoClick();
|
|
10947
11075
|
}
|
|
10948
11076
|
}, 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
11077
|
'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) => {
|
|
11078
|
+
}) }) }))] })), 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
11079
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10952
11080
|
e.preventDefault();
|
|
10953
11081
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10954
11082
|
}
|
|
10955
|
-
}, style: { cursor: 'pointer' }, children: [
|
|
11083
|
+
}, 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
11084
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10957
11085
|
e.preventDefault();
|
|
10958
11086
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10959
11087
|
}
|
|
10960
|
-
}, style: { cursor: 'pointer' }, children:
|
|
11088
|
+
}, 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
11089
|
};
|
|
10962
11090
|
Sidebar.displayName = 'Sidebar';
|
|
10963
11091
|
|
|
@@ -12392,25 +12520,18 @@ const YouTubePlayer = ({ videoId, title, description, size = 'm', variant = 'def
|
|
|
12392
12520
|
};
|
|
12393
12521
|
YouTubePlayer.displayName = 'YouTubePlayer';
|
|
12394
12522
|
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
|
|
12406
|
-
};
|
|
12407
|
-
const getTheme = () => {
|
|
12408
|
-
return 'light';
|
|
12409
|
-
};
|
|
12410
|
-
const toggleTheme = () => {
|
|
12411
|
-
console.log('toggleTheme called');
|
|
12412
|
-
};
|
|
12413
|
-
|
|
12523
|
+
Object.defineProperty(exports, 'getTheme', {
|
|
12524
|
+
enumerable: true,
|
|
12525
|
+
get: function () { return theme.getTheme; }
|
|
12526
|
+
});
|
|
12527
|
+
Object.defineProperty(exports, 'setTheme', {
|
|
12528
|
+
enumerable: true,
|
|
12529
|
+
get: function () { return theme.setTheme; }
|
|
12530
|
+
});
|
|
12531
|
+
Object.defineProperty(exports, 'toggleTheme', {
|
|
12532
|
+
enumerable: true,
|
|
12533
|
+
get: function () { return theme.toggleTheme; }
|
|
12534
|
+
});
|
|
12414
12535
|
exports.Accordion = Accordion;
|
|
12415
12536
|
exports.AdBanner = AdBanner;
|
|
12416
12537
|
exports.Alert = Alert;
|
|
@@ -12503,8 +12624,5 @@ exports.Tooltip = Tooltip;
|
|
|
12503
12624
|
exports.Tutorial = Tutorial;
|
|
12504
12625
|
exports.VideoPlayer = VideoPlayer;
|
|
12505
12626
|
exports.YouTubePlayer = YouTubePlayer;
|
|
12506
|
-
exports.getTheme = getTheme;
|
|
12507
|
-
exports.setTheme = setTheme;
|
|
12508
|
-
exports.toggleTheme = toggleTheme;
|
|
12509
12627
|
exports.useToast = useToast;
|
|
12510
12628
|
//# sourceMappingURL=index.js.map
|