@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/README.md +68 -28
- 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 +202 -104
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +213 -106
- 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 +216 -110
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import React, { useState, useCallback, useEffect, useRef, useMemo, useContext, useLayoutEffect, forwardRef, useId, createContext } from 'react';
|
|
3
3
|
import { ChevronDownIcon, StarIcon, TrendingUpIcon, StarFilledIcon, CartIcon, CloseIcon, ArrowRightIcon, InfoFilledIcon, ErrorFilledIcon, WarningFilledIcon, CircleCheckFilledIcon, RefreshIcon, ChevronLeftIcon, PauseIcon, PlayIcon, ChevronRightIcon, RepeatIcon, MuteFilledIcon, VolumeUpIcon, SettingsIcon, UserIcon, HideIcon, ShowIcon, SearchIcon, ChevronUpIcon, GalleryIcon, HeartIcon, BookmarkIcon, ShareAltIcon, DownloadIcon, ArrowLeftIcon, ShrinkIcon, ExpandIcon, DoneIcon as DoneIcon$1, CopyIcon, EyedropperIcon, BulbIcon, CloudCloseIcon, BellActiveIcon, AwardIcon, CalendarIcon, PlusIcon, ErrorIcon, FileBlankIcon, ClockIcon, MinusIcon as MinusIcon$1, VideoIcon, CodeIcon, WriteIcon, UploadIcon, ArrowBarLeftIcon, ArrowBarRightIcon, StarHalfIcon, MoveIcon, MoreVerticalIcon, ArrowDownIcon, ArrowUpLeftIcon, ArrowUpRightIcon, ArrowDownLeftIcon, ArrowDownRightIcon, FacebookIcon, XIcon, InstagramIcon, LinkedinIcon, PinterestIcon, WhatsappIcon, TelegramIcon, MailIcon, LinkIcon, ScanQrcodeIcon, CaretUpdownFilledIcon, WarningIcon, InfoIcon } from '@designbasekorea/icons';
|
|
4
4
|
import { flushSync, createPortal } from 'react-dom';
|
|
5
|
+
export { getTheme, setTheme, toggleTheme } from '@designbasekorea/theme';
|
|
5
6
|
|
|
6
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}
|
|
7
8
|
|
|
@@ -2993,44 +2994,71 @@ const drawStars = (ctx, width, height, starsRef, options) => {
|
|
|
2993
2994
|
};
|
|
2994
2995
|
const drawWaves = (ctx, width, height, options) => {
|
|
2995
2996
|
const { colors, offset, speedFactor } = options;
|
|
2996
|
-
offset.current += 0.
|
|
2997
|
+
offset.current += 0.005 * speedFactor; // Slower, smoother movement
|
|
2997
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;
|
|
2998
3006
|
ctx.beginPath();
|
|
2999
3007
|
ctx.moveTo(0, height);
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
const
|
|
3005
|
-
|
|
3006
|
-
|
|
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
|
|
3007
3017
|
ctx.lineTo(x, y);
|
|
3008
3018
|
}
|
|
3009
3019
|
ctx.lineTo(width, height);
|
|
3010
3020
|
ctx.lineTo(0, height);
|
|
3011
3021
|
ctx.closePath();
|
|
3012
|
-
|
|
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
|
|
3013
3027
|
ctx.fill();
|
|
3028
|
+
ctx.globalAlpha = 1.0;
|
|
3029
|
+
// ctx.filter = 'none';
|
|
3014
3030
|
});
|
|
3015
3031
|
};
|
|
3016
3032
|
const drawPulse = (ctx, width, height, options) => {
|
|
3017
3033
|
const { colors, time, intensity } = options;
|
|
3018
3034
|
const centerX = width / 2;
|
|
3019
3035
|
const centerY = height / 2;
|
|
3020
|
-
const maxRadius = Math.max(width, height) * 0.
|
|
3021
|
-
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
|
|
3022
3038
|
const factor = intensityMap[intensity];
|
|
3023
3039
|
colors.forEach((color, i) => {
|
|
3024
|
-
|
|
3025
|
-
const
|
|
3026
|
-
|
|
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;
|
|
3027
3050
|
const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);
|
|
3028
3051
|
const rgb = hexToRgb$1(color);
|
|
3052
|
+
// Harder center, softer edge
|
|
3029
3053
|
gradient.addColorStop(0, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
|
|
3030
|
-
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})`);
|
|
3031
3056
|
gradient.addColorStop(1, `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0)`);
|
|
3032
3057
|
ctx.fillStyle = gradient;
|
|
3058
|
+
// Use globalCompositeOperation to blend nicely
|
|
3059
|
+
ctx.globalCompositeOperation = 'screen';
|
|
3033
3060
|
ctx.fillRect(0, 0, width, height);
|
|
3061
|
+
ctx.globalCompositeOperation = 'source-over';
|
|
3034
3062
|
});
|
|
3035
3063
|
};
|
|
3036
3064
|
|
|
@@ -3322,63 +3350,132 @@ const AnimationBackground = ({ type = 'gradient', theme = 'dark', intensity = 's
|
|
|
3322
3350
|
}, children: content }), showGrid && (jsx(GridOverlay, { size: gridSize, color: effectiveGridColor, opacity: gridOpacity })), children && (jsx("div", { className: "designbase-animation-background__content", style: { position: 'relative', zIndex: 10, width: '100%', height: '100%' }, children: children }))] }));
|
|
3323
3351
|
};
|
|
3324
3352
|
|
|
3325
|
-
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, }) => {
|
|
3326
3354
|
const [isVisible, setIsVisible] = useState(false);
|
|
3327
|
-
const [currentIndex, setCurrentIndex] = useState(0);
|
|
3328
3355
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
3356
|
+
// Initialize with full text unless it's a mount trigger for typing/decode
|
|
3357
|
+
const [displayText, setDisplayText] = useState((type === 'decode' || type === 'typing') && trigger === 'mount' ? '' : children);
|
|
3358
|
+
const [currentRepeat, setCurrentRepeat] = useState(0);
|
|
3329
3359
|
const textRef = useRef(null);
|
|
3330
|
-
useRef(null);
|
|
3331
|
-
//
|
|
3332
|
-
const [displayText, setDisplayText] = useState('');
|
|
3360
|
+
const observerRef = useRef(null);
|
|
3361
|
+
// Initial trigger logic
|
|
3333
3362
|
useEffect(() => {
|
|
3334
|
-
if (
|
|
3363
|
+
if (trigger === 'mount') {
|
|
3335
3364
|
const timer = setTimeout(() => {
|
|
3336
3365
|
setIsVisible(true);
|
|
3366
|
+
startAnimation();
|
|
3337
3367
|
}, delay);
|
|
3338
3368
|
return () => clearTimeout(timer);
|
|
3339
3369
|
}
|
|
3340
|
-
else {
|
|
3341
|
-
|
|
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();
|
|
3342
3382
|
}
|
|
3343
|
-
}, [delay]);
|
|
3344
|
-
//
|
|
3383
|
+
}, [trigger, delay]);
|
|
3384
|
+
// Update initial text visibility when props change
|
|
3345
3385
|
useEffect(() => {
|
|
3346
|
-
if (type === 'typing' &&
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
clearInterval(typeInterval);
|
|
3353
|
-
return prev;
|
|
3354
|
-
}
|
|
3355
|
-
setDisplayText(children.slice(0, prev + 1));
|
|
3356
|
-
return prev + 1;
|
|
3357
|
-
});
|
|
3358
|
-
}, speed / children.length);
|
|
3359
|
-
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
|
+
}
|
|
3360
3392
|
}
|
|
3361
|
-
}, [
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
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 {
|
|
3369
3417
|
setIsAnimating(false);
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3418
|
+
}
|
|
3419
|
+
return;
|
|
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
|
+
}
|
|
3378
3447
|
}
|
|
3448
|
+
iterations += 1 / 3;
|
|
3449
|
+
}, 30);
|
|
3450
|
+
};
|
|
3451
|
+
const handleMouseEnter = () => {
|
|
3452
|
+
if (trigger === 'hover') {
|
|
3453
|
+
setIsVisible(true);
|
|
3454
|
+
startAnimation();
|
|
3379
3455
|
}
|
|
3380
|
-
}
|
|
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
|
+
};
|
|
3381
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
|
+
}
|
|
3382
3479
|
if (clickable && !disabled && onClick) {
|
|
3383
3480
|
onClick();
|
|
3384
3481
|
}
|
|
@@ -3395,14 +3492,6 @@ const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, dela
|
|
|
3395
3492
|
}
|
|
3396
3493
|
return {};
|
|
3397
3494
|
};
|
|
3398
|
-
const getWaveStyle = () => {
|
|
3399
|
-
if (type === 'wave') {
|
|
3400
|
-
return {
|
|
3401
|
-
'--wave-colors': waveColors.join(', '),
|
|
3402
|
-
};
|
|
3403
|
-
}
|
|
3404
|
-
return {};
|
|
3405
|
-
};
|
|
3406
3495
|
const getGlowStyle = () => {
|
|
3407
3496
|
if (type === 'glow') {
|
|
3408
3497
|
return {
|
|
@@ -3411,26 +3500,52 @@ const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, dela
|
|
|
3411
3500
|
}
|
|
3412
3501
|
return {};
|
|
3413
3502
|
};
|
|
3414
|
-
|
|
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}`, {
|
|
3415
3507
|
'designbase-animation-text--visible': isVisible,
|
|
3416
3508
|
'designbase-animation-text--animating': isAnimating,
|
|
3417
|
-
'designbase-animation-text--clickable': clickable,
|
|
3509
|
+
'designbase-animation-text--clickable': clickable || trigger === 'click',
|
|
3418
3510
|
'designbase-animation-text--disabled': disabled,
|
|
3419
3511
|
}, className);
|
|
3420
3512
|
const style = {
|
|
3421
3513
|
...getGradientStyle(),
|
|
3422
|
-
...getWaveStyle(),
|
|
3423
3514
|
...getGlowStyle(),
|
|
3424
3515
|
'--db-animation-speed': `${speed}ms`,
|
|
3425
3516
|
'--db-text-custom': customColor,
|
|
3517
|
+
'--db-wave-colors': waveColors.join(', '),
|
|
3518
|
+
'--db-animation-iteration-count': repeat === 0 ? 'infinite' : repeat,
|
|
3426
3519
|
};
|
|
3427
|
-
const
|
|
3428
|
-
if (type === '
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3520
|
+
const renderContent = () => {
|
|
3521
|
+
if (type === 'wave' || type === 'shake') {
|
|
3522
|
+
if (!isVisible && !isAnimating)
|
|
3523
|
+
return children;
|
|
3524
|
+
return children.split('').map((char, index) => (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 (jsxs("div", { ref: textRef, className: containerClasses, style: style, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [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 }), 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() })] }));
|
|
3434
3549
|
};
|
|
3435
3550
|
|
|
3436
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, }) => {
|
|
@@ -4192,6 +4307,7 @@ SegmentControl.displayName = 'SegmentControl';
|
|
|
4192
4307
|
|
|
4193
4308
|
const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true, closeOnEscape = true, children, className, overlayClassName, }) => {
|
|
4194
4309
|
const modalRef = useRef(null);
|
|
4310
|
+
const titleId = useId();
|
|
4195
4311
|
// 아이콘 크기 계산 (m이 기본값)
|
|
4196
4312
|
const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
|
|
4197
4313
|
// Prevent scrolling while modal is open
|
|
@@ -4223,11 +4339,11 @@ const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true,
|
|
|
4223
4339
|
return null;
|
|
4224
4340
|
const modalClasses = clsx('designbase-modal', `designbase-modal--${size}`, className);
|
|
4225
4341
|
const overlayClasses = clsx('designbase-modal__overlay', overlayClassName);
|
|
4226
|
-
return (jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ?
|
|
4342
|
+
return (jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? titleId : undefined, children: [title && (jsx(ModalHeader, { title: title, titleId: titleId, showCloseButton: true, onClose: onClose, iconSize: iconSize })), jsx("div", { className: "designbase-modal__content", children: children })] }) }));
|
|
4227
4343
|
};
|
|
4228
|
-
const ModalHeader = ({ title, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
|
|
4344
|
+
const ModalHeader = ({ title, titleId, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
|
|
4229
4345
|
const classes = clsx('designbase-modal__header', className);
|
|
4230
|
-
return (jsxs("div", { className: classes, children: [jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsx("h2", { id:
|
|
4346
|
+
return (jsxs("div", { className: classes, children: [jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsx("h2", { id: titleId || 'modal-title', className: "designbase-modal__title", children: title })), children] }), showCloseButton && onClose && (jsx("button", { type: "button", onClick: onClose, "aria-label": "\uBAA8\uB2EC \uB2EB\uAE30", className: "designbase-modal__close-button", children: jsx(CloseIcon, { size: iconSize, color: "currentColor" }) }))] }));
|
|
4231
4347
|
};
|
|
4232
4348
|
const ModalBody = ({ className, children, }) => {
|
|
4233
4349
|
const classes = clsx('designbase-modal__body', className);
|
|
@@ -4490,6 +4606,7 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
|
|
|
4490
4606
|
const [selectedValue, setSelectedValue] = useState(value ?? defaultValue ?? (multiple ? [] : ''));
|
|
4491
4607
|
const [searchTerm, setSearchTerm] = useState('');
|
|
4492
4608
|
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
4609
|
+
const labelId = useId();
|
|
4493
4610
|
const containerRef = useRef(null);
|
|
4494
4611
|
const inputRef = useRef(null);
|
|
4495
4612
|
const dropdownRef = useRef(null);
|
|
@@ -4649,7 +4766,7 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
|
|
|
4649
4766
|
const filteredOptions = getFilteredOptions();
|
|
4650
4767
|
const selectedLabels = getSelectedLabels();
|
|
4651
4768
|
const hasValue = multiple ? selectedValue.length > 0 : selectedValue !== '';
|
|
4652
|
-
return (jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxs("label", { className: "designbase-select__label", children: [label, required && jsx("span", { className: "designbase-select__required", children: "*" })] })), 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 ?
|
|
4769
|
+
return (jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxs("label", { id: labelId, className: "designbase-select__label", children: [label, required && jsx("span", { className: "designbase-select__required", children: "*" })] })), 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: [jsx("div", { className: "designbase-select__value", children: multiple ? (jsx("div", { className: "designbase-select__tags", ref: tagsContainerRef, children: selectedValue.map((value) => {
|
|
4653
4770
|
const option = options.find(opt => opt.value === value);
|
|
4654
4771
|
return (jsxs("span", { className: "designbase-select__tag", children: [jsx("span", { className: "designbase-select__tag-label", children: option?.label || value }), jsx("button", { type: "button", className: "designbase-select__tag-remove", onClick: (e) => {
|
|
4655
4772
|
e.stopPropagation();
|
|
@@ -5269,7 +5386,7 @@ const Card = forwardRef(function Card({ title, subtitle, description, children,
|
|
|
5269
5386
|
return null;
|
|
5270
5387
|
return (jsx("div", { className: "designbase-card__actions", children: actions.map((action, index) => {
|
|
5271
5388
|
const ActionIcon = action.icon;
|
|
5272
|
-
return (jsx(Button, { variant: action.variant || 'primary', size: action.size || 's', onClick: () => handleActionClick(action, index), disabled: action.disabled || disabled, loading: !!action.loading,
|
|
5389
|
+
return (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));
|
|
5273
5390
|
}) }));
|
|
5274
5391
|
};
|
|
5275
5392
|
const renderContent = () => (jsxs("div", { className: "designbase-card__content", children: [renderIcon(), (title || subtitle) && (jsxs("div", { className: "designbase-card__header", children: [title && jsx("h3", { className: "designbase-card__title", children: title }), subtitle && jsx("p", { className: "designbase-card__subtitle", children: subtitle })] })), description && jsx("p", { className: "designbase-card__description", children: description }), children && jsx("div", { className: "designbase-card__body", children: children }), renderTags(), renderMeta(), renderActions()] }));
|
|
@@ -10897,7 +11014,7 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
|
|
|
10897
11014
|
}
|
|
10898
11015
|
};
|
|
10899
11016
|
|
|
10900
|
-
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 }) => {
|
|
11017
|
+
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 }) => {
|
|
10901
11018
|
const [expandedItems, setExpandedItems] = useState([]);
|
|
10902
11019
|
const handleToggle = () => {
|
|
10903
11020
|
if (onToggle) {
|
|
@@ -10938,24 +11055,24 @@ const Sidebar = ({ size = 'm', variant = 'default', position = 'left', logo, onL
|
|
|
10938
11055
|
const hasChildren = item.children && item.children.length > 0;
|
|
10939
11056
|
return (jsx("li", { className: "designbase-sidebar__item", children: jsx(MenuItem, { ...item, type: "block", style: "accordion", depth: level, expanded: isExpanded, expandable: hasChildren, onClick: () => handleItemClick(item), onChildClick: (child) => handleItemClick(child) }) }, item.id));
|
|
10940
11057
|
};
|
|
10941
|
-
return (jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxs("div", { className: "designbase-sidebar__container", children: [jsxs("div", { className: "designbase-sidebar__header", children: [jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, onKeyDown: (e) => {
|
|
11058
|
+
return (jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxs("div", { className: "designbase-sidebar__container", children: [showLogo && (jsxs("div", { className: "designbase-sidebar__header", children: [jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, onKeyDown: (e) => {
|
|
10942
11059
|
if (onLogoClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
10943
11060
|
e.preventDefault();
|
|
10944
11061
|
onLogoClick();
|
|
10945
11062
|
}
|
|
10946
11063
|
}, children: logo || jsx(Logo, { size: "s" }) }), collapsible && (jsx(Button, { variant: "ghost", size: "s", iconOnly: true, className: "designbase-sidebar__toggle", onPress: handleToggle, "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: jsx(ChevronLeftIcon, { className: clsx('designbase-sidebar__toggle-icon', {
|
|
10947
11064
|
'designbase-sidebar__toggle-icon--collapsed': collapsed,
|
|
10948
|
-
}) }) }))] }), jsx("nav", { className: "designbase-sidebar__nav", children: jsx("ul", { className: "designbase-sidebar__nav-list", children: items.map((item) => renderSidebarItem(item)) }) }), userProfile && !collapsed && (jsxs("div", { className: "designbase-sidebar__user", children: [jsxs("div", { className: "designbase-sidebar__user-info", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
|
|
11065
|
+
}) }) }))] })), jsx("nav", { className: "designbase-sidebar__nav", children: jsx("ul", { className: "designbase-sidebar__nav-list", children: items.map((item) => renderSidebarItem(item)) }) }), userProfile && !collapsed && (jsxs("div", { className: "designbase-sidebar__user", children: [jsxs("div", { className: "designbase-sidebar__user-info", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
|
|
10949
11066
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10950
11067
|
e.preventDefault();
|
|
10951
11068
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10952
11069
|
}
|
|
10953
|
-
}, style: { cursor: 'pointer' }, children: [
|
|
11070
|
+
}, style: { cursor: 'pointer' }, children: [jsx(Avatar, { src: userProfile.avatar, initials: userProfile.name, alt: userProfile.name, size: "s", className: "designbase-sidebar__user-avatar" }), jsxs("div", { className: "designbase-sidebar__user-details", children: [jsx("div", { className: "designbase-sidebar__user-name", children: userProfile.name }), userProfile.email && (jsx("div", { className: "designbase-sidebar__user-email", children: userProfile.email })), userProfile.role && (jsx("div", { className: "designbase-sidebar__user-role", children: userProfile.role }))] })] }), userMenuItems.length > 0 && (jsx("ul", { className: "designbase-sidebar__user-menu", children: userMenuItems.map((item) => (jsx("li", { children: 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 && (jsx("div", { className: "designbase-sidebar__user-collapsed", onClick: () => onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' }), role: "button", tabIndex: 0, onKeyDown: (e) => {
|
|
10954
11071
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
10955
11072
|
e.preventDefault();
|
|
10956
11073
|
onUserMenuItemClick?.({ id: 'profile', label: '프로필', href: '#' });
|
|
10957
11074
|
}
|
|
10958
|
-
}, style: { cursor: 'pointer' }, children:
|
|
11075
|
+
}, style: { cursor: 'pointer' }, children: jsx(Avatar, { src: userProfile.avatar, initials: userProfile.name, alt: userProfile.name, size: "s", className: "designbase-sidebar__user-avatar-collapsed" }) }))] }) }));
|
|
10959
11076
|
};
|
|
10960
11077
|
Sidebar.displayName = 'Sidebar';
|
|
10961
11078
|
|
|
@@ -12390,24 +12507,5 @@ const YouTubePlayer = ({ videoId, title, description, size = 'm', variant = 'def
|
|
|
12390
12507
|
};
|
|
12391
12508
|
YouTubePlayer.displayName = 'YouTubePlayer';
|
|
12392
12509
|
|
|
12393
|
-
|
|
12394
|
-
* Designbase UI 컴포넌트 라이브러리 메인 엔트리 포인트
|
|
12395
|
-
*
|
|
12396
|
-
* 목적: 모든 UI 컴포넌트와 타입을 내보냄
|
|
12397
|
-
* 기능: Tree-shaking 가능한 개별 컴포넌트 내보내기
|
|
12398
|
-
* 사용법: import { Button, Input } from '@designbasekorea/ui'
|
|
12399
|
-
*/
|
|
12400
|
-
// 테마 CSS 자동 로드 (로컬 복사본 사용)
|
|
12401
|
-
// 테마 관련 유틸리티 재내보내기
|
|
12402
|
-
const setTheme = (theme) => {
|
|
12403
|
-
console.log('setTheme called with:', theme);
|
|
12404
|
-
};
|
|
12405
|
-
const getTheme = () => {
|
|
12406
|
-
return 'light';
|
|
12407
|
-
};
|
|
12408
|
-
const toggleTheme = () => {
|
|
12409
|
-
console.log('toggleTheme called');
|
|
12410
|
-
};
|
|
12411
|
-
|
|
12412
|
-
export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Testimonial, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, Tutorial, VideoPlayer, YouTubePlayer, getTheme, setTheme, toggleTheme, useToast };
|
|
12510
|
+
export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Testimonial, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, Tutorial, VideoPlayer, YouTubePlayer, useToast };
|
|
12413
12511
|
//# sourceMappingURL=index.esm.js.map
|