@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.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('@designbasekorea/icons'), require('react-dom')) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', '@designbasekorea/icons', 'react-dom'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DesignbaseUI = {}, global.jsxRuntime, global.React, global.icons, global.ReactDOM));
|
|
5
|
-
})(this, (function (exports, jsxRuntime, React, icons, $4AOtR$reactdom) { 'use strict';
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react/jsx-runtime'), require('react'), require('@designbasekorea/icons'), require('react-dom'), require('@designbasekorea/theme')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react/jsx-runtime', 'react', '@designbasekorea/icons', 'react-dom', '@designbasekorea/theme'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DesignbaseUI = {}, global.jsxRuntime, global.React, global.icons, global.ReactDOM, global.theme));
|
|
5
|
+
})(this, (function (exports, jsxRuntime, React, icons, $4AOtR$reactdom, theme) { 'use strict';
|
|
6
6
|
|
|
7
7
|
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}
|
|
8
8
|
|
|
@@ -2994,44 +2994,71 @@
|
|
|
2994
2994
|
};
|
|
2995
2995
|
const drawWaves = (ctx, width, height, options) => {
|
|
2996
2996
|
const { colors, offset, speedFactor } = options;
|
|
2997
|
-
offset.current += 0.
|
|
2997
|
+
offset.current += 0.005 * speedFactor; // Slower, smoother movement
|
|
2998
2998
|
colors.forEach((color, i) => {
|
|
2999
|
+
const rgb = hexToRgb$1(color);
|
|
3000
|
+
const gradient = ctx.createLinearGradient(0, 0, 0, height);
|
|
3001
|
+
// Gradient from color to transparent for depth
|
|
3002
|
+
gradient.addColorStop(0, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
|
|
3003
|
+
gradient.addColorStop(0.5, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.5)`);
|
|
3004
|
+
gradient.addColorStop(1, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.8)`);
|
|
3005
|
+
ctx.fillStyle = gradient;
|
|
2999
3006
|
ctx.beginPath();
|
|
3000
3007
|
ctx.moveTo(0, height);
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
const
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
+
// Organic wave generation
|
|
3009
|
+
for (let x = 0; x <= width; x += 5) {
|
|
3010
|
+
const freq1 = 0.002 + i * 0.0005;
|
|
3011
|
+
const freq2 = 0.005 + i * 0.001;
|
|
3012
|
+
const phase = offset.current + i * 1.5;
|
|
3013
|
+
// Combine two sine waves for more natural look
|
|
3014
|
+
const y1 = Math.sin(x * freq1 + phase) * (40 + i * 15);
|
|
3015
|
+
const y2 = Math.sin(x * freq2 + phase * 1.2) * (20 + i * 5);
|
|
3016
|
+
const y = height / 1.5 + y1 + y2 + (i * 30); // Base height + waves + layering offset
|
|
3008
3017
|
ctx.lineTo(x, y);
|
|
3009
3018
|
}
|
|
3010
3019
|
ctx.lineTo(width, height);
|
|
3011
3020
|
ctx.lineTo(0, height);
|
|
3012
3021
|
ctx.closePath();
|
|
3013
|
-
|
|
3022
|
+
// Add subtle blur for "dreamy" effect
|
|
3023
|
+
// Note: filter can be expensive, use sparingly.
|
|
3024
|
+
// If performance is an issue, remove this toggle or reduce canvas size.
|
|
3025
|
+
// ctx.filter = 'blur(4px)';
|
|
3026
|
+
ctx.globalAlpha = 0.6; // Base transparency
|
|
3014
3027
|
ctx.fill();
|
|
3028
|
+
ctx.globalAlpha = 1.0;
|
|
3029
|
+
// ctx.filter = 'none';
|
|
3015
3030
|
});
|
|
3016
3031
|
};
|
|
3017
3032
|
const drawPulse = (ctx, width, height, options) => {
|
|
3018
3033
|
const { colors, time, intensity } = options;
|
|
3019
3034
|
const centerX = width / 2;
|
|
3020
3035
|
const centerY = height / 2;
|
|
3021
|
-
const maxRadius = Math.max(width, height) * 0.
|
|
3022
|
-
const intensityMap = { subtle: 0.
|
|
3036
|
+
const maxRadius = Math.max(width, height) * 0.6; // Slightly reduced max radius to keep it contained
|
|
3037
|
+
const intensityMap = { subtle: 0.8, medium: 1.2, vivid: 1.8 }; // Increased base intensity
|
|
3023
3038
|
const factor = intensityMap[intensity];
|
|
3024
3039
|
colors.forEach((color, i) => {
|
|
3025
|
-
|
|
3026
|
-
const
|
|
3027
|
-
|
|
3040
|
+
// Offset time for each color layer
|
|
3041
|
+
const t = time * 0.002 * factor + (i * (Math.PI / 1.5));
|
|
3042
|
+
// Breathing effect for radius
|
|
3043
|
+
const radius = (Math.sin(t) * 0.15 + 0.6) * maxRadius;
|
|
3044
|
+
// Breathing effect for opacity
|
|
3045
|
+
const alpha = (Math.sin(t + Math.PI / 2) * 0.3 + 0.5) * factor; // Higher base alpha (0.2->0.8 range)
|
|
3046
|
+
// Clamp alpha max to 1
|
|
3047
|
+
const safeAlpha = Math.min(Math.max(alpha, 0), 1);
|
|
3048
|
+
if (safeAlpha <= 0.01)
|
|
3049
|
+
return;
|
|
3028
3050
|
const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
|
|
3029
3051
|
const rgb = hexToRgb$1(color);
|
|
3052
|
+
// Harder center, softer edge
|
|
3030
3053
|
gradient.addColorStop(0, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
|
|
3031
|
-
gradient.addColorStop(0.
|
|
3054
|
+
gradient.addColorStop(0.2, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${safeAlpha * 0.2})`);
|
|
3055
|
+
gradient.addColorStop(0.6, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${safeAlpha * 0.6})`);
|
|
3032
3056
|
gradient.addColorStop(1, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
|
|
3033
3057
|
ctx.fillStyle = gradient;
|
|
3058
|
+
// Use globalCompositeOperation to blend nicely
|
|
3059
|
+
ctx.globalCompositeOperation = 'screen';
|
|
3034
3060
|
ctx.fillRect(0, 0, width, height);
|
|
3061
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
3035
3062
|
});
|
|
3036
3063
|
};
|
|
3037
3064
|
|
|
@@ -3323,63 +3350,132 @@
|
|
|
3323
3350
|
}, 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 }))] }));
|
|
3324
3351
|
};
|
|
3325
3352
|
|
|
3326
|
-
const AnimationText = ({ children, type = 'fade', speed = 1000, repeat =
|
|
3353
|
+
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, }) => {
|
|
3327
3354
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
3328
|
-
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
3329
3355
|
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
3356
|
+
// Initialize with full text unless it's a mount trigger for typing/decode
|
|
3357
|
+
const [displayText, setDisplayText] = React.useState((type === 'decode' || type === 'typing') && trigger === 'mount' ? '' : children);
|
|
3358
|
+
const [currentRepeat, setCurrentRepeat] = React.useState(0);
|
|
3330
3359
|
const textRef = React.useRef(null);
|
|
3331
|
-
React.useRef(null);
|
|
3332
|
-
//
|
|
3333
|
-
const [displayText, setDisplayText] = React.useState('');
|
|
3360
|
+
const observerRef = React.useRef(null);
|
|
3361
|
+
// Initial trigger logic
|
|
3334
3362
|
React.useEffect(() => {
|
|
3335
|
-
if (
|
|
3363
|
+
if (trigger === 'mount') {
|
|
3336
3364
|
const timer = setTimeout(() => {
|
|
3337
3365
|
setIsVisible(true);
|
|
3366
|
+
startAnimation();
|
|
3338
3367
|
}, delay);
|
|
3339
3368
|
return () => clearTimeout(timer);
|
|
3340
3369
|
}
|
|
3341
|
-
else {
|
|
3342
|
-
|
|
3370
|
+
else if (trigger === 'in-view' && textRef.current) {
|
|
3371
|
+
observerRef.current = new IntersectionObserver((entries) => {
|
|
3372
|
+
if (entries[0].isIntersecting) {
|
|
3373
|
+
setTimeout(() => {
|
|
3374
|
+
setIsVisible(true);
|
|
3375
|
+
startAnimation();
|
|
3376
|
+
}, delay);
|
|
3377
|
+
observerRef.current?.disconnect();
|
|
3378
|
+
}
|
|
3379
|
+
});
|
|
3380
|
+
observerRef.current.observe(textRef.current);
|
|
3381
|
+
return () => observerRef.current?.disconnect();
|
|
3343
3382
|
}
|
|
3344
|
-
}, [delay]);
|
|
3345
|
-
//
|
|
3383
|
+
}, [trigger, delay]);
|
|
3384
|
+
// Update initial text visibility when props change
|
|
3346
3385
|
React.useEffect(() => {
|
|
3347
|
-
if (type === 'typing' &&
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
clearInterval(typeInterval);
|
|
3354
|
-
return prev;
|
|
3355
|
-
}
|
|
3356
|
-
setDisplayText(children.slice(0, prev + 1));
|
|
3357
|
-
return prev + 1;
|
|
3358
|
-
});
|
|
3359
|
-
}, speed / children.length);
|
|
3360
|
-
return () => clearInterval(typeInterval);
|
|
3386
|
+
if ((type === 'typing' || type === 'decode') && trigger === 'mount') ;
|
|
3387
|
+
else {
|
|
3388
|
+
// For hover/click, ensure text is visible when not animating
|
|
3389
|
+
if (!isAnimating) {
|
|
3390
|
+
setDisplayText(children);
|
|
3391
|
+
}
|
|
3361
3392
|
}
|
|
3362
|
-
}, [
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3393
|
+
}, [children, type, trigger]);
|
|
3394
|
+
const startAnimation = () => {
|
|
3395
|
+
setIsAnimating(true);
|
|
3396
|
+
setCurrentRepeat(0);
|
|
3397
|
+
if (type === 'typing') {
|
|
3398
|
+
startTyping(0);
|
|
3399
|
+
}
|
|
3400
|
+
else if (type === 'decode') {
|
|
3401
|
+
startDecoding(0);
|
|
3402
|
+
}
|
|
3403
|
+
};
|
|
3404
|
+
const startTyping = (iteration) => {
|
|
3405
|
+
setDisplayText('');
|
|
3406
|
+
let currentIndex = 0;
|
|
3407
|
+
const interval = setInterval(() => {
|
|
3408
|
+
if (currentIndex >= children.length) {
|
|
3409
|
+
clearInterval(interval);
|
|
3410
|
+
// Repetition logic
|
|
3411
|
+
if (repeat === 0 || iteration < repeat - 1) {
|
|
3412
|
+
setTimeout(() => {
|
|
3413
|
+
startTyping(iteration + 1);
|
|
3414
|
+
}, 500);
|
|
3415
|
+
}
|
|
3416
|
+
else {
|
|
3370
3417
|
setIsAnimating(false);
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
setTimeout(repeatAnimation, speed);
|
|
3374
|
-
}
|
|
3375
|
-
}, speed);
|
|
3376
|
-
};
|
|
3377
|
-
if (isVisible) {
|
|
3378
|
-
setTimeout(repeatAnimation, speed);
|
|
3418
|
+
}
|
|
3419
|
+
return;
|
|
3379
3420
|
}
|
|
3421
|
+
setDisplayText(children.slice(0, currentIndex + 1));
|
|
3422
|
+
currentIndex++;
|
|
3423
|
+
}, speed / children.length);
|
|
3424
|
+
};
|
|
3425
|
+
const startDecoding = (iteration) => {
|
|
3426
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+';
|
|
3427
|
+
let iterations = 0;
|
|
3428
|
+
const interval = setInterval(() => {
|
|
3429
|
+
setDisplayText(children.split('').map((char, index) => {
|
|
3430
|
+
if (index < iterations) {
|
|
3431
|
+
return children[index];
|
|
3432
|
+
}
|
|
3433
|
+
return characters[Math.floor(Math.random() * characters.length)];
|
|
3434
|
+
}).join(''));
|
|
3435
|
+
if (iterations >= children.length) {
|
|
3436
|
+
clearInterval(interval);
|
|
3437
|
+
setDisplayText(children);
|
|
3438
|
+
// Repetition logic
|
|
3439
|
+
if (repeat === 0 || iteration < repeat - 1) {
|
|
3440
|
+
setTimeout(() => {
|
|
3441
|
+
startDecoding(iteration + 1);
|
|
3442
|
+
}, 500);
|
|
3443
|
+
}
|
|
3444
|
+
else {
|
|
3445
|
+
setIsAnimating(false);
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
iterations += 1 / 3;
|
|
3449
|
+
}, 30);
|
|
3450
|
+
};
|
|
3451
|
+
const handleMouseEnter = () => {
|
|
3452
|
+
if (trigger === 'hover') {
|
|
3453
|
+
setIsVisible(true);
|
|
3454
|
+
startAnimation();
|
|
3380
3455
|
}
|
|
3381
|
-
}
|
|
3456
|
+
};
|
|
3457
|
+
const handleMouseLeave = () => {
|
|
3458
|
+
if (trigger === 'hover') {
|
|
3459
|
+
setIsVisible(false);
|
|
3460
|
+
setIsAnimating(false);
|
|
3461
|
+
if (type === 'typing' || type === 'decode') {
|
|
3462
|
+
setDisplayText(children);
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
};
|
|
3382
3466
|
const handleClick = () => {
|
|
3467
|
+
if (trigger === 'click') {
|
|
3468
|
+
setIsVisible(!isVisible);
|
|
3469
|
+
if (isVisible) {
|
|
3470
|
+
setIsAnimating(false);
|
|
3471
|
+
if (type === 'typing' || type === 'decode') {
|
|
3472
|
+
setDisplayText(children);
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
else {
|
|
3476
|
+
startAnimation();
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3383
3479
|
if (clickable && !disabled && onClick) {
|
|
3384
3480
|
onClick();
|
|
3385
3481
|
}
|
|
@@ -3396,14 +3492,6 @@
|
|
|
3396
3492
|
}
|
|
3397
3493
|
return {};
|
|
3398
3494
|
};
|
|
3399
|
-
const getWaveStyle = () => {
|
|
3400
|
-
if (type === 'wave') {
|
|
3401
|
-
return {
|
|
3402
|
-
'--wave-colors': waveColors.join(', '),
|
|
3403
|
-
};
|
|
3404
|
-
}
|
|
3405
|
-
return {};
|
|
3406
|
-
};
|
|
3407
3495
|
const getGlowStyle = () => {
|
|
3408
3496
|
if (type === 'glow') {
|
|
3409
3497
|
return {
|
|
@@ -3412,26 +3500,52 @@
|
|
|
3412
3500
|
}
|
|
3413
3501
|
return {};
|
|
3414
3502
|
};
|
|
3415
|
-
|
|
3503
|
+
// For typing, the class should be applied to the inner element to handle caret correctly with ghost element
|
|
3504
|
+
const containerClasses = classNames('designbase-animation-text',
|
|
3505
|
+
// Exclude typing logic from outer container to prevent caret on full-width ghost container
|
|
3506
|
+
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}`, {
|
|
3416
3507
|
'designbase-animation-text--visible': isVisible,
|
|
3417
3508
|
'designbase-animation-text--animating': isAnimating,
|
|
3418
|
-
'designbase-animation-text--clickable': clickable,
|
|
3509
|
+
'designbase-animation-text--clickable': clickable || trigger === 'click',
|
|
3419
3510
|
'designbase-animation-text--disabled': disabled,
|
|
3420
3511
|
}, className);
|
|
3421
3512
|
const style = {
|
|
3422
3513
|
...getGradientStyle(),
|
|
3423
|
-
...getWaveStyle(),
|
|
3424
3514
|
...getGlowStyle(),
|
|
3425
3515
|
'--db-animation-speed': `${speed}ms`,
|
|
3426
3516
|
'--db-text-custom': customColor,
|
|
3517
|
+
'--db-wave-colors': waveColors.join(', '),
|
|
3518
|
+
'--db-animation-iteration-count': repeat === 0 ? 'infinite' : repeat,
|
|
3427
3519
|
};
|
|
3428
|
-
const
|
|
3429
|
-
if (type === '
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3520
|
+
const renderContent = () => {
|
|
3521
|
+
if (type === 'wave' || type === 'shake') {
|
|
3522
|
+
if (!isVisible && !isAnimating)
|
|
3523
|
+
return children;
|
|
3524
|
+
return children.split('').map((char, index) => (jsxRuntime.jsx("span", { style: {
|
|
3525
|
+
animationDelay: `${index * 0.05}s`,
|
|
3526
|
+
display: 'inline-block'
|
|
3527
|
+
}, children: char === ' ' ? '\u00A0' : char }, index)));
|
|
3528
|
+
}
|
|
3529
|
+
return displayText;
|
|
3530
|
+
};
|
|
3531
|
+
return (jsxRuntime.jsxs("div", { ref: textRef, className: containerClasses, style: style, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [jsxRuntime.jsx("span", { "aria-hidden": "true", style: {
|
|
3532
|
+
visibility: 'hidden',
|
|
3533
|
+
pointerEvents: 'none',
|
|
3534
|
+
userSelect: 'none',
|
|
3535
|
+
whiteSpace: type === 'typing' ? 'pre-wrap' : undefined
|
|
3536
|
+
}, children: children }), jsxRuntime.jsx("span", { className: classNames({
|
|
3537
|
+
'designbase-animation-text--typing': type === 'typing',
|
|
3538
|
+
'designbase-animation-text--animating': isAnimating && type === 'typing' // Ensure animating class is passed for typing caret
|
|
3539
|
+
}), style: {
|
|
3540
|
+
position: 'absolute',
|
|
3541
|
+
top: 0,
|
|
3542
|
+
left: 0,
|
|
3543
|
+
// For typing, we want width to be auto so caret follows text
|
|
3544
|
+
// For others, width 100% matches ghost element
|
|
3545
|
+
width: type === 'typing' ? 'auto' : '100%',
|
|
3546
|
+
height: '100%',
|
|
3547
|
+
whiteSpace: type === 'typing' ? 'pre-wrap' : undefined // Ensure pre-wrap behavior matches
|
|
3548
|
+
}, children: renderContent() })] }));
|
|
3435
3549
|
};
|
|
3436
3550
|
|
|
3437
3551
|
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, }) => {
|
|
@@ -4193,6 +4307,7 @@
|
|
|
4193
4307
|
|
|
4194
4308
|
const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true, closeOnEscape = true, children, className, overlayClassName, }) => {
|
|
4195
4309
|
const modalRef = React.useRef(null);
|
|
4310
|
+
const titleId = React.useId();
|
|
4196
4311
|
// 아이콘 크기 계산 (m이 기본값)
|
|
4197
4312
|
const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
|
|
4198
4313
|
// Prevent scrolling while modal is open
|
|
@@ -4224,11 +4339,12 @@
|
|
|
4224
4339
|
return null;
|
|
4225
4340
|
const modalClasses = clsx('designbase-modal', `designbase-modal--${size}`, className);
|
|
4226
4341
|
const overlayClasses = clsx('designbase-modal__overlay', overlayClassName);
|
|
4227
|
-
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 ?
|
|
4342
|
+
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 })] }) }));
|
|
4228
4343
|
};
|
|
4229
|
-
const ModalHeader = ({ title, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
|
|
4344
|
+
const ModalHeader = ({ title, titleId, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
|
|
4345
|
+
const fallbackTitleId = React.useId();
|
|
4230
4346
|
const classes = clsx('designbase-modal__header', className);
|
|
4231
|
-
return (jsxRuntime.jsxs("div", { className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntime.jsx("h2", { id:
|
|
4347
|
+
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" }) }))] }));
|
|
4232
4348
|
};
|
|
4233
4349
|
const ModalBody = ({ className, children, }) => {
|
|
4234
4350
|
const classes = clsx('designbase-modal__body', className);
|
|
@@ -4491,6 +4607,11 @@
|
|
|
4491
4607
|
const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? (multiple ? [] : ''));
|
|
4492
4608
|
const [searchTerm, setSearchTerm] = React.useState('');
|
|
4493
4609
|
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
|
4610
|
+
const selectId = React.useId();
|
|
4611
|
+
const labelId = `${selectId}-label`;
|
|
4612
|
+
const listboxId = `${selectId}-listbox`;
|
|
4613
|
+
const helperTextId = `${selectId}-helper-text`;
|
|
4614
|
+
const errorTextId = `${selectId}-error-text`;
|
|
4494
4615
|
const containerRef = React.useRef(null);
|
|
4495
4616
|
const inputRef = React.useRef(null);
|
|
4496
4617
|
const dropdownRef = React.useRef(null);
|
|
@@ -4650,23 +4771,29 @@
|
|
|
4650
4771
|
const filteredOptions = getFilteredOptions();
|
|
4651
4772
|
const selectedLabels = getSelectedLabels();
|
|
4652
4773
|
const hasValue = multiple ? selectedValue.length > 0 : selectedValue !== '';
|
|
4653
|
-
|
|
4774
|
+
const activeDescendantId = focusedIndex >= 0 ? `${selectId}-option-${focusedIndex}` : undefined;
|
|
4775
|
+
const describedBy = error && errorMessage
|
|
4776
|
+
? errorTextId
|
|
4777
|
+
: helperText
|
|
4778
|
+
? helperTextId
|
|
4779
|
+
: undefined;
|
|
4780
|
+
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) => {
|
|
4654
4781
|
const option = options.find(opt => opt.value === value);
|
|
4655
4782
|
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) => {
|
|
4656
4783
|
e.stopPropagation();
|
|
4657
4784
|
handleRemoveValue(value);
|
|
4658
4785
|
}, children: jsxRuntime.jsx(icons.CloseIcon, { size: 12 }) })] }, value));
|
|
4659
|
-
}) })) : (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) => {
|
|
4786
|
+
}) })) : (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) => {
|
|
4660
4787
|
const isSelected = multiple
|
|
4661
4788
|
? selectedValue.includes(option.value)
|
|
4662
4789
|
: selectedValue === option.value;
|
|
4663
4790
|
const isFocused = index === focusedIndex;
|
|
4664
|
-
return (jsxRuntime.jsxs("div", { className: clsx('designbase-select__option', {
|
|
4791
|
+
return (jsxRuntime.jsxs("div", { id: `${selectId}-option-${index}`, className: clsx('designbase-select__option', {
|
|
4665
4792
|
'designbase-select__option--selected': isSelected,
|
|
4666
4793
|
'designbase-select__option--focused': isFocused,
|
|
4667
4794
|
'designbase-select__option--disabled': option.disabled,
|
|
4668
4795
|
}), 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));
|
|
4669
|
-
})) })] }), helperText && !error && (jsxRuntime.jsx("p", { className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsxRuntime.jsx("p", { className: "designbase-select__error-message", children: errorMessage }))] }));
|
|
4796
|
+
})) })] }), 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 }))] }));
|
|
4670
4797
|
};
|
|
4671
4798
|
Select.displayName = 'Select';
|
|
4672
4799
|
|
|
@@ -5270,7 +5397,7 @@
|
|
|
5270
5397
|
return null;
|
|
5271
5398
|
return (jsxRuntime.jsx("div", { className: "designbase-card__actions", children: actions.map((action, index) => {
|
|
5272
5399
|
const ActionIcon = action.icon;
|
|
5273
|
-
return (jsxRuntime.jsx(Button, { variant: action.variant || 'primary', size: action.size || 's', onClick: () => handleActionClick(action, index), disabled: action.disabled || disabled, loading: !!action.loading,
|
|
5400
|
+
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));
|
|
5274
5401
|
}) }));
|
|
5275
5402
|
};
|
|
5276
5403
|
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()] }));
|
|
@@ -10898,7 +11025,7 @@
|
|
|
10898
11025
|
}
|
|
10899
11026
|
};
|
|
10900
11027
|
|
|
10901
|
-
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 }) => {
|
|
11028
|
+
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 }) => {
|
|
10902
11029
|
const [expandedItems, setExpandedItems] = React.useState([]);
|
|
10903
11030
|
const handleToggle = () => {
|
|
10904
11031
|
if (onToggle) {
|
|
@@ -10939,24 +11066,24 @@
|
|
|
10939
11066
|
const hasChildren = item.children && item.children.length > 0;
|
|
10940
11067
|
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));
|
|
10941
11068
|
};
|
|
10942
|
-
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) => {
|
|
11069
|
+
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) => {
|
|
10943
11070
|
if (onLogoClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
10944
11071
|
e.preventDefault();
|
|
10945
11072
|
onLogoClick();
|
|
10946
11073
|
}
|
|
10947
11074
|
}, 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', {
|
|
10948
11075
|
'designbase-sidebar__toggle-icon--collapsed': collapsed,
|
|
10949
|
-
}) }) }))] }), 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) => {
|
|
11076
|
+
}) }) }))] })), 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) => {
|
|
10950
11077
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10951
11078
|
e.preventDefault();
|
|
10952
11079
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10953
11080
|
}
|
|
10954
|
-
}, style: { cursor: 'pointer' }, children: [
|
|
11081
|
+
}, 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) => {
|
|
10955
11082
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10956
11083
|
e.preventDefault();
|
|
10957
11084
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10958
11085
|
}
|
|
10959
|
-
}, style: { cursor: 'pointer' }, children:
|
|
11086
|
+
}, style: { cursor: 'pointer' }, children: jsxRuntime.jsx(Avatar, { src: userProfile.avatar, initials: userProfile.name, alt: userProfile.name, size: "s", className: "designbase-sidebar__user-avatar-collapsed" }) }))] }) }));
|
|
10960
11087
|
};
|
|
10961
11088
|
Sidebar.displayName = 'Sidebar';
|
|
10962
11089
|
|
|
@@ -12391,25 +12518,18 @@
|
|
|
12391
12518
|
};
|
|
12392
12519
|
YouTubePlayer.displayName = 'YouTubePlayer';
|
|
12393
12520
|
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12402
|
-
|
|
12403
|
-
|
|
12404
|
-
|
|
12405
|
-
};
|
|
12406
|
-
const getTheme = () => {
|
|
12407
|
-
return 'light';
|
|
12408
|
-
};
|
|
12409
|
-
const toggleTheme = () => {
|
|
12410
|
-
console.log('toggleTheme called');
|
|
12411
|
-
};
|
|
12412
|
-
|
|
12521
|
+
Object.defineProperty(exports, 'getTheme', {
|
|
12522
|
+
enumerable: true,
|
|
12523
|
+
get: function () { return theme.getTheme; }
|
|
12524
|
+
});
|
|
12525
|
+
Object.defineProperty(exports, 'setTheme', {
|
|
12526
|
+
enumerable: true,
|
|
12527
|
+
get: function () { return theme.setTheme; }
|
|
12528
|
+
});
|
|
12529
|
+
Object.defineProperty(exports, 'toggleTheme', {
|
|
12530
|
+
enumerable: true,
|
|
12531
|
+
get: function () { return theme.toggleTheme; }
|
|
12532
|
+
});
|
|
12413
12533
|
exports.Accordion = Accordion;
|
|
12414
12534
|
exports.AdBanner = AdBanner;
|
|
12415
12535
|
exports.Alert = Alert;
|
|
@@ -12502,9 +12622,6 @@
|
|
|
12502
12622
|
exports.Tutorial = Tutorial;
|
|
12503
12623
|
exports.VideoPlayer = VideoPlayer;
|
|
12504
12624
|
exports.YouTubePlayer = YouTubePlayer;
|
|
12505
|
-
exports.getTheme = getTheme;
|
|
12506
|
-
exports.setTheme = setTheme;
|
|
12507
|
-
exports.toggleTheme = toggleTheme;
|
|
12508
12625
|
exports.useToast = useToast;
|
|
12509
12626
|
|
|
12510
12627
|
}));
|