@designbasekorea/ui 0.2.33 → 0.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -2476,58 +2476,57 @@
2476
2476
  });
2477
2477
  Button.displayName = 'Button';
2478
2478
 
2479
- // 톤별 색상 팔레트
2479
+ // 톤별 색상 팔레트 (Light Tone은 더 밝은 색상만 사용)
2480
2480
  const colorPalettes = {
2481
2481
  primary: {
2482
- light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd', '#60a5fa'], // blue-50 ~ blue-400 (더 밝게)
2482
+ light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd'], // blue-50 ~ blue-300 (더 밝게, blue-400 제거)
2483
2483
  vivid: ['#3b82f6', '#2563eb', '#1d4ed8', '#1e40af', '#1e3a8a'], // blue-500 ~ blue-900
2484
2484
  dark: ['#0f172a', '#1e293b', '#334155', '#475569', '#64748b'], // slate-900 ~ slate-600 (더 어둡게)
2485
2485
  },
2486
2486
  secondary: {
2487
- light: ['#f8fafc', '#f1f5f9', '#e2e8f0', '#cbd5e1', '#94a3b8'], // slate-50 ~ slate-400 (더 밝게)
2487
+ light: ['#f8fafc', '#f1f5f9', '#e2e8f0', '#cbd5e1'], // slate-50 ~ slate-300 (더 밝게, slate-400 제거)
2488
2488
  vivid: ['#6b7280', '#4b5563', '#374151', '#1f2937', '#111827'], // gray-500 ~ gray-900
2489
2489
  dark: ['#0f0f0f', '#1a1a1a', '#262626', '#404040', '#525252'], // neutral-950 ~ neutral-600 (더 어둡게)
2490
2490
  },
2491
2491
  success: {
2492
- light: ['#f0fdf4', '#dcfce7', '#bbf7d0', '#86efac', '#4ade80'], // green-50 ~ green-400 (더 밝게)
2492
+ light: ['#f0fdf4', '#dcfce7', '#bbf7d0', '#86efac'], // green-50 ~ green-300 (더 밝게, green-400 제거)
2493
2493
  vivid: ['#22c55e', '#16a34a', '#15803d', '#166534', '#14532d'], // green-500 ~ green-900
2494
2494
  dark: ['#052e16', '#14532d', '#166534', '#15803d', '#16a34a'], // green-950 ~ green-600 (더 어둡게)
2495
2495
  },
2496
2496
  warning: {
2497
- light: ['#fffbeb', '#fef3c7', '#fde68a', '#fcd34d', '#fbbf24'], // amber-50 ~ amber-400 (더 밝게)
2497
+ light: ['#fffbeb', '#fef3c7', '#fde68a'], // amber-50 ~ amber-200 (더 밝게, amber-300 이상 제거)
2498
2498
  vivid: ['#f59e0b', '#d97706', '#b45309', '#92400e', '#78350f'], // amber-600 ~ amber-900
2499
2499
  dark: ['#451a03', '#78350f', '#92400e', '#b45309', '#d97706'], // amber-950 ~ amber-600 (더 어둡게)
2500
2500
  },
2501
2501
  error: {
2502
- light: ['#fef2f2', '#fecaca', '#fca5a5', '#f87171', '#f56565'], // red-50 ~ red-400 (더 밝게)
2502
+ light: ['#fef2f2', '#fecaca', '#fca5a5'], // red-50 ~ red-200 (더 밝게, red-300 이상 제거)
2503
2503
  vivid: ['#ef4444', '#dc2626', '#b91c1c', '#991b1b', '#7f1d1d'], // red-500 ~ red-900
2504
2504
  dark: ['#450a0a', '#7f1d1d', '#991b1b', '#b91c1c', '#dc2626'], // red-950 ~ red-600 (더 어둡게)
2505
2505
  },
2506
2506
  info: {
2507
- light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd', '#60a5fa'], // blue-50 ~ blue-400 (더 밝게)
2507
+ light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd'], // blue-50 ~ blue-300 (더 밝게, blue-400 제거)
2508
2508
  vivid: ['#3b82f6', '#2563eb', '#1d4ed8', '#1e40af', '#1e3a8a'], // blue-500 ~ blue-900
2509
2509
  dark: ['#0f172a', '#1e293b', '#334155', '#475569', '#64748b'], // slate-900 ~ slate-600 (더 어둡게)
2510
2510
  },
2511
2511
  purple: {
2512
- light: ['#faf5ff', '#f3e8ff', '#e9d5ff', '#d8b4fe', '#c084fc'], // purple-50 ~ purple-400 (더 밝게)
2512
+ light: ['#faf5ff', '#f3e8ff', '#e9d5ff', '#d8b4fe'], // purple-50 ~ purple-300 (더 밝게, purple-400 제거)
2513
2513
  vivid: ['#a855f7', '#9333ea', '#7c3aed', '#6d28d9', '#5b21b6'], // purple-600 ~ purple-900
2514
2514
  dark: ['#3b0764', '#581c87', '#6b21a8', '#7c3aed', '#9333ea'], // purple-950 ~ purple-600 (더 어둡게)
2515
2515
  },
2516
2516
  ocean: {
2517
- light: ['#f0fdfa', '#ccfbf1', '#99f6e4', '#5eead4', '#2dd4bf'], // teal-50 ~ teal-400 (더 밝게)
2517
+ light: ['#f0fdfa', '#ccfbf1', '#99f6e4'], // teal-50 ~ teal-200 (더 밝게, teal-300 이상 제거)
2518
2518
  vivid: ['#14b8a6', '#0d9488', '#0f766e', '#115e59', '#134e4a'], // teal-500 ~ teal-900
2519
2519
  dark: ['#042f2e', '#134e4a', '#115e59', '#0f766e', '#0d9488'], // teal-950 ~ teal-600 (더 어둡게)
2520
2520
  },
2521
2521
  sunset: {
2522
- light: ['#fff7ed', '#fed7aa', '#fdba74', '#fb923c', '#f97316'], // orange-50 ~ orange-500 (더 밝게)
2522
+ light: ['#fff7ed', '#fed7aa', '#fdba74'], // orange-50 ~ orange-200 (더 밝게, orange-300 이상 제거)
2523
2523
  vivid: ['#f97316', '#ea580c', '#c2410c', '#9a3412', '#7c2d12'], // orange-600 ~ orange-900
2524
2524
  dark: ['#431407', '#7c2d12', '#9a3412', '#c2410c', '#ea580c'], // orange-950 ~ orange-600 (더 어둡게)
2525
2525
  },
2526
2526
  };
2527
- const RandomGradient = ({ scheme = 'primary', tone = 'vivid', width = '100%', height = '600px', blur = 60, colorCount = 4, animated = false, animationDuration = 10, overlay = true, overlayOpacity = 0.2, children, className, }) => {
2528
- const [gradientStyle, setGradientStyle] = React.useState({});
2529
- // 블러 최소값 60으로 제한
2530
- const minBlur = Math.max(60, blur);
2527
+ const RandomGradient = ({ scheme = 'primary', tone = 'vivid', width = '100%', height = '600px', blur = 80, colorCount = 4, animated = false, animationDuration = 10, overlay = true, overlayOpacity = 0.2, children, className, }) => {
2528
+ // 블러 최소값 80으로 제한 (더 부드러운 그라데이션을 위해)
2529
+ const minBlur = Math.max(80, blur);
2531
2530
  // 그라데이션 생성 함수
2532
2531
  const generateGradient = React.useMemo(() => {
2533
2532
  return () => {
@@ -2545,13 +2544,54 @@
2545
2544
  return {
2546
2545
  background: `radial-gradient(circle at ${centerX}% ${centerY}%, ${gradientStops})`,
2547
2546
  filter: `blur(${minBlur}px)`,
2548
- transition: `all ${animationDuration}s ease-in-out`,
2547
+ transition: animated ? `background ${animationDuration}s ease-in-out` : 'none', // 블러는 transition 적용 안 함
2549
2548
  };
2550
2549
  };
2551
- }, [scheme, tone, colorCount, minBlur, animationDuration]);
2552
- // 초기 그라데이션 애니메이션
2550
+ }, [scheme, tone, colorCount, minBlur, animationDuration, animated]);
2551
+ // 초기 그라데이션 생성 함수
2552
+ const createInitialGradient = React.useCallback(() => {
2553
+ const schemeColors = colorPalettes[scheme][tone];
2554
+ const numColors = Math.min(6, Math.max(3, colorCount));
2555
+ const colors = [];
2556
+ for (let i = 0; i < numColors; i++) {
2557
+ const randomColor = schemeColors[Math.floor(Math.random() * schemeColors.length)];
2558
+ colors.push(randomColor);
2559
+ }
2560
+ const positions = Array.from({ length: numColors }, () => Math.random() * 100).sort((a, b) => a - b);
2561
+ const gradientStops = colors.map((color, i) => `${color} ${positions[i]}%`).join(', ');
2562
+ const centerX = Math.random() * 100;
2563
+ const centerY = Math.random() * 100;
2564
+ return {
2565
+ background: `radial-gradient(circle at ${centerX}% ${centerY}%, ${gradientStops})`,
2566
+ filter: `blur(${minBlur}px)`,
2567
+ transition: animated ? `background ${animationDuration}s ease-in-out` : 'none',
2568
+ };
2569
+ }, [scheme, tone, colorCount, minBlur, animated, animationDuration]);
2570
+ // 초기 그라데이션을 즉시 계산하여 설정 (useState 초기값 함수 사용)
2571
+ const [gradientStyle, setGradientStyle] = React.useState(() => {
2572
+ const schemeColors = colorPalettes[scheme][tone];
2573
+ const numColors = Math.min(6, Math.max(3, colorCount));
2574
+ const colors = [];
2575
+ for (let i = 0; i < numColors; i++) {
2576
+ const randomColor = schemeColors[Math.floor(Math.random() * schemeColors.length)];
2577
+ colors.push(randomColor);
2578
+ }
2579
+ const positions = Array.from({ length: numColors }, () => Math.random() * 100).sort((a, b) => a - b);
2580
+ const gradientStops = colors.map((color, i) => `${color} ${positions[i]}%`).join(', ');
2581
+ const centerX = Math.random() * 100;
2582
+ const centerY = Math.random() * 100;
2583
+ return {
2584
+ background: `radial-gradient(circle at ${centerX}% ${centerY}%, ${gradientStops})`,
2585
+ filter: `blur(${minBlur}px)`,
2586
+ transition: animated ? `background ${animationDuration}s ease-in-out` : 'none',
2587
+ };
2588
+ });
2589
+ // props 변경 시 그라데이션 업데이트
2590
+ React.useEffect(() => {
2591
+ setGradientStyle(createInitialGradient());
2592
+ }, [createInitialGradient]);
2593
+ // 애니메이션 업데이트
2553
2594
  React.useEffect(() => {
2554
- setGradientStyle(generateGradient());
2555
2595
  if (animated) {
2556
2596
  const interval = setInterval(() => {
2557
2597
  setGradientStyle(generateGradient());
@@ -3972,7 +4012,7 @@
3972
4012
  ModalBody.displayName = 'ModalBody';
3973
4013
  ModalFooter.displayName = 'ModalFooter';
3974
4014
 
3975
- const Label = ({ children, htmlFor, required = false, size = 'm', disabled = false, error = false, className, onClick, }) => {
4015
+ const Label = ({ children, htmlFor, required = false, size = 's', disabled = false, error = false, className, onClick, }) => {
3976
4016
  const classes = [
3977
4017
  'designbase-label',
3978
4018
  `designbase-label--${size}`,
@@ -4019,7 +4059,7 @@
4019
4059
  lg: 18,
4020
4060
  };
4021
4061
  const iconSize = iconSizeMap[size];
4022
- return (jsxRuntime.jsxs("div", { className: classes, children: [label && (jsxRuntime.jsx(Label, { htmlFor: inputId, required: required, error: error, disabled: disabled, size: size === 's' ? 'xs' : size === 'm' ? 's' : 'm', children: label })), jsxRuntime.jsxs("div", { className: "designbase-input__wrapper", children: [actualStartIcon && (jsxRuntime.jsx("div", { className: "designbase-input__start-icon", children: React.createElement(actualStartIcon, { size: iconSize }) })), jsxRuntime.jsx("input", { ...props, ref: forwardedRef, id: inputId, type: actualType, value: value, defaultValue: defaultValue, placeholder: placeholder, disabled: disabled, readOnly: readOnly, required: required, className: inputClasses, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, "aria-describedby": clsx(helperText && helperTextId, error && errorMessage && errorMessageId), "aria-invalid": error }), isPassword && (jsxRuntime.jsx("button", { type: "button", className: "designbase-input__password-toggle", onClick: handlePasswordToggle, disabled: disabled, "aria-label": showPassword ? '비밀번호 숨기기' : '비밀번호 보기', children: React.createElement(PasswordIcon, { size: iconSize }) })), EndIcon && !isPassword && (jsxRuntime.jsx("div", { className: "designbase-input__end-icon", children: React.createElement(EndIcon, { size: iconSize }) }))] }), helperText && !error && (jsxRuntime.jsx("p", { id: helperTextId, className: "designbase-input__helper-text", children: helperText })), error && errorMessage && (jsxRuntime.jsx("p", { id: errorMessageId, className: "designbase-input__error-message", children: errorMessage }))] }));
4062
+ return (jsxRuntime.jsxs("div", { className: classes, children: [label && (jsxRuntime.jsx(Label, { htmlFor: inputId, required: required, error: error, disabled: disabled, size: size === 's' ? 's' : size === 'm' ? 'm' : 'l', children: label })), jsxRuntime.jsxs("div", { className: "designbase-input__wrapper", children: [actualStartIcon && (jsxRuntime.jsx("div", { className: "designbase-input__start-icon", children: React.createElement(actualStartIcon, { size: iconSize }) })), jsxRuntime.jsx("input", { ...props, ref: forwardedRef, id: inputId, type: actualType, value: value, defaultValue: defaultValue, placeholder: placeholder, disabled: disabled, readOnly: readOnly, required: required, className: inputClasses, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, "aria-describedby": clsx(helperText && helperTextId, error && errorMessage && errorMessageId), "aria-invalid": error }), isPassword && (jsxRuntime.jsx("button", { type: "button", className: "designbase-input__password-toggle", onClick: handlePasswordToggle, disabled: disabled, "aria-label": showPassword ? '비밀번호 숨기기' : '비밀번호 보기', children: React.createElement(PasswordIcon, { size: iconSize }) })), EndIcon && !isPassword && (jsxRuntime.jsx("div", { className: "designbase-input__end-icon", children: React.createElement(EndIcon, { size: iconSize }) }))] }), helperText && !error && (jsxRuntime.jsx("p", { id: helperTextId, className: "designbase-input__helper-text", children: helperText })), error && errorMessage && (jsxRuntime.jsx("p", { id: errorMessageId, className: "designbase-input__error-message", children: errorMessage }))] }));
4023
4063
  });
4024
4064
  Input.displayName = 'Input';
4025
4065
 
@@ -6962,7 +7002,7 @@
6962
7002
  }, className);
6963
7003
  const textareaClasses = clsx('designbase-textarea__field', textareaClassName);
6964
7004
  const isOverLimit = maxLength && currentLength > maxLength;
6965
- return (jsxRuntime.jsxs("div", { className: classes, children: [label && (jsxRuntime.jsx(Label, { htmlFor: textareaId, required: required, error: error, disabled: disabled, size: size === 's' ? 'xs' : size === 'm' ? 's' : 'm', children: label })), showCharacterCount && characterCountPosition === 'top' && (jsxRuntime.jsx("div", { className: "designbase-textarea__character-count designbase-textarea__character-count--top", children: jsxRuntime.jsxs("span", { className: clsx('designbase-textarea__character-count-text', {
7005
+ return (jsxRuntime.jsxs("div", { className: classes, children: [label && (jsxRuntime.jsx(Label, { htmlFor: textareaId, required: required, error: error, disabled: disabled, size: size === 's' ? 's' : size === 'm' ? 'm' : 'l', children: label })), showCharacterCount && characterCountPosition === 'top' && (jsxRuntime.jsx("div", { className: "designbase-textarea__character-count designbase-textarea__character-count--top", children: jsxRuntime.jsxs("span", { className: clsx('designbase-textarea__character-count-text', {
6966
7006
  'designbase-textarea__character-count-text--error': isOverLimit
6967
7007
  }), children: [currentLength, maxLength && ` / ${maxLength}`] }) })), jsxRuntime.jsx("div", { className: "designbase-textarea__wrapper", children: jsxRuntime.jsx("textarea", { ref: forwardedRef, id: textareaId, className: textareaClasses, placeholder: placeholder, defaultValue: defaultValue, value: value, rows: rows, maxLength: maxLength, disabled: disabled, readOnly: readOnly, required: required, "aria-describedby": clsx({
6968
7008
  [helperTextId]: helperText,