@designbasekorea/ui 0.1.0 → 0.1.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 +477 -0
- package/dist/index.css +1 -391
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +86 -124
- package/dist/index.esm.css +1 -391
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +320 -273
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +318 -272
- package/dist/index.js.map +1 -1
- package/dist/index.umd.css +1 -391
- package/dist/index.umd.css.map +1 -1
- package/dist/index.umd.js +321 -274
- package/dist/index.umd.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var theme = require('@designbase/theme');
|
|
4
3
|
var React = require('react');
|
|
5
4
|
var $4AOtR$reactdom = require('react-dom');
|
|
6
|
-
var icons = require('@
|
|
5
|
+
var icons = require('@designbasekorea/icons');
|
|
7
6
|
|
|
8
7
|
function getDefaultExportFromCjs (x) {
|
|
9
8
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -3450,7 +3449,7 @@ function $701a24aa0da5b062$export$ea18c227d4417cc3(props, ref) {
|
|
|
3450
3449
|
};
|
|
3451
3450
|
}
|
|
3452
3451
|
|
|
3453
|
-
const Spinner = ({ type = 'circular', size = '
|
|
3452
|
+
const Spinner = ({ type = 'circular', size = 'm', color, speed = 1, label = '로딩 중...', showLabel = false, className, ...props }) => {
|
|
3454
3453
|
const classes = clsx('designbase-spinner', `designbase-spinner--${type}`, `designbase-spinner--${size}`, className);
|
|
3455
3454
|
const style = {
|
|
3456
3455
|
'--spinner-color': color,
|
|
@@ -3476,7 +3475,7 @@ const Spinner = ({ type = 'circular', size = 'md', color, speed = 1, label = '
|
|
|
3476
3475
|
};
|
|
3477
3476
|
Spinner.displayName = 'Spinner';
|
|
3478
3477
|
|
|
3479
|
-
const Button = React.forwardRef(({ variant = 'primary', size = '
|
|
3478
|
+
const Button = React.forwardRef(({ variant = 'primary', size = 'm', radius, fullWidth = false, disabled = false, loading = false, iconOnly = false, startIcon: StartIcon, endIcon: EndIcon, className, children, onPress, type = 'button', ...props }, forwardedRef) => {
|
|
3480
3479
|
const ref = $df56164dff5785e2$export$4338b53315abf666(forwardedRef);
|
|
3481
3480
|
const { buttonProps } = $701a24aa0da5b062$export$ea18c227d4417cc3({
|
|
3482
3481
|
...props,
|
|
@@ -3492,7 +3491,7 @@ const Button = React.forwardRef(({ variant = 'primary', size = 'md', radius, ful
|
|
|
3492
3491
|
if (iconOnly) {
|
|
3493
3492
|
return 'designbase-button--radius-pill';
|
|
3494
3493
|
}
|
|
3495
|
-
return `designbase-button--radius-${size === 'xs' || size === '
|
|
3494
|
+
return `designbase-button--radius-${size === 'xs' || size === 's' ? 's' : size === 'l' || size === 'xl' ? 'l' : 'm'}`;
|
|
3496
3495
|
};
|
|
3497
3496
|
const classes = clsx('designbase-button', `designbase-button--${variant}`, `designbase-button--${size}`, getRadiusClass(), {
|
|
3498
3497
|
'designbase-button--full-width': fullWidth,
|
|
@@ -3502,9 +3501,9 @@ const Button = React.forwardRef(({ variant = 'primary', size = 'md', radius, ful
|
|
|
3502
3501
|
const iconSize = (() => {
|
|
3503
3502
|
switch (size) {
|
|
3504
3503
|
case 'xs': return 12;
|
|
3505
|
-
case '
|
|
3506
|
-
case '
|
|
3507
|
-
case '
|
|
3504
|
+
case 's': return 14;
|
|
3505
|
+
case 'm': return 16;
|
|
3506
|
+
case 'l': return 18;
|
|
3508
3507
|
case 'xl': return 20;
|
|
3509
3508
|
default: return 16;
|
|
3510
3509
|
}
|
|
@@ -3528,21 +3527,25 @@ const Button = React.forwardRef(({ variant = 'primary', size = 'md', radius, ful
|
|
|
3528
3527
|
};
|
|
3529
3528
|
const renderContent = () => {
|
|
3530
3529
|
if (loading) {
|
|
3531
|
-
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Spinner, { type: "circular", size: size === 'xs' ? 'xs' : size === '
|
|
3530
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(Spinner, { type: "circular", size: size === 'xs' ? 'xs' : size === 's' ? 's' : 'm', color: getIconColor(), speed: 1, showLabel: false }), !iconOnly && jsxRuntimeExports.jsx("span", { children: "\uB85C\uB529 \uC911..." })] }));
|
|
3531
|
+
}
|
|
3532
|
+
// iconOnly 버튼일 때는 children을 아이콘으로 처리
|
|
3533
|
+
if (iconOnly && children) {
|
|
3534
|
+
return React.cloneElement(children, {
|
|
3535
|
+
size: iconSize,
|
|
3536
|
+
color: getIconColor(),
|
|
3537
|
+
style: {
|
|
3538
|
+
...children.props?.style
|
|
3539
|
+
}
|
|
3540
|
+
});
|
|
3532
3541
|
}
|
|
3533
|
-
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [StartIcon && (jsxRuntimeExports.jsx(StartIcon, { size: iconSize, className: "designbase-button__start-icon", color: getIconColor() })),
|
|
3534
|
-
size: iconSize,
|
|
3535
|
-
color: getIconColor(),
|
|
3536
|
-
style: {
|
|
3537
|
-
...children.props?.style
|
|
3538
|
-
}
|
|
3539
|
-
}), EndIcon && (jsxRuntimeExports.jsx(EndIcon, { size: iconSize, className: "designbase-button__end-icon", color: getIconColor() }))] }));
|
|
3542
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [StartIcon && (jsxRuntimeExports.jsx(StartIcon, { size: iconSize, className: "designbase-button__start-icon", color: getIconColor() })), children, EndIcon && (jsxRuntimeExports.jsx(EndIcon, { size: iconSize, className: "designbase-button__end-icon", color: getIconColor() }))] }));
|
|
3540
3543
|
};
|
|
3541
3544
|
return (jsxRuntimeExports.jsx("button", { ...buttonProps, ref: ref, className: classes, "aria-label": iconOnly ? props['aria-label'] || children : undefined, children: renderContent() }));
|
|
3542
3545
|
});
|
|
3543
3546
|
Button.displayName = 'Button';
|
|
3544
3547
|
|
|
3545
|
-
const Input = React.forwardRef(({ type = 'text', label, placeholder, defaultValue, value, size = '
|
|
3548
|
+
const Input = React.forwardRef(({ type = 'text', label, placeholder, defaultValue, value, size = 'm', disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, startIcon: StartIcon, endIcon: EndIcon, fullWidth = false, className, inputClassName, onChange, onFocus, onBlur, ...props }, forwardedRef) => {
|
|
3546
3549
|
const inputId = React.useId();
|
|
3547
3550
|
const helperTextId = React.useId();
|
|
3548
3551
|
const errorMessageId = React.useId();
|
|
@@ -3568,8 +3571,10 @@ const Input = React.forwardRef(({ type = 'text', label, placeholder, defaultValu
|
|
|
3568
3571
|
});
|
|
3569
3572
|
Input.displayName = 'Input';
|
|
3570
3573
|
|
|
3571
|
-
const Modal = ({ isOpen, onClose, title, size = '
|
|
3574
|
+
const Modal = ({ isOpen, onClose, title, size = 'm', closeOnOutsideClick = true, closeOnEscape = true, children, className, overlayClassName, }) => {
|
|
3572
3575
|
const modalRef = React.useRef(null);
|
|
3576
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
3577
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
|
|
3573
3578
|
// Prevent scrolling while modal is open
|
|
3574
3579
|
React.useEffect(() => {
|
|
3575
3580
|
if (isOpen) {
|
|
@@ -3599,11 +3604,11 @@ const Modal = ({ isOpen, onClose, title, size = 'md', closeOnOutsideClick = true
|
|
|
3599
3604
|
return null;
|
|
3600
3605
|
const modalClasses = clsx('designbase-modal', `designbase-modal--${size}`, className);
|
|
3601
3606
|
const overlayClasses = clsx('designbase-modal__overlay', overlayClassName);
|
|
3602
|
-
return (jsxRuntimeExports.jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxRuntimeExports.jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? 'modal-title' : undefined, children: [title && (jsxRuntimeExports.jsx(ModalHeader, { title: title, showCloseButton: true, onClose: onClose })), jsxRuntimeExports.jsx("div", { className: "designbase-modal__content", children: children })] }) }));
|
|
3607
|
+
return (jsxRuntimeExports.jsx("div", { className: overlayClasses, onClick: closeOnOutsideClick ? onClose : undefined, children: jsxRuntimeExports.jsxs("div", { ref: modalRef, className: modalClasses, onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? 'modal-title' : undefined, children: [title && (jsxRuntimeExports.jsx(ModalHeader, { title: title, showCloseButton: true, onClose: onClose, iconSize: iconSize })), jsxRuntimeExports.jsx("div", { className: "designbase-modal__content", children: children })] }) }));
|
|
3603
3608
|
};
|
|
3604
|
-
const ModalHeader = ({ title, showCloseButton = true, onClose, className, children, }) => {
|
|
3609
|
+
const ModalHeader = ({ title, showCloseButton = true, onClose, iconSize = 20, className, children, }) => {
|
|
3605
3610
|
const classes = clsx('designbase-modal__header', className);
|
|
3606
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntimeExports.jsx("h2", { id: "modal-title", className: "designbase-modal__title", children: title })), children] }), showCloseButton && onClose && (jsxRuntimeExports.jsx("button", { type: "button", onClick: onClose, "aria-label": "\uBAA8\uB2EC \uB2EB\uAE30", className: "designbase-modal__close-button", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size:
|
|
3611
|
+
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsxs("div", { className: "designbase-modal__header-content", children: [title && (jsxRuntimeExports.jsx("h2", { id: "modal-title", className: "designbase-modal__title", children: title })), children] }), showCloseButton && onClose && (jsxRuntimeExports.jsx("button", { type: "button", onClick: onClose, "aria-label": "\uBAA8\uB2EC \uB2EB\uAE30", className: "designbase-modal__close-button", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: iconSize, color: "currentColor" }) }))] }));
|
|
3607
3612
|
};
|
|
3608
3613
|
const ModalBody = ({ className, children, }) => {
|
|
3609
3614
|
const classes = clsx('designbase-modal__body', className);
|
|
@@ -3618,7 +3623,7 @@ ModalHeader.displayName = 'ModalHeader';
|
|
|
3618
3623
|
ModalBody.displayName = 'ModalBody';
|
|
3619
3624
|
ModalFooter.displayName = 'ModalFooter';
|
|
3620
3625
|
|
|
3621
|
-
const Checkbox = React.forwardRef(({ isSelected, defaultSelected, isIndeterminate = false, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = '
|
|
3626
|
+
const Checkbox = React.forwardRef(({ isSelected, defaultSelected, isIndeterminate = false, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = 'm', children, className, name, value, onChange, ...props }, forwardedRef) => {
|
|
3622
3627
|
const [selected, setSelected] = React.useState(isSelected ?? defaultSelected ?? false);
|
|
3623
3628
|
React.useEffect(() => {
|
|
3624
3629
|
if (isSelected !== undefined) {
|
|
@@ -3652,7 +3657,7 @@ const Checkbox = React.forwardRef(({ isSelected, defaultSelected, isIndeterminat
|
|
|
3652
3657
|
});
|
|
3653
3658
|
Checkbox.displayName = 'Checkbox';
|
|
3654
3659
|
|
|
3655
|
-
const Toggle = React.forwardRef(({ isSelected, defaultSelected, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = '
|
|
3660
|
+
const Toggle = React.forwardRef(({ isSelected, defaultSelected, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = 'm', children, className, name, value, onChange, ...props }, forwardedRef) => {
|
|
3656
3661
|
const [selected, setSelected] = React.useState(isSelected ?? defaultSelected ?? false);
|
|
3657
3662
|
React.useEffect(() => {
|
|
3658
3663
|
if (isSelected !== undefined) {
|
|
@@ -3676,7 +3681,7 @@ const Toggle = React.forwardRef(({ isSelected, defaultSelected, isDisabled = fal
|
|
|
3676
3681
|
});
|
|
3677
3682
|
Toggle.displayName = 'Toggle';
|
|
3678
3683
|
|
|
3679
|
-
const Radio = React.forwardRef(({ isSelected, defaultSelected, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = '
|
|
3684
|
+
const Radio = React.forwardRef(({ isSelected, defaultSelected, isDisabled = false, isReadOnly = false, isRequired = false, hasLabel = true, size = 'm', children, className, name, value, onChange, ...props }, forwardedRef) => {
|
|
3680
3685
|
const [selected, setSelected] = React.useState(isSelected ?? defaultSelected ?? false);
|
|
3681
3686
|
React.useEffect(() => {
|
|
3682
3687
|
if (isSelected !== undefined) {
|
|
@@ -3698,12 +3703,12 @@ const Radio = React.forwardRef(({ isSelected, defaultSelected, isDisabled = fals
|
|
|
3698
3703
|
}, className);
|
|
3699
3704
|
const getIconColor = () => {
|
|
3700
3705
|
if (isDisabled) {
|
|
3701
|
-
return 'var(--color-
|
|
3706
|
+
return 'var(--db-color-disabled)';
|
|
3702
3707
|
}
|
|
3703
3708
|
if (selected) {
|
|
3704
|
-
return 'var(--color-
|
|
3709
|
+
return 'var(--db-color-primary)';
|
|
3705
3710
|
}
|
|
3706
|
-
return 'var(--color-
|
|
3711
|
+
return 'var(--db-color-primary)';
|
|
3707
3712
|
};
|
|
3708
3713
|
return (jsxRuntimeExports.jsxs("label", { className: classes, children: [jsxRuntimeExports.jsx("input", { ...props, ref: forwardedRef, name: name, value: value, type: "radio", checked: selected, onChange: handleChange, disabled: isDisabled, readOnly: isReadOnly, required: isRequired, className: "designbase-radio__input" }), jsxRuntimeExports.jsx("div", { className: "designbase-radio__visual", children: selected && (jsxRuntimeExports.jsx("div", { className: "designbase-radio__dot", style: { backgroundColor: getIconColor() } })) }), children && jsxRuntimeExports.jsx("span", { className: "designbase-radio__label", children: children })] }));
|
|
3709
3714
|
});
|
|
@@ -3841,7 +3846,7 @@ const ToastProvider = ({ children }) => {
|
|
|
3841
3846
|
return (jsxRuntimeExports.jsxs(ToastContext.Provider, { value: { addToast, removeToast }, children: [children, jsxRuntimeExports.jsx(ToastContainer, { toasts: toasts, onRemoveToast: removeToast })] }));
|
|
3842
3847
|
};
|
|
3843
3848
|
|
|
3844
|
-
const Select = ({ value, defaultValue, options, label, placeholder = '선택하세요', multiple = false, searchable = false, disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, size = '
|
|
3849
|
+
const Select = ({ value, defaultValue, options, label, placeholder = '선택하세요', multiple = false, searchable = false, disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, size = 'm', fullWidth = false, dropdownWidth = 'auto', maxHeight = 200, showClearButton = true, className, onChange, onFocus, onBlur, ...props }) => {
|
|
3845
3850
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
3846
3851
|
const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? (multiple ? [] : ''));
|
|
3847
3852
|
const [searchTerm, setSearchTerm] = React.useState('');
|
|
@@ -4020,12 +4025,12 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
|
|
|
4020
4025
|
'designbase-select__option--selected': isSelected,
|
|
4021
4026
|
'designbase-select__option--focused': isFocused,
|
|
4022
4027
|
'designbase-select__option--disabled': option.disabled,
|
|
4023
|
-
}), onClick: () => handleOptionSelect(option), role: "option", "aria-selected": isSelected, children: [multiple && (jsxRuntimeExports.jsx("div", { className: "designbase-select__checkbox", children: jsxRuntimeExports.jsx(Checkbox, { isSelected: isSelected, isDisabled: option.disabled, size: "
|
|
4028
|
+
}), onClick: () => handleOptionSelect(option), role: "option", "aria-selected": isSelected, children: [multiple && (jsxRuntimeExports.jsx("div", { className: "designbase-select__checkbox", children: jsxRuntimeExports.jsx(Checkbox, { isSelected: isSelected, isDisabled: option.disabled, size: "s", hasLabel: false, onChange: () => handleOptionSelect(option) }) })), jsxRuntimeExports.jsx("span", { className: "designbase-select__option-label", children: option.label })] }, option.value));
|
|
4024
4029
|
})) }) }), helperText && !error && (jsxRuntimeExports.jsx("p", { className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsxRuntimeExports.jsx("p", { className: "designbase-select__error-message", children: errorMessage }))] }));
|
|
4025
4030
|
};
|
|
4026
4031
|
Select.displayName = 'Select';
|
|
4027
4032
|
|
|
4028
|
-
const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal', size = '
|
|
4033
|
+
const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal', size = 'm', fullWidth = false, variant = 'default', className, onTabChange, ...props }) => {
|
|
4029
4034
|
const [activeTabId, setActiveTabId] = React.useState(selectedId ?? defaultSelectedId ?? items[0]?.id ?? '');
|
|
4030
4035
|
const [focusedTabId, setFocusedTabId] = React.useState('');
|
|
4031
4036
|
const tabListRef = React.useRef(null);
|
|
@@ -4137,12 +4142,12 @@ const Tabs = ({ items, defaultSelectedId, selectedId, orientation = 'horizontal'
|
|
|
4137
4142
|
else {
|
|
4138
4143
|
tabRefs.current.delete(item.id);
|
|
4139
4144
|
}
|
|
4140
|
-
}, className: tabClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, "aria-controls": `panel-${item.id}`, id: `tab-${item.id}`, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onClick: () => handleTabSelect(item.id), onKeyDown: (e) => handleKeyDown(e, item.id), onFocus: () => handleTabFocus(item.id), onBlur: handleTabBlur, children: [item.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-tabs__tab-icon", children: jsxRuntimeExports.jsx(item.icon, { size: size === '
|
|
4145
|
+
}, className: tabClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, "aria-controls": `panel-${item.id}`, id: `tab-${item.id}`, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onClick: () => handleTabSelect(item.id), onKeyDown: (e) => handleKeyDown(e, item.id), onFocus: () => handleTabFocus(item.id), onBlur: handleTabBlur, children: [item.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-tabs__tab-icon", children: jsxRuntimeExports.jsx(item.icon, { size: size === 's' ? 16 : size === 'l' ? 20 : 18 }) })), jsxRuntimeExports.jsx("span", { className: "designbase-tabs__tab-label", children: item.label })] }, item.id));
|
|
4141
4146
|
}) }), activeTab && (jsxRuntimeExports.jsx("div", { className: "designbase-tabs__panel", role: "tabpanel", id: `panel-${activeTab.id}`, "aria-labelledby": `tab-${activeTab.id}`, tabIndex: 0, children: activeTab.content }))] }));
|
|
4142
4147
|
};
|
|
4143
4148
|
Tabs.displayName = 'Tabs';
|
|
4144
4149
|
|
|
4145
|
-
const SegmentControl = ({ options, defaultValue, value, size = '
|
|
4150
|
+
const SegmentControl = ({ options, defaultValue, value, size = 'm', fullWidth = false, disabled = false, className, onChange, ...props }) => {
|
|
4146
4151
|
const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? options[0]?.value ?? '');
|
|
4147
4152
|
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
|
4148
4153
|
const containerRef = React.useRef(null);
|
|
@@ -4237,7 +4242,7 @@ const SegmentControl = ({ options, defaultValue, value, size = 'md', fullWidth =
|
|
|
4237
4242
|
else {
|
|
4238
4243
|
segmentRefs.current.delete(option.value);
|
|
4239
4244
|
}
|
|
4240
|
-
}, className: segmentClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onClick: () => handleSegmentSelect(option.value), onFocus: () => handleSegmentFocus(index), onBlur: handleSegmentBlur, children: [option.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-segment-control__segment-icon", children: jsxRuntimeExports.jsx(option.icon, { size: size === '
|
|
4245
|
+
}, className: segmentClasses, role: "tab", "aria-selected": isSelected, "aria-disabled": isDisabled, tabIndex: isSelected ? 0 : -1, disabled: isDisabled, onClick: () => handleSegmentSelect(option.value), onFocus: () => handleSegmentFocus(index), onBlur: handleSegmentBlur, children: [option.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-segment-control__segment-icon", children: jsxRuntimeExports.jsx(option.icon, { size: size === 's' ? 14 : size === 'l' ? 18 : 16 }) })), jsxRuntimeExports.jsx("span", { className: "designbase-segment-control__segment-label", children: option.label })] }, option.value));
|
|
4241
4246
|
}), jsxRuntimeExports.jsx("div", { className: "designbase-segment-control__indicator", style: {
|
|
4242
4247
|
transform: `translateX(${selectedIndex * 100}%)`,
|
|
4243
4248
|
width: `${100 / options.length}%`,
|
|
@@ -4245,7 +4250,9 @@ const SegmentControl = ({ options, defaultValue, value, size = 'md', fullWidth =
|
|
|
4245
4250
|
};
|
|
4246
4251
|
SegmentControl.displayName = 'SegmentControl';
|
|
4247
4252
|
|
|
4248
|
-
const Dropdown = ({ items, trigger, label = '메뉴', size = '
|
|
4253
|
+
const Dropdown = ({ items, trigger, label = '메뉴', size = 'm', placement = 'bottom-left', fullWidth = false, disabled = false, className, isOpen: controlledIsOpen, onToggle, ...props }) => {
|
|
4254
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
4255
|
+
const iconSize = size === 's' ? 14 : size === 'l' ? 18 : 16;
|
|
4249
4256
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
4250
4257
|
const [focusedIndex, setFocusedIndex] = React.useState(-1);
|
|
4251
4258
|
const containerRef = React.useRef(null);
|
|
@@ -4378,7 +4385,7 @@ const Dropdown = ({ items, trigger, label = '메뉴', size = 'md', placement = '
|
|
|
4378
4385
|
const menuClasses = clsx('designbase-dropdown__menu', `designbase-dropdown__menu--${placement}`, {
|
|
4379
4386
|
'designbase-dropdown__menu--open': isDropdownOpen,
|
|
4380
4387
|
});
|
|
4381
|
-
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: classes, ...props, children: [jsxRuntimeExports.jsx("button", { ref: triggerRef, className: triggerClasses, onClick: handleToggle, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "true", "aria-expanded": isDropdownOpen, "aria-label": label, children: trigger || (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: "designbase-dropdown__trigger-label", children: label }), jsxRuntimeExports.jsx(icons.ChevronDownIcon, { size:
|
|
4388
|
+
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: classes, ...props, children: [jsxRuntimeExports.jsx("button", { ref: triggerRef, className: triggerClasses, onClick: handleToggle, onKeyDown: handleKeyDown, disabled: disabled, "aria-haspopup": "true", "aria-expanded": isDropdownOpen, "aria-label": label, children: trigger || (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("span", { className: "designbase-dropdown__trigger-label", children: label }), jsxRuntimeExports.jsx(icons.ChevronDownIcon, { size: iconSize, color: "currentColor", className: "designbase-dropdown__trigger-icon" })] })) }), jsxRuntimeExports.jsx("div", { ref: menuRef, className: menuClasses, role: "menu", "aria-label": label, children: items.map((item, index) => {
|
|
4382
4389
|
if (item.divider) {
|
|
4383
4390
|
return (jsxRuntimeExports.jsx("div", { className: "designbase-dropdown__divider", role: "separator" }, `divider-${index}`));
|
|
4384
4391
|
}
|
|
@@ -4395,12 +4402,12 @@ const Dropdown = ({ items, trigger, label = '메뉴', size = 'md', placement = '
|
|
|
4395
4402
|
else {
|
|
4396
4403
|
itemRefs.current.delete(item.id);
|
|
4397
4404
|
}
|
|
4398
|
-
}, className: itemClasses, role: "menuitem", disabled: isDisabled, onClick: () => handleItemClick(item), onFocus: () => setFocusedIndex(index), children: [item.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-dropdown__item-icon", children: jsxRuntimeExports.jsx(item.icon, { size:
|
|
4405
|
+
}, className: itemClasses, role: "menuitem", disabled: isDisabled, onClick: () => handleItemClick(item), onFocus: () => setFocusedIndex(index), children: [item.icon && (jsxRuntimeExports.jsx("span", { className: "designbase-dropdown__item-icon", children: jsxRuntimeExports.jsx(item.icon, { size: iconSize, color: "currentColor" }) })), jsxRuntimeExports.jsx("span", { className: "designbase-dropdown__item-label", children: item.label })] }, item.id));
|
|
4399
4406
|
}) })] }));
|
|
4400
4407
|
};
|
|
4401
4408
|
Dropdown.displayName = 'Dropdown';
|
|
4402
4409
|
|
|
4403
|
-
const Logo = ({ text = 'Logo', src, alt, size = '
|
|
4410
|
+
const Logo = ({ text = 'Logo', src, alt, size = 'm', variant = 'default', clickable = false, href, target = '_self', fullWidth = false, className, onClick, ...props }) => {
|
|
4404
4411
|
const classes = clsx('designbase-logo', `designbase-logo--${size}`, `designbase-logo--${variant}`, {
|
|
4405
4412
|
'designbase-logo--clickable': clickable || href,
|
|
4406
4413
|
'designbase-logo--full-width': fullWidth,
|
|
@@ -4425,7 +4432,7 @@ const Logo = ({ text = 'Logo', src, alt, size = 'md', variant = 'default', click
|
|
|
4425
4432
|
};
|
|
4426
4433
|
Logo.displayName = 'Logo';
|
|
4427
4434
|
|
|
4428
|
-
const Progressbar = ({ value, max = 100, min = 0, size = '
|
|
4435
|
+
const Progressbar = ({ value, max = 100, min = 0, size = 'm', variant = 'default', style = 'solid', showLabel = false, label, labelPosition = 'top', fullWidth = false, disabled = false, className, ...props }) => {
|
|
4429
4436
|
// 값 범위 제한
|
|
4430
4437
|
const clampedValue = Math.max(min, Math.min(max, value));
|
|
4431
4438
|
const percentage = ((clampedValue - min) / (max - min)) * 100;
|
|
@@ -4453,7 +4460,7 @@ const Progressbar = ({ value, max = 100, min = 0, size = 'md', variant = 'defaul
|
|
|
4453
4460
|
};
|
|
4454
4461
|
Progressbar.displayName = 'Progressbar';
|
|
4455
4462
|
|
|
4456
|
-
const Badge = ({ children, size = '
|
|
4463
|
+
const Badge = ({ children, size = 'm', variant = 'primary', style = 'text', count, maxCount = 99, disabled = false, className, ...props }) => {
|
|
4457
4464
|
// 숫자 스타일일 때 count 값을 사용
|
|
4458
4465
|
const displayContent = style === 'number' && count !== undefined
|
|
4459
4466
|
? (count > maxCount ? `${maxCount}+` : count.toString())
|
|
@@ -4465,7 +4472,7 @@ const Badge = ({ children, size = 'md', variant = 'primary', style = 'text', cou
|
|
|
4465
4472
|
};
|
|
4466
4473
|
Badge.displayName = 'Badge';
|
|
4467
4474
|
|
|
4468
|
-
const MenuItem = ({ id, label, href, icon: Icon, active = false, disabled = false, badge, badgeColor = 'primary', variant = 'default', type = 'inline', size = '
|
|
4475
|
+
const MenuItem = ({ id, label, href, icon: Icon, active = false, disabled = false, badge, badgeColor = 'primary', variant = 'default', type = 'inline', size = 'm', style = 'dropdown', subItems, expanded = false, expandable = false, depth = 0, onClick, onChildClick, className, }) => {
|
|
4469
4476
|
const [internalExpanded, setInternalExpanded] = React.useState(expanded);
|
|
4470
4477
|
// expanded prop이 변경될 때 internalExpanded 업데이트
|
|
4471
4478
|
React.useEffect(() => {
|
|
@@ -4520,11 +4527,11 @@ const MenuItem = ({ id, label, href, icon: Icon, active = false, disabled = fals
|
|
|
4520
4527
|
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsxs("div", { className: contentClasses, onClick: handleClick, children: [Icon && (jsxRuntimeExports.jsx("div", { className: clsx('designbase-menu-item__icon', `designbase-menu-item__icon--${variant}`, {
|
|
4521
4528
|
'designbase-menu-item__icon--active': active,
|
|
4522
4529
|
'designbase-menu-item__icon--disabled': disabled,
|
|
4523
|
-
}), children: jsxRuntimeExports.jsx(Icon, { size: size === '
|
|
4530
|
+
}), children: jsxRuntimeExports.jsx(Icon, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) })), jsxRuntimeExports.jsx("span", { className: "designbase-menu-item__label", children: label }), badge && (jsxRuntimeExports.jsx(Badge, { count: typeof badge === 'string' ? parseInt(badge) : badge, variant: badgeColor === 'neutral' ? 'secondary' : badgeColor, size: "s", style: "number" })), hasChildren && (jsxRuntimeExports.jsx("div", { className: "designbase-menu-item__expand-icon", children: isExpanded ? (jsxRuntimeExports.jsx(icons.ChevronUpIcon, { size: 16 })) : (jsxRuntimeExports.jsx(icons.ChevronDownIcon, { size: 16 })) }))] }), hasChildren && isExpanded && (jsxRuntimeExports.jsx("div", { className: clsx('designbase-menu-item__children', `designbase-menu-item__children--${style}`), children: subItems.map((child) => (jsxRuntimeExports.jsx(MenuItem, { id: child.id, label: child.label, href: child.href, icon: child.icon, active: child.active, disabled: child.disabled, badge: child.badge, badgeColor: child.badgeColor, variant: child.variant, type: child.type, size: size, style: child.style || style, subItems: child.subItems, depth: depth + 1, onClick: () => handleChildClick(child), onChildClick: onChildClick }, child.id))) }))] }));
|
|
4524
4531
|
};
|
|
4525
4532
|
MenuItem.displayName = 'MenuItem';
|
|
4526
4533
|
|
|
4527
|
-
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = '
|
|
4534
|
+
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = icons.SearchIcon, clearIcon: ClearIconComponent = icons.CloseIcon, onChange, onSearch, onFocus, onBlur, onKeyDown, className, ...props }) => {
|
|
4528
4535
|
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
4529
4536
|
const inputRef = React.useRef(null);
|
|
4530
4537
|
const currentValue = value !== undefined ? value : internalValue;
|
|
@@ -4564,17 +4571,24 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
|
|
|
4564
4571
|
'designbase-search-bar__input--disabled': disabled,
|
|
4565
4572
|
'designbase-search-bar__input--readonly': readOnly,
|
|
4566
4573
|
});
|
|
4567
|
-
return (jsxRuntimeExports.jsx("div", { className: classes, role: "search", children: jsxRuntimeExports.jsxs("div", { className: "designbase-search-bar__container", children: [jsxRuntimeExports.jsx("div", { className: "designbase-search-bar__search-icon", children: jsxRuntimeExports.jsx(SearchIconComponent, { size: size === '
|
|
4574
|
+
return (jsxRuntimeExports.jsx("div", { className: classes, role: "search", children: jsxRuntimeExports.jsxs("div", { className: "designbase-search-bar__container", children: [jsxRuntimeExports.jsx("div", { className: "designbase-search-bar__search-icon", children: jsxRuntimeExports.jsx(SearchIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }), jsxRuntimeExports.jsx("input", { ref: inputRef, type: "text", className: inputClasses, value: currentValue, placeholder: placeholder, disabled: disabled, readOnly: readOnly, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, onKeyDown: handleKeyDown, "aria-label": "\uAC80\uC0C9\uC5B4 \uC785\uB825", ...props }), currentValue && currentValue.length > 0 && !disabled && !readOnly && (jsxRuntimeExports.jsx("button", { type: "button", className: "designbase-search-bar__clear-button", onClick: handleClear, "aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30", children: jsxRuntimeExports.jsx(ClearIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }))] }) }));
|
|
4568
4575
|
};
|
|
4569
4576
|
SearchBar.displayName = 'SearchBar';
|
|
4570
4577
|
|
|
4571
|
-
const Avatar = ({ src, alt, initials, icon, size = '
|
|
4578
|
+
const Avatar = ({ src, alt, initials, icon, size = 'm', variant = 'circle', status, badge, badgeMaxCount = 99, badgeVariant = 'danger', badgeStyle = 'number', badgeText, onClick, disabled = false, className, ...props }) => {
|
|
4572
4579
|
const [imageError, setImageError] = React.useState(false);
|
|
4580
|
+
const [imageLoading, setImageLoading] = React.useState(true);
|
|
4581
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
4582
|
+
const iconSize = size === 'xs' ? 12 : size === 's' ? 16 : size === 'm' ? 20 : size === 'l' ? 24 : size === 'xl' ? 32 : 40; // 2xl
|
|
4573
4583
|
const shouldShowImage = src && !imageError;
|
|
4574
4584
|
const shouldShowInitials = !shouldShowImage && initials;
|
|
4575
|
-
const shouldShowIcon = !shouldShowImage && !shouldShowInitials
|
|
4585
|
+
const shouldShowIcon = !shouldShowImage && !shouldShowInitials;
|
|
4576
4586
|
const handleImageError = () => {
|
|
4577
4587
|
setImageError(true);
|
|
4588
|
+
setImageLoading(false);
|
|
4589
|
+
};
|
|
4590
|
+
const handleImageLoad = () => {
|
|
4591
|
+
setImageLoading(false);
|
|
4578
4592
|
};
|
|
4579
4593
|
const handleClick = () => {
|
|
4580
4594
|
if (!disabled && onClick) {
|
|
@@ -4585,20 +4599,63 @@ const Avatar = ({ src, alt, initials, icon, size = 'md', variant = 'circle', sta
|
|
|
4585
4599
|
'designbase-avatar--clickable': onClick,
|
|
4586
4600
|
'designbase-avatar--disabled': disabled,
|
|
4587
4601
|
}, className);
|
|
4602
|
+
// 랜덤 컬러 생성 함수
|
|
4603
|
+
const generateRandomColor = (text) => {
|
|
4604
|
+
// 텍스트를 기반으로 일관된 색상 생성
|
|
4605
|
+
let hash = 0;
|
|
4606
|
+
for (let i = 0; i < text.length; i++) {
|
|
4607
|
+
hash = text.charCodeAt(i) + ((hash << 5) - hash);
|
|
4608
|
+
}
|
|
4609
|
+
// 연한 배경색 팔레트
|
|
4610
|
+
const lightColors = [
|
|
4611
|
+
'#E3F2FD', // 연한 파랑
|
|
4612
|
+
'#F3E5F5', // 연한 보라
|
|
4613
|
+
'#E8F5E8', // 연한 초록
|
|
4614
|
+
'#FFF3E0', // 연한 주황
|
|
4615
|
+
'#FCE4EC', // 연한 핑크
|
|
4616
|
+
'#E0F2F1', // 연한 청록
|
|
4617
|
+
'#FFF8E1', // 연한 노랑
|
|
4618
|
+
'#F1F8E9', // 연한 라임
|
|
4619
|
+
'#E8EAF6', // 연한 인디고
|
|
4620
|
+
'#FFEBEE', // 연한 빨강
|
|
4621
|
+
];
|
|
4622
|
+
// 진한 텍스트 색상 팔레트
|
|
4623
|
+
const darkColors = [
|
|
4624
|
+
'#1976D2', // 진한 파랑
|
|
4625
|
+
'#7B1FA2', // 진한 보라
|
|
4626
|
+
'#388E3C', // 진한 초록
|
|
4627
|
+
'#F57C00', // 진한 주황
|
|
4628
|
+
'#C2185B', // 진한 핑크
|
|
4629
|
+
'#00796B', // 진한 청록
|
|
4630
|
+
'#F9A825', // 진한 노랑
|
|
4631
|
+
'#689F38', // 진한 라임
|
|
4632
|
+
'#3F51B5', // 진한 인디고
|
|
4633
|
+
'#D32F2F', // 진한 빨강
|
|
4634
|
+
];
|
|
4635
|
+
const colorIndex = Math.abs(hash) % lightColors.length;
|
|
4636
|
+
return {
|
|
4637
|
+
backgroundColor: lightColors[colorIndex],
|
|
4638
|
+
color: darkColors[colorIndex]
|
|
4639
|
+
};
|
|
4640
|
+
};
|
|
4588
4641
|
const getInitials = () => {
|
|
4589
4642
|
if (!initials)
|
|
4590
4643
|
return '';
|
|
4591
|
-
|
|
4644
|
+
// 한 글자만 표시 (첫 번째 글자)
|
|
4645
|
+
return initials.charAt(0).toUpperCase();
|
|
4592
4646
|
};
|
|
4593
4647
|
return (jsxRuntimeExports.jsxs("div", { className: classes, role: onClick ? 'button' : undefined, tabIndex: onClick && !disabled ? 0 : undefined, onClick: handleClick, onKeyDown: (e) => {
|
|
4594
4648
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
4595
4649
|
e.preventDefault();
|
|
4596
4650
|
handleClick();
|
|
4597
4651
|
}
|
|
4598
|
-
}, ...props, children: [shouldShowImage && (jsxRuntimeExports.jsx("
|
|
4652
|
+
}, ...props, children: [imageLoading && shouldShowImage && (jsxRuntimeExports.jsx("div", { className: "designbase-avatar__loading", children: jsxRuntimeExports.jsx("div", { className: "designbase-avatar__skeleton" }) })), shouldShowImage && (jsxRuntimeExports.jsx("img", { src: src, alt: alt || '아바타 이미지', className: "designbase-avatar__image", onLoad: handleImageLoad, onError: handleImageError, loading: "lazy" })), shouldShowInitials && (jsxRuntimeExports.jsx("div", { className: "designbase-avatar__initials", style: generateRandomColor(initials || ''), children: getInitials() })), shouldShowIcon && (jsxRuntimeExports.jsx("div", { className: "designbase-avatar__icon", children: icon ? (React.isValidElement(icon) ? (React.cloneElement(icon, {
|
|
4653
|
+
size: iconSize,
|
|
4654
|
+
color: 'currentColor'
|
|
4655
|
+
})) : icon) : (jsxRuntimeExports.jsx(icons.UserIcon, { size: iconSize, color: "currentColor" })) })), status && (jsxRuntimeExports.jsx("span", { className: clsx('designbase-avatar__status', `designbase-avatar__status--${status}`) })), badge !== undefined && (jsxRuntimeExports.jsx("div", { className: "designbase-avatar__badge", children: jsxRuntimeExports.jsx(Badge, { count: badgeStyle === 'text' ? undefined : badge, maxCount: badgeMaxCount, variant: badgeVariant, style: badgeStyle, size: size === 'xs' || size === 's' ? 's' : size === 'l' || size === 'xl' || size === '2xl' ? 'l' : 'm', children: badgeStyle === 'text' ? badgeText : undefined }) }))] }));
|
|
4599
4656
|
};
|
|
4600
4657
|
Avatar.displayName = 'Avatar';
|
|
4601
|
-
const AvatarGroup = ({ children, max, size = '
|
|
4658
|
+
const AvatarGroup = ({ children, max, size = 'm', variant = 'circle', spacing = 'normal', className, ...props }) => {
|
|
4602
4659
|
const childrenArray = React.Children.toArray(children);
|
|
4603
4660
|
const totalCount = childrenArray.length;
|
|
4604
4661
|
const visibleCount = max ? Math.min(max, totalCount) : totalCount;
|
|
@@ -4611,10 +4668,12 @@ const AvatarGroup = ({ children, max, size = 'md', variant = 'circle', spacing =
|
|
|
4611
4668
|
};
|
|
4612
4669
|
AvatarGroup.displayName = 'AvatarGroup';
|
|
4613
4670
|
|
|
4614
|
-
const Navbar = ({ size = '
|
|
4671
|
+
const Navbar = ({ size = 'm', variant = 'default', position = 'static', logo, onLogoClick, items = [], onItemClick, userMenuItems = [], onUserMenuItemClick, userProfile, onAuthClick, isAuthenticated = false, showSearch = false, onSearch, searchPlaceholder = '검색...', fullWidth = false, shadow = false, className, ...props }) => {
|
|
4615
4672
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);
|
|
4616
4673
|
const [isUserMenuOpen, setIsUserMenuOpen] = React.useState(false);
|
|
4617
4674
|
const [searchQuery, setSearchQuery] = React.useState('');
|
|
4675
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
4676
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
4618
4677
|
const handleMobileMenuToggle = () => {
|
|
4619
4678
|
setIsMobileMenuOpen(!isMobileMenuOpen);
|
|
4620
4679
|
};
|
|
@@ -4649,7 +4708,7 @@ const Navbar = ({ size = 'md', variant = 'default', position = 'static', logo, o
|
|
|
4649
4708
|
'designbase-navbar__container--full-width': fullWidth,
|
|
4650
4709
|
});
|
|
4651
4710
|
const renderNavItem = (item) => (jsxRuntimeExports.jsx("li", { className: "designbase-navbar__nav-item", children: jsxRuntimeExports.jsx(MenuItem, { ...item, type: "inline", style: "dropdown", onClick: () => handleItemClick(item), onChildClick: (child) => handleItemClick(child) }) }, item.id));
|
|
4652
|
-
return (jsxRuntimeExports.jsxs("nav", { className: classes, role: "navigation", "aria-label": "\uBA54\uC778 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: [jsxRuntimeExports.jsxs("div", { className: containerClasses, children: [jsxRuntimeExports.jsx("div", { className: "designbase-navbar__brand", children: jsxRuntimeExports.jsx("div", { className: "designbase-navbar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, children: logo || jsxRuntimeExports.jsx(Logo, { size: size === '
|
|
4711
|
+
return (jsxRuntimeExports.jsxs("nav", { className: classes, role: "navigation", "aria-label": "\uBA54\uC778 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: [jsxRuntimeExports.jsxs("div", { className: containerClasses, children: [jsxRuntimeExports.jsx("div", { className: "designbase-navbar__brand", children: jsxRuntimeExports.jsx("div", { className: "designbase-navbar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, children: logo || jsxRuntimeExports.jsx(Logo, { size: size === 's' ? 's' : size === 'l' ? 'l' : 'm' }) }) }), jsxRuntimeExports.jsx("div", { className: "designbase-navbar__nav", children: jsxRuntimeExports.jsx("ul", { className: "designbase-navbar__nav-list", children: items.map(renderNavItem) }) }), showSearch && (jsxRuntimeExports.jsx("div", { className: "designbase-navbar__search", children: jsxRuntimeExports.jsx(SearchBar, { placeholder: searchPlaceholder, value: searchQuery, onChange: setSearchQuery, onSearch: onSearch, size: size === 's' ? 's' : size === 'l' ? 'l' : 'm', variant: "outlined" }) })), jsxRuntimeExports.jsx("div", { className: "designbase-navbar__user-menu", children: isAuthenticated && userProfile ? (jsxRuntimeExports.jsxs("div", { className: "designbase-navbar__user-dropdown", children: [jsxRuntimeExports.jsxs("button", { className: "designbase-navbar__user-toggle", onClick: handleUserMenuToggle, "aria-expanded": isUserMenuOpen, children: [jsxRuntimeExports.jsx(Avatar, { src: userProfile.avatar, alt: userProfile.name, initials: userProfile.name, size: size === 's' ? 's' : size === 'l' ? 'l' : 'm', badge: userProfile.badge, badgeVariant: userProfile.badgeVariant, badgeStyle: userProfile.badgeStyle, badgeText: userProfile.badgeText }), jsxRuntimeExports.jsx("span", { className: "designbase-navbar__user-name", children: userProfile.name }), jsxRuntimeExports.jsx("i", { className: "designbase-icon-chevron-down" })] }), isUserMenuOpen && (jsxRuntimeExports.jsxs("ul", { className: "designbase-navbar__user-dropdown-menu", children: [userProfile.email && (jsxRuntimeExports.jsx("li", { className: "designbase-navbar__user-info", children: jsxRuntimeExports.jsx("span", { className: "designbase-navbar__user-email", children: userProfile.email }) })), userMenuItems.map((item) => (jsxRuntimeExports.jsx("li", { children: jsxRuntimeExports.jsxs("a", { href: item.href, className: clsx('designbase-navbar__user-dropdown-item', {
|
|
4653
4712
|
'designbase-navbar__user-dropdown-item--disabled': item.disabled,
|
|
4654
4713
|
}), onClick: (e) => {
|
|
4655
4714
|
if (item.disabled) {
|
|
@@ -4657,7 +4716,7 @@ const Navbar = ({ size = 'md', variant = 'default', position = 'static', logo, o
|
|
|
4657
4716
|
return;
|
|
4658
4717
|
}
|
|
4659
4718
|
handleUserMenuItemClick(item);
|
|
4660
|
-
}, children: [item.icon && React.createElement(item.icon, { size:
|
|
4719
|
+
}, children: [item.icon && React.createElement(item.icon, { size: iconSize, color: 'currentColor' }), item.label] }) }, item.id)))] }))] })) : (jsxRuntimeExports.jsx("button", { className: "designbase-navbar__auth-button", onClick: onAuthClick, children: "\uB85C\uADF8\uC778" })) }), jsxRuntimeExports.jsxs("button", { className: "designbase-navbar__mobile-toggle", onClick: handleMobileMenuToggle, "aria-expanded": isMobileMenuOpen, "aria-label": "\uBA54\uB274 \uC5F4\uAE30", children: [jsxRuntimeExports.jsx("span", { className: "designbase-navbar__mobile-toggle-line" }), jsxRuntimeExports.jsx("span", { className: "designbase-navbar__mobile-toggle-line" }), jsxRuntimeExports.jsx("span", { className: "designbase-navbar__mobile-toggle-line" })] })] }), isMobileMenuOpen && (jsxRuntimeExports.jsxs("div", { className: "designbase-navbar__mobile-menu", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-navbar__mobile-menu-header", children: [jsxRuntimeExports.jsx("h3", { children: "\uBA54\uB274" }), jsxRuntimeExports.jsx("button", { className: "designbase-navbar__mobile-menu-close", onClick: handleMobileMenuToggle, "aria-label": "\uBA54\uB274 \uB2EB\uAE30", children: jsxRuntimeExports.jsx("i", { className: "designbase-icon-x" }) })] }), showSearch && (jsxRuntimeExports.jsx("div", { className: "designbase-navbar__mobile-search", children: jsxRuntimeExports.jsx(SearchBar, { placeholder: searchPlaceholder, value: searchQuery, onChange: setSearchQuery, onSearch: onSearch, size: "s", variant: "outlined", fullWidth: true }) })), jsxRuntimeExports.jsx("ul", { className: "designbase-navbar__mobile-nav-list", children: items.map((item) => (jsxRuntimeExports.jsxs("li", { className: "designbase-navbar__mobile-nav-item", children: [jsxRuntimeExports.jsxs("a", { href: item.href, className: clsx('designbase-navbar__mobile-nav-link', {
|
|
4661
4720
|
'designbase-navbar__mobile-nav-link--active': item.active,
|
|
4662
4721
|
'designbase-navbar__mobile-nav-link--disabled': item.disabled,
|
|
4663
4722
|
}), onClick: (e) => {
|
|
@@ -4666,7 +4725,7 @@ const Navbar = ({ size = 'md', variant = 'default', position = 'static', logo, o
|
|
|
4666
4725
|
return;
|
|
4667
4726
|
}
|
|
4668
4727
|
handleItemClick(item);
|
|
4669
|
-
}, children: [item.icon && React.createElement(item.icon, { size:
|
|
4728
|
+
}, children: [item.icon && React.createElement(item.icon, { size: iconSize, color: 'currentColor' }), item.label] }), item.children && item.children.length > 0 && (jsxRuntimeExports.jsx("ul", { className: "designbase-navbar__mobile-submenu", children: item.children.map((child) => (jsxRuntimeExports.jsx("li", { children: jsxRuntimeExports.jsxs("a", { href: child.href, className: clsx('designbase-navbar__mobile-submenu-link', {
|
|
4670
4729
|
'designbase-navbar__mobile-submenu-link--active': child.active,
|
|
4671
4730
|
'designbase-navbar__mobile-submenu-link--disabled': child.disabled,
|
|
4672
4731
|
}), onClick: (e) => {
|
|
@@ -4675,7 +4734,7 @@ const Navbar = ({ size = 'md', variant = 'default', position = 'static', logo, o
|
|
|
4675
4734
|
return;
|
|
4676
4735
|
}
|
|
4677
4736
|
handleItemClick(child);
|
|
4678
|
-
}, children: [child.icon && React.createElement(child.icon, { size:
|
|
4737
|
+
}, children: [child.icon && React.createElement(child.icon, { size: iconSize, color: 'currentColor' }), child.label] }) }, child.id))) }))] }, item.id))) }), isAuthenticated && userProfile && (jsxRuntimeExports.jsxs("div", { className: "designbase-navbar__mobile-user", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-navbar__mobile-user-info", children: [userProfile.avatar ? (jsxRuntimeExports.jsx("img", { src: userProfile.avatar, alt: userProfile.name, className: "designbase-navbar__mobile-user-avatar" })) : (jsxRuntimeExports.jsx("div", { className: "designbase-navbar__mobile-user-avatar-placeholder", children: userProfile.name.charAt(0).toUpperCase() })), jsxRuntimeExports.jsxs("div", { children: [jsxRuntimeExports.jsx("div", { className: "designbase-navbar__mobile-user-name", children: userProfile.name }), userProfile.email && (jsxRuntimeExports.jsx("div", { className: "designbase-navbar__mobile-user-email", children: userProfile.email }))] })] }), jsxRuntimeExports.jsx("ul", { className: "designbase-navbar__mobile-user-menu", children: userMenuItems.map((item) => (jsxRuntimeExports.jsx("li", { children: jsxRuntimeExports.jsxs("a", { href: item.href, className: clsx('designbase-navbar__mobile-user-menu-link', {
|
|
4679
4738
|
'designbase-navbar__mobile-user-menu-link--disabled': item.disabled,
|
|
4680
4739
|
}), onClick: (e) => {
|
|
4681
4740
|
if (item.disabled) {
|
|
@@ -4683,11 +4742,11 @@ const Navbar = ({ size = 'md', variant = 'default', position = 'static', logo, o
|
|
|
4683
4742
|
return;
|
|
4684
4743
|
}
|
|
4685
4744
|
handleUserMenuItemClick(item);
|
|
4686
|
-
}, children: [item.icon && React.createElement(item.icon, { size:
|
|
4745
|
+
}, children: [item.icon && React.createElement(item.icon, { size: iconSize, color: 'currentColor' }), item.label] }) }, item.id))) })] }))] }))] }));
|
|
4687
4746
|
};
|
|
4688
4747
|
Navbar.displayName = 'Navbar';
|
|
4689
4748
|
|
|
4690
|
-
const Sidebar = ({ size = '
|
|
4749
|
+
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 }) => {
|
|
4691
4750
|
const [expandedItems, setExpandedItems] = React.useState([]);
|
|
4692
4751
|
const handleToggle = () => {
|
|
4693
4752
|
if (onToggle) {
|
|
@@ -4728,7 +4787,7 @@ const Sidebar = ({ size = 'md', variant = 'default', position = 'left', logo, on
|
|
|
4728
4787
|
const hasChildren = item.children && item.children.length > 0;
|
|
4729
4788
|
return (jsxRuntimeExports.jsx("li", { className: "designbase-sidebar__item", children: jsxRuntimeExports.jsx(MenuItem, { ...item, type: "block", style: "accordion", depth: level, expanded: isExpanded, expandable: hasChildren, onClick: () => handleItemClick(item), onChildClick: (child) => handleItemClick(child) }) }, item.id));
|
|
4730
4789
|
};
|
|
4731
|
-
return (jsxRuntimeExports.jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__container", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__header", children: [jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, children: logo || jsxRuntimeExports.jsx(Logo, { size: size === '
|
|
4790
|
+
return (jsxRuntimeExports.jsx("aside", { className: classes, role: "complementary", "aria-label": "\uC0AC\uC774\uB4DC\uBC14 \uB124\uBE44\uAC8C\uC774\uC158", ...props, children: jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__container", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__header", children: [jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__logo", onClick: onLogoClick, role: onLogoClick ? 'button' : undefined, tabIndex: onLogoClick ? 0 : undefined, children: logo || jsxRuntimeExports.jsx(Logo, { size: size === 's' ? 's' : size === 'l' ? 'l' : 'm' }) }), collapsible && (jsxRuntimeExports.jsx("button", { className: "designbase-sidebar__toggle", onClick: handleToggle, "aria-label": collapsed ? '사이드바 펼치기' : '사이드바 접기', children: jsxRuntimeExports.jsx("i", { className: clsx('designbase-sidebar__toggle-icon', 'designbase-icon-chevron-left', {
|
|
4732
4791
|
'designbase-sidebar__toggle-icon--collapsed': collapsed,
|
|
4733
4792
|
}) }) }))] }), jsxRuntimeExports.jsx("nav", { className: "designbase-sidebar__nav", children: jsxRuntimeExports.jsx("ul", { className: "designbase-sidebar__nav-list", children: items.map((item) => renderSidebarItem(item)) }) }), userProfile && !collapsed && (jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__user", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__user-info", children: [userProfile.avatar ? (jsxRuntimeExports.jsx("img", { src: userProfile.avatar, alt: userProfile.name, className: "designbase-sidebar__user-avatar" })) : (jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__user-avatar-placeholder", children: userProfile.name.charAt(0).toUpperCase() })), jsxRuntimeExports.jsxs("div", { className: "designbase-sidebar__user-details", children: [jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__user-name", children: userProfile.name }), userProfile.email && (jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__user-email", children: userProfile.email })), userProfile.role && (jsxRuntimeExports.jsx("div", { className: "designbase-sidebar__user-role", children: userProfile.role }))] })] }), userMenuItems.length > 0 && (jsxRuntimeExports.jsx("ul", { className: "designbase-sidebar__user-menu", children: userMenuItems.map((item) => (jsxRuntimeExports.jsx("li", { children: jsxRuntimeExports.jsxs("a", { href: item.href, className: clsx('designbase-sidebar__user-menu-link', {
|
|
4734
4793
|
'designbase-sidebar__user-menu-link--disabled': item.disabled,
|
|
@@ -4742,7 +4801,7 @@ const Sidebar = ({ size = 'md', variant = 'default', position = 'left', logo, on
|
|
|
4742
4801
|
};
|
|
4743
4802
|
Sidebar.displayName = 'Sidebar';
|
|
4744
4803
|
|
|
4745
|
-
const Pagination = ({ currentPage, totalPages, totalItems, pageSize = 10, pageSizeOptions = [10, 20, 50, 100], onPageChange, onPageSizeChange, size = '
|
|
4804
|
+
const Pagination = ({ currentPage, totalPages, totalItems, pageSize = 10, pageSizeOptions = [10, 20, 50, 100], onPageChange, onPageSizeChange, size = 'm', variant = 'default', alignment = 'center', siblingCount = 1, boundaryCount = 1, showPreviousNext = true, showFirstLast = false, showPageSizeSelector = false, showTotal = false, totalTemplate, disabled = false, fullWidth = false, className, ...props }) => {
|
|
4746
4805
|
// 페이지 범위 계산
|
|
4747
4806
|
const getPageNumbers = () => {
|
|
4748
4807
|
const totalNumbers = siblingCount * 2 + 3; // 이전, 다음, 현재, 경계 페이지들
|
|
@@ -4820,7 +4879,7 @@ const Pagination = ({ currentPage, totalPages, totalItems, pageSize = 10, pageSi
|
|
|
4820
4879
|
};
|
|
4821
4880
|
Pagination.displayName = 'Pagination';
|
|
4822
4881
|
|
|
4823
|
-
const Breadcrumbs = ({ items, size = '
|
|
4882
|
+
const Breadcrumbs = ({ items, size = 'm', breadcrumbStyle = 'default', separator = jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: 16 }), onItemClick, maxItems, collapseOnMobile = true, className, ...props }) => {
|
|
4824
4883
|
const handleItemClick = (item, e) => {
|
|
4825
4884
|
if (item.disabled || item.active) {
|
|
4826
4885
|
e.preventDefault();
|
|
@@ -4864,7 +4923,7 @@ const Breadcrumbs = ({ items, size = 'md', breadcrumbStyle = 'default', separato
|
|
|
4864
4923
|
};
|
|
4865
4924
|
Breadcrumbs.displayName = 'Breadcrumbs';
|
|
4866
4925
|
|
|
4867
|
-
const Table = ({ data, columns, title, showCountBadge = false, showFilter = false, filterOptions = [], onFilterChange, size = '
|
|
4926
|
+
const Table = ({ data, columns, title, showCountBadge = false, showFilter = false, filterOptions = [], onFilterChange, size = 'm', variant = 'default', selectable = false, multiSelect = false, selectedRows = [], onSelectionChange, sortable = false, sortColumn, sortDirection, onSortChange, loading = false, emptyMessage = '데이터가 없습니다.', onRowClick, rowKey = 'id', height, scrollable = false, className, ...props }) => {
|
|
4868
4927
|
const [internalSelectedRows, setInternalSelectedRows] = React.useState(selectedRows);
|
|
4869
4928
|
const getRowKey = (item, index) => {
|
|
4870
4929
|
if (typeof rowKey === 'string') {
|
|
@@ -4948,7 +5007,7 @@ const Table = ({ data, columns, title, showCountBadge = false, showFilter = fals
|
|
|
4948
5007
|
if (loading) {
|
|
4949
5008
|
return (jsxRuntimeExports.jsx("div", { className: classes, ...props, children: jsxRuntimeExports.jsxs("div", { className: "designbase-table__loading", children: [jsxRuntimeExports.jsx("div", { className: "designbase-table__loading-spinner" }), jsxRuntimeExports.jsx("span", { children: "\uB85C\uB529 \uC911..." })] }) }));
|
|
4950
5009
|
}
|
|
4951
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, style: { height }, ...props, children: [(title || showCountBadge || showFilter) && (jsxRuntimeExports.jsxs("div", { className: "designbase-table__header", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-table__header-left", children: [title && (jsxRuntimeExports.jsx("h3", { className: "designbase-table__title", children: title })), showCountBadge && (jsxRuntimeExports.jsx(Badge, { count: data.length, style: "number", variant: "primary", size: "
|
|
5010
|
+
return (jsxRuntimeExports.jsxs("div", { className: classes, style: { height }, ...props, children: [(title || showCountBadge || showFilter) && (jsxRuntimeExports.jsxs("div", { className: "designbase-table__header", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-table__header-left", children: [title && (jsxRuntimeExports.jsx("h3", { className: "designbase-table__title", children: title })), showCountBadge && (jsxRuntimeExports.jsx(Badge, { count: data.length, style: "number", variant: "primary", size: "s" }))] }), showFilter && filterOptions.length > 0 && (jsxRuntimeExports.jsx("div", { className: "designbase-table__header-right", children: jsxRuntimeExports.jsx(Select, { placeholder: "\uD544\uD130 \uC120\uD0DD", options: filterOptions, onChange: (value) => onFilterChange?.(Array.isArray(value) ? value[0] : value), size: size, showClearButton: false, searchable: false, multiple: false }) }))] })), jsxRuntimeExports.jsx("div", { className: "designbase-table__container", children: jsxRuntimeExports.jsxs("table", { className: tableClasses, children: [jsxRuntimeExports.jsx("thead", { className: "designbase-table__thead", children: jsxRuntimeExports.jsxs("tr", { className: "designbase-table__tr", children: [selectable && (jsxRuntimeExports.jsx("th", { className: "designbase-table__th designbase-table__th--checkbox", children: jsxRuntimeExports.jsx(Checkbox, { isSelected: isAllSelected, isIndeterminate: isIndeterminate, onChange: (checked) => handleSelectAll(checked), size: "s", hasLabel: false }) })), columns.map((column) => (jsxRuntimeExports.jsx("th", { className: clsx('designbase-table__th', {
|
|
4952
5011
|
'designbase-table__th--sortable': sortable && column.sortable,
|
|
4953
5012
|
'designbase-table__th--sorted': sortColumn === column.key,
|
|
4954
5013
|
[`designbase-table__th--${column.align || 'left'}`]: column.align,
|
|
@@ -4960,7 +5019,7 @@ const Table = ({ data, columns, title, showCountBadge = false, showFilter = fals
|
|
|
4960
5019
|
return (jsxRuntimeExports.jsxs("tr", { className: clsx('designbase-table__tr', {
|
|
4961
5020
|
'designbase-table__tr--selected': isSelected,
|
|
4962
5021
|
'designbase-table__tr--clickable': onRowClick,
|
|
4963
|
-
}), onClick: () => onRowClick?.(item, index), children: [selectable && (jsxRuntimeExports.jsx("td", { className: "designbase-table__td designbase-table__td--checkbox", children: jsxRuntimeExports.jsx(Checkbox, { isSelected: isSelected, onChange: (checked) => handleRowSelect(key, checked), size: "
|
|
5022
|
+
}), onClick: () => onRowClick?.(item, index), children: [selectable && (jsxRuntimeExports.jsx("td", { className: "designbase-table__td designbase-table__td--checkbox", children: jsxRuntimeExports.jsx(Checkbox, { isSelected: isSelected, onChange: (checked) => handleRowSelect(key, checked), size: "s", hasLabel: false, onClick: (e) => e.stopPropagation() }) })), columns.map((column) => (jsxRuntimeExports.jsx("td", { className: clsx('designbase-table__td', {
|
|
4964
5023
|
[`designbase-table__td--${column.align || 'left'}`]: column.align,
|
|
4965
5024
|
'designbase-table__td--fixed-left': column.fixed === 'left',
|
|
4966
5025
|
'designbase-table__td--fixed-right': column.fixed === 'right',
|
|
@@ -4969,7 +5028,7 @@ const Table = ({ data, columns, title, showCountBadge = false, showFilter = fals
|
|
|
4969
5028
|
};
|
|
4970
5029
|
Table.displayName = 'Table';
|
|
4971
5030
|
|
|
4972
|
-
const Chip = ({ label, size = '
|
|
5031
|
+
const Chip = ({ label, size = 'm', variant = 'default', color = 'primary', deletable = false, onDelete, onClick, startIcon, endIcon, disabled = false, selected = false, fullWidth = false, className, ...props }) => {
|
|
4973
5032
|
const handleDelete = (e) => {
|
|
4974
5033
|
e.stopPropagation();
|
|
4975
5034
|
if (!disabled && onDelete) {
|
|
@@ -5022,7 +5081,7 @@ const Divider = ({ orientation = 'horizontal', thickness = 1, color, length, var
|
|
|
5022
5081
|
return (jsxRuntimeExports.jsx("div", { className: dividerClasses, style: dividerStyle, role: "separator", "aria-orientation": orientation, ...props }));
|
|
5023
5082
|
};
|
|
5024
5083
|
|
|
5025
|
-
const RangeSlider = ({ value, range, min = 0, max = 100, step = 1, size = '
|
|
5084
|
+
const RangeSlider = ({ value, range, min = 0, max = 100, step = 1, size = 'm', variant = 'default', showValue = false, showMarks = false, marks = [], markLabels = {}, disabled = false, readOnly = false, fullWidth = false, vertical = false, onChange, onRangeChange, className, ...props }) => {
|
|
5026
5085
|
const [internalValue, setInternalValue] = React.useState(value ?? min);
|
|
5027
5086
|
const [internalRange, setInternalRange] = React.useState(range ?? [min, max]);
|
|
5028
5087
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
@@ -5239,7 +5298,7 @@ const RangeSlider = ({ value, range, min = 0, max = 100, step = 1, size = 'md',
|
|
|
5239
5298
|
};
|
|
5240
5299
|
RangeSlider.displayName = 'RangeSlider';
|
|
5241
5300
|
|
|
5242
|
-
const Tooltip = ({ content, children, position = 'top', size = '
|
|
5301
|
+
const Tooltip = ({ content, children, position = 'top', size = 'm', variant = 'default', delay = 200, hideDelay = 0, alwaysShow = false, disabled = false, maxWidth = 200, showArrow = true, className, ...props }) => {
|
|
5243
5302
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
5244
5303
|
const [tooltipStyle, setTooltipStyle] = React.useState({});
|
|
5245
5304
|
const [arrowStyle, setArrowStyle] = React.useState({});
|
|
@@ -5477,7 +5536,7 @@ const Tooltip = ({ content, children, position = 'top', size = 'md', variant = '
|
|
|
5477
5536
|
};
|
|
5478
5537
|
Tooltip.displayName = 'Tooltip';
|
|
5479
5538
|
|
|
5480
|
-
const Popover = ({ content, children, position = 'top', size = '
|
|
5539
|
+
const Popover = ({ content, children, position = 'top', size = 'm', variant = 'default', trigger = 'click', delay = 200, hideDelay = 0, alwaysShow = false, disabled = false, maxWidth = 300, showArrow = true, closeOnOutsideClick = true, closeOnEscape = true, open: controlledOpen, onOpenChange, className, ...props }) => {
|
|
5481
5540
|
const [internalOpen, setInternalOpen] = React.useState(false);
|
|
5482
5541
|
const [popoverStyle, setPopoverStyle] = React.useState({});
|
|
5483
5542
|
const [arrowStyle, setArrowStyle] = React.useState({});
|
|
@@ -5770,7 +5829,7 @@ const Popover = ({ content, children, position = 'top', size = 'md', variant = '
|
|
|
5770
5829
|
};
|
|
5771
5830
|
Popover.displayName = 'Popover';
|
|
5772
5831
|
|
|
5773
|
-
const Alert = ({ title, children, variant = 'info', size = '
|
|
5832
|
+
const Alert = ({ title, children, variant = 'info', size = 'm', showIcon = true, closable = false, actions, actionButtons, onClose, className, ...props }) => {
|
|
5774
5833
|
const [isVisible, setIsVisible] = React.useState(true);
|
|
5775
5834
|
const handleClose = () => {
|
|
5776
5835
|
setIsVisible(false);
|
|
@@ -5779,34 +5838,37 @@ const Alert = ({ title, children, variant = 'info', size = 'md', showIcon = true
|
|
|
5779
5838
|
if (!isVisible) {
|
|
5780
5839
|
return null;
|
|
5781
5840
|
}
|
|
5841
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
5842
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
5782
5843
|
const getIcon = () => {
|
|
5783
5844
|
if (!showIcon)
|
|
5784
5845
|
return null;
|
|
5785
5846
|
const iconProps = {
|
|
5786
|
-
size:
|
|
5847
|
+
size: iconSize,
|
|
5848
|
+
color: 'currentColor',
|
|
5787
5849
|
};
|
|
5788
5850
|
switch (variant) {
|
|
5789
5851
|
case 'info':
|
|
5790
|
-
return jsxRuntimeExports.jsx(icons.
|
|
5852
|
+
return jsxRuntimeExports.jsx(icons.InfoFilledIcon, { ...iconProps });
|
|
5791
5853
|
case 'success':
|
|
5792
|
-
return jsxRuntimeExports.jsx(icons.
|
|
5854
|
+
return jsxRuntimeExports.jsx(icons.CircleCheckFilledIcon, { ...iconProps });
|
|
5793
5855
|
case 'warning':
|
|
5794
|
-
return jsxRuntimeExports.jsx(icons.
|
|
5856
|
+
return jsxRuntimeExports.jsx(icons.WarningFilledIcon, { ...iconProps });
|
|
5795
5857
|
case 'danger':
|
|
5796
|
-
return jsxRuntimeExports.jsx(icons.
|
|
5858
|
+
return jsxRuntimeExports.jsx(icons.ErrorFilledIcon, { ...iconProps });
|
|
5797
5859
|
default:
|
|
5798
|
-
return jsxRuntimeExports.jsx(icons.
|
|
5860
|
+
return jsxRuntimeExports.jsx(icons.InfoFilledIcon, { ...iconProps });
|
|
5799
5861
|
}
|
|
5800
5862
|
};
|
|
5801
5863
|
const classes = clsx('designbase-alert', `designbase-alert--${variant}`, `designbase-alert--${size}`, {
|
|
5802
5864
|
'designbase-alert--with-icon': showIcon,
|
|
5803
5865
|
'designbase-alert--closable': closable,
|
|
5804
5866
|
}, className);
|
|
5805
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, role: "alert", "aria-live": "polite", ...props, children: [jsxRuntimeExports.jsxs("div", { className: "designbase-alert__content", children: [showIcon && (jsxRuntimeExports.jsx("div", { className: "designbase-alert__icon", children: getIcon() })), jsxRuntimeExports.jsxs("div", { className: "designbase-alert__body", children: [title && (jsxRuntimeExports.jsx("div", { className: "designbase-alert__title", children: title })), jsxRuntimeExports.jsx("div", { className: "designbase-alert__message", children: children })] }), closable && (jsxRuntimeExports.jsx("button", { type: "button", className: "designbase-alert__close", onClick: handleClose, "aria-label": "\uC54C\uB9BC \uB2EB\uAE30", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size:
|
|
5867
|
+
return (jsxRuntimeExports.jsxs("div", { className: classes, role: "alert", "aria-live": "polite", ...props, children: [jsxRuntimeExports.jsxs("div", { className: "designbase-alert__content", children: [showIcon && (jsxRuntimeExports.jsx("div", { className: "designbase-alert__icon", children: getIcon() })), jsxRuntimeExports.jsxs("div", { className: "designbase-alert__body", children: [title && (jsxRuntimeExports.jsx("div", { className: "designbase-alert__title", children: title })), jsxRuntimeExports.jsx("div", { className: "designbase-alert__message", children: children })] }), closable && (jsxRuntimeExports.jsx("button", { type: "button", className: "designbase-alert__close", onClick: handleClose, "aria-label": "\uC54C\uB9BC \uB2EB\uAE30", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: iconSize }) }))] }), (actions || actionButtons) && (jsxRuntimeExports.jsx("div", { className: "designbase-alert__actions", children: actionButtons ? (jsxRuntimeExports.jsx("div", { className: "designbase-alert__action-buttons", children: actionButtons.map((action, index) => (jsxRuntimeExports.jsx(Button, { size: action.size || size, variant: action.variant || 'secondary', onClick: action.onClick, disabled: action.disabled, children: action.label }, index))) })) : (actions) }))] }));
|
|
5806
5868
|
};
|
|
5807
5869
|
Alert.displayName = 'Alert';
|
|
5808
5870
|
|
|
5809
|
-
const Confirm = ({ open, title, children, confirmText = '확인', cancelText = '취소', confirmVariant = 'primary', variant = 'info', size = '
|
|
5871
|
+
const Confirm = ({ open, title, children, confirmText = '확인', cancelText = '취소', confirmVariant = 'primary', variant = 'info', size = 'm', showIcon = true, confirmDisabled = false, cancelDisabled = false, onConfirm, onCancel, onClose, closeOnEscape = true, closeOnOverlayClick = true, className, ...props }) => {
|
|
5810
5872
|
const modalRef = React.useRef(null);
|
|
5811
5873
|
// ESC 키 처리
|
|
5812
5874
|
React.useEffect(() => {
|
|
@@ -5882,7 +5944,7 @@ const Confirm = ({ open, title, children, confirmText = '확인', cancelText = '
|
|
|
5882
5944
|
if (!showIcon)
|
|
5883
5945
|
return null;
|
|
5884
5946
|
const iconProps = {
|
|
5885
|
-
size: size === '
|
|
5947
|
+
size: size === 's' ? 20 : size === 'l' ? 32 : 24,
|
|
5886
5948
|
};
|
|
5887
5949
|
switch (variant) {
|
|
5888
5950
|
case 'info':
|
|
@@ -5906,7 +5968,7 @@ const Confirm = ({ open, title, children, confirmText = '확인', cancelText = '
|
|
|
5906
5968
|
};
|
|
5907
5969
|
Confirm.displayName = 'Confirm';
|
|
5908
5970
|
|
|
5909
|
-
const Accordion = ({ items, style = 'default', size = '
|
|
5971
|
+
const Accordion = ({ items, style = 'default', size = 'm', allowMultiple = false, defaultExpandedItems = [], defaultItemType = 'none', onItemChange, className, }) => {
|
|
5910
5972
|
const [expandedItems, setExpandedItems] = React.useState(() => {
|
|
5911
5973
|
if (allowMultiple) {
|
|
5912
5974
|
return defaultExpandedItems;
|
|
@@ -5972,11 +6034,13 @@ const Accordion = ({ items, style = 'default', size = 'md', allowMultiple = fals
|
|
|
5972
6034
|
const classes = clsx('designbase-accordion', `designbase-accordion--${style}`, `designbase-accordion--${size}`, {
|
|
5973
6035
|
'designbase-accordion--multiple': allowMultiple,
|
|
5974
6036
|
}, className);
|
|
6037
|
+
// 아이콘 크기 계산
|
|
6038
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
5975
6039
|
const renderItemPrefix = (item, index) => {
|
|
5976
6040
|
const itemType = item.itemType || defaultItemType;
|
|
5977
6041
|
switch (itemType) {
|
|
5978
6042
|
case 'icon':
|
|
5979
|
-
return item.icon ? (jsxRuntimeExports.jsx("div", { className: "designbase-accordion__icon", children: jsxRuntimeExports.jsx(item.icon, { size:
|
|
6043
|
+
return item.icon ? (jsxRuntimeExports.jsx("div", { className: "designbase-accordion__icon", children: jsxRuntimeExports.jsx(item.icon, { size: iconSize, color: "var(--db-icon-primary)" }) })) : null;
|
|
5980
6044
|
case 'number':
|
|
5981
6045
|
return (jsxRuntimeExports.jsxs("div", { className: "designbase-accordion__number", children: [index + 1, "."] }));
|
|
5982
6046
|
case 'question':
|
|
@@ -5992,7 +6056,7 @@ const Accordion = ({ items, style = 'default', size = 'md', allowMultiple = fals
|
|
|
5992
6056
|
'designbase-accordion__item--expanded': expanded,
|
|
5993
6057
|
'designbase-accordion__item--disabled': item.disabled,
|
|
5994
6058
|
});
|
|
5995
|
-
return (jsxRuntimeExports.jsxs("div", { className: itemClasses, children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "designbase-accordion__trigger", onClick: () => !item.disabled && handleItemToggle(item.id), disabled: item.disabled, "aria-expanded": expanded, "aria-controls": `accordion-content-${item.id}`, children: [renderItemPrefix(item, index), jsxRuntimeExports.jsx("span", { className: "designbase-accordion__title", children: item.title }), jsxRuntimeExports.jsx("div", { className: "designbase-accordion__chevron", children: jsxRuntimeExports.jsx(icons.ChevronDownIcon, { size:
|
|
6059
|
+
return (jsxRuntimeExports.jsxs("div", { className: itemClasses, children: [jsxRuntimeExports.jsxs("button", { type: "button", className: "designbase-accordion__trigger", onClick: () => !item.disabled && handleItemToggle(item.id), disabled: item.disabled, "aria-expanded": expanded, "aria-controls": `accordion-content-${item.id}`, children: [renderItemPrefix(item, index), jsxRuntimeExports.jsx("span", { className: "designbase-accordion__title", children: item.title }), jsxRuntimeExports.jsx("div", { className: "designbase-accordion__chevron", children: jsxRuntimeExports.jsx(icons.ChevronDownIcon, { size: iconSize, color: "var(--db-icon-primary)" }) })] }), jsxRuntimeExports.jsx("div", { id: `accordion-content-${item.id}`, className: "designbase-accordion__content", "aria-hidden": !expanded, children: jsxRuntimeExports.jsx("div", { className: "designbase-accordion__content-inner", children: item.content }) })] }, item.id));
|
|
5996
6060
|
}) }));
|
|
5997
6061
|
};
|
|
5998
6062
|
Accordion.displayName = 'Accordion';
|
|
@@ -6137,7 +6201,7 @@ const useContextMenu = () => {
|
|
|
6137
6201
|
};
|
|
6138
6202
|
};
|
|
6139
6203
|
|
|
6140
|
-
const Textarea = React.forwardRef(({ label, placeholder, defaultValue, value, size = '
|
|
6204
|
+
const Textarea = React.forwardRef(({ label, placeholder, defaultValue, value, size = 'm', rows = 4, maxLength, showCharacterCount = false, characterCountPosition = 'bottom', disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, fullWidth = false, resizable = true, className, textareaClassName, onChange, onFocus, onBlur, ...props }, forwardedRef) => {
|
|
6141
6205
|
const textareaId = React.useId();
|
|
6142
6206
|
const helperTextId = React.useId();
|
|
6143
6207
|
const errorMessageId = React.useId();
|
|
@@ -6177,6 +6241,8 @@ const Image$1 = ({ src, alt = '', ratio = 'auto', fit = 'cover', loading = 'lazy
|
|
|
6177
6241
|
const [currentSrc, setCurrentSrc] = React.useState(src);
|
|
6178
6242
|
const [showPlaceholder, setShowPlaceholder] = React.useState(placeholder !== 'none');
|
|
6179
6243
|
const imageRef = React.useRef(null);
|
|
6244
|
+
// 에러 아이콘 크기 (기본값 m)
|
|
6245
|
+
const errorIconSize = 20;
|
|
6180
6246
|
// src가 변경되면 상태 초기화
|
|
6181
6247
|
React.useEffect(() => {
|
|
6182
6248
|
setCurrentSrc(src);
|
|
@@ -6265,20 +6331,20 @@ const Image$1 = ({ src, alt = '', ratio = 'auto', fit = 'cover', loading = 'lazy
|
|
|
6265
6331
|
const placeholderClasses = clsx('designbase-image__placeholder', `designbase-image__placeholder--${placeholder}`, {
|
|
6266
6332
|
'designbase-image__placeholder--visible': showPlaceholder,
|
|
6267
6333
|
});
|
|
6268
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, style: containerStyle, onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, children: [showPlaceholder && (jsxRuntimeExports.jsxs("div", { className: placeholderClasses, children: [placeholder === 'skeleton' && (jsxRuntimeExports.jsx("div", { className: "designbase-image__skeleton" })), placeholder === 'blur' && (jsxRuntimeExports.jsx("div", { className: "designbase-image__blur" }))] })), imageState === 'error' && (jsxRuntimeExports.jsxs("div", { className: "designbase-image__error", children: [jsxRuntimeExports.jsx(icons.GalleryIcon, { size:
|
|
6334
|
+
return (jsxRuntimeExports.jsxs("div", { className: classes, style: containerStyle, onClick: onClick, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, children: [showPlaceholder && (jsxRuntimeExports.jsxs("div", { className: placeholderClasses, children: [placeholder === 'skeleton' && (jsxRuntimeExports.jsx("div", { className: "designbase-image__skeleton" })), placeholder === 'blur' && (jsxRuntimeExports.jsx("div", { className: "designbase-image__blur" }))] })), imageState === 'error' && (jsxRuntimeExports.jsxs("div", { className: "designbase-image__error", children: [jsxRuntimeExports.jsx(icons.GalleryIcon, { size: errorIconSize, color: "currentColor" }), jsxRuntimeExports.jsx("span", { className: "designbase-image__error-text", children: alt || '이미지를 불러올 수 없습니다' })] })), jsxRuntimeExports.jsx("img", { ref: imageRef, src: currentSrc, alt: alt, loading: loading, className: imageClasses, onLoad: handleLoad, onError: handleError, draggable: false })] }));
|
|
6269
6335
|
};
|
|
6270
6336
|
|
|
6271
|
-
const Container = ({ size = '
|
|
6272
|
-
// 크기별 최대 폭 설정
|
|
6337
|
+
const Container = ({ size = 'l', maxWidth, variant = 'plain', padding = 'm', margin = 'none', backgroundColor, border = false, rounded = false, shadow = false, className, children, }) => {
|
|
6338
|
+
// 크기별 최대 폭 설정 (토큰 기반)
|
|
6273
6339
|
const getMaxWidth = () => {
|
|
6274
6340
|
if (maxWidth)
|
|
6275
6341
|
return maxWidth;
|
|
6276
6342
|
const sizes = {
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
xl:
|
|
6281
|
-
full: 100,
|
|
6343
|
+
s: 'var(--db-container-max-width-s)',
|
|
6344
|
+
m: 'var(--db-container-max-width-m)',
|
|
6345
|
+
l: 'var(--db-container-max-width-l)',
|
|
6346
|
+
xl: 'var(--db-container-max-width-xl)',
|
|
6347
|
+
full: '100%',
|
|
6282
6348
|
};
|
|
6283
6349
|
return sizes[size];
|
|
6284
6350
|
};
|
|
@@ -6288,9 +6354,9 @@ const Container = ({ size = 'lg', maxWidth, variant = 'plain', padding = 'md', m
|
|
|
6288
6354
|
return '';
|
|
6289
6355
|
const paddingClasses = {
|
|
6290
6356
|
none: 'designbase-container--padding-none',
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6357
|
+
s: 'designbase-container--padding-s',
|
|
6358
|
+
m: 'designbase-container--padding-m',
|
|
6359
|
+
l: 'designbase-container--padding-l',
|
|
6294
6360
|
xl: 'designbase-container--padding-xl',
|
|
6295
6361
|
};
|
|
6296
6362
|
return paddingClasses[padding];
|
|
@@ -6301,9 +6367,9 @@ const Container = ({ size = 'lg', maxWidth, variant = 'plain', padding = 'md', m
|
|
|
6301
6367
|
return '';
|
|
6302
6368
|
const marginClasses = {
|
|
6303
6369
|
none: 'designbase-container--margin-none',
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6370
|
+
s: 'designbase-container--margin-s',
|
|
6371
|
+
m: 'designbase-container--margin-m',
|
|
6372
|
+
l: 'designbase-container--margin-l',
|
|
6307
6373
|
xl: 'designbase-container--margin-xl',
|
|
6308
6374
|
};
|
|
6309
6375
|
return marginClasses[margin];
|
|
@@ -6332,7 +6398,7 @@ const Container = ({ size = 'lg', maxWidth, variant = 'plain', padding = 'md', m
|
|
|
6332
6398
|
'designbase-container--border': variant === 'wrapper' && border,
|
|
6333
6399
|
}, className);
|
|
6334
6400
|
const style = {
|
|
6335
|
-
maxWidth:
|
|
6401
|
+
maxWidth: getMaxWidth(),
|
|
6336
6402
|
backgroundColor: variant === 'wrapper' ? backgroundColor : undefined,
|
|
6337
6403
|
};
|
|
6338
6404
|
return (jsxRuntimeExports.jsx("div", { className: classes, style: style, children: children }));
|
|
@@ -6383,7 +6449,7 @@ const GridCol = ({ size, sizeSm, sizeMd, sizeLg, sizeXl, offset = 0, offsetSm =
|
|
|
6383
6449
|
return (jsxRuntimeExports.jsx("div", { className: classes, style: style, children: children }));
|
|
6384
6450
|
};
|
|
6385
6451
|
|
|
6386
|
-
const Form = ({ fields, layout = 'vertical', size = '
|
|
6452
|
+
const Form = ({ fields, layout = 'vertical', size = 'm', variant = 'default', onSubmit, onChange, initialValues = {}, submitText = '제출', submitLoading = false, submitDisabled = false, showReset = false, resetText = '리셋', title, description, className, style, }) => {
|
|
6387
6453
|
const [values, setValues] = React.useState(initialValues);
|
|
6388
6454
|
const [errors, setErrors] = React.useState({});
|
|
6389
6455
|
const [touched, setTouched] = React.useState({});
|
|
@@ -6560,7 +6626,7 @@ const Form = ({ fields, layout = 'vertical', size = 'md', variant = 'default', o
|
|
|
6560
6626
|
return (jsxRuntimeExports.jsxs("form", { ref: formRef, className: classes, style: style, onSubmit: handleSubmit, children: [(title || description) && (jsxRuntimeExports.jsxs("div", { className: "designbase-form__header", children: [title && jsxRuntimeExports.jsx("h3", { className: "designbase-form__title", children: title }), description && jsxRuntimeExports.jsx("p", { className: "designbase-form__description", children: description })] })), jsxRuntimeExports.jsx("div", { className: "designbase-form__fields", children: fields.map(field => (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-form__field-wrapper', `designbase-form__field-wrapper--${field.type}`), children: [field.label && (jsxRuntimeExports.jsxs("label", { className: "designbase-form__label", htmlFor: field.name, children: [field.label, field.required && jsxRuntimeExports.jsx("span", { className: "designbase-form__required", children: "*" })] })), renderField(field), touched[field.name] && errors[field.name] && (jsxRuntimeExports.jsx("div", { className: "designbase-form__error", children: errors[field.name] })), field.helpText && !errors[field.name] && (jsxRuntimeExports.jsx("div", { className: "designbase-form__help", children: field.helpText }))] }, field.name))) }), jsxRuntimeExports.jsxs("div", { className: "designbase-form__actions", children: [jsxRuntimeExports.jsx(Button, { type: "submit", variant: "primary", size: size, loading: submitLoading, disabled: submitDisabled, children: submitText }), showReset && (jsxRuntimeExports.jsx(Button, { type: "button", variant: "secondary", size: size, onClick: handleReset, children: resetText }))] })] }));
|
|
6561
6627
|
};
|
|
6562
6628
|
|
|
6563
|
-
const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant = 'button', size = '
|
|
6629
|
+
const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant = 'button', size = 'm', position = 'bottom', platforms = ['facebook', 'twitter', 'linkedin', 'whatsapp', 'email', 'link'], customPlatforms = {}, buttonText = '공유', buttonIcon = icons.ShareAltIcon, modalTitle = '공유하기', copySuccessMessage = '링크가 클립보드에 복사되었습니다!', showQrCode = true, qrCodeSize = 200, className, style, onShare, onShareError, onCopySuccess, onCopyError, }) => {
|
|
6564
6630
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
6565
6631
|
const [isCopied, setIsCopied] = React.useState(false);
|
|
6566
6632
|
const [qrCodeData, setQrCodeData] = React.useState('');
|
|
@@ -6717,7 +6783,7 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
|
|
|
6717
6783
|
}), style: { '--platform-color': config.color }, onClick: () => handlePlatformShare(platform), title: config.name, "aria-label": `${config.name}에 공유하기`, children: [jsxRuntimeExports.jsx(PlatformIcon, { className: "designbase-share__platform-icon" }), jsxRuntimeExports.jsx("span", { className: "designbase-share__platform-name", children: config.name }), isLinkCopy && isCopied && (jsxRuntimeExports.jsxs("span", { className: "designbase-share__copy-success", children: [jsxRuntimeExports.jsx(icons.CopyIcon, {}), "\uBCF5\uC0AC\uB428!"] }))] }, platform));
|
|
6718
6784
|
};
|
|
6719
6785
|
// 공유 영역 렌더링
|
|
6720
|
-
const renderShareContent = () => (jsxRuntimeExports.jsxs("div", { className: "designbase-share__content", children: [jsxRuntimeExports.jsx("div", { className: "designbase-share__platforms", children: activePlatforms.map(renderPlatformButton) }), showQrCode && qrCodeData && (jsxRuntimeExports.jsxs("div", { className: "designbase-share__qr-section", children: [jsxRuntimeExports.jsx("h4", { className: "designbase-share__qr-title", children: "QR \uCF54\uB4DC" }), jsxRuntimeExports.jsx("div", { className: "designbase-share__qr-code", children: jsxRuntimeExports.jsx("img", { src: generateQrCode(), alt: "QR Code", width: qrCodeSize, height: qrCodeSize }) }), jsxRuntimeExports.jsx("p", { className: "designbase-share__qr-description", children: "QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uC5EC \uB9C1\uD06C\uC5D0 \uC811\uC18D\uD558\uC138\uC694" })] })), jsxRuntimeExports.jsxs("div", { className: "designbase-share__link-preview", children: [jsxRuntimeExports.jsx("h4", { className: "designbase-share__link-title", children: "\uACF5\uC720 \uB9C1\uD06C" }), jsxRuntimeExports.jsxs("div", { className: "designbase-share__link-container", children: [jsxRuntimeExports.jsx("input", { type: "text", value: url, readOnly: true, className: "designbase-share__link-input" }), jsxRuntimeExports.jsx(Button, { size: "
|
|
6786
|
+
const renderShareContent = () => (jsxRuntimeExports.jsxs("div", { className: "designbase-share__content", children: [jsxRuntimeExports.jsx("div", { className: "designbase-share__platforms", children: activePlatforms.map(renderPlatformButton) }), showQrCode && qrCodeData && (jsxRuntimeExports.jsxs("div", { className: "designbase-share__qr-section", children: [jsxRuntimeExports.jsx("h4", { className: "designbase-share__qr-title", children: "QR \uCF54\uB4DC" }), jsxRuntimeExports.jsx("div", { className: "designbase-share__qr-code", children: jsxRuntimeExports.jsx("img", { src: generateQrCode(), alt: "QR Code", width: qrCodeSize, height: qrCodeSize }) }), jsxRuntimeExports.jsx("p", { className: "designbase-share__qr-description", children: "QR \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD558\uC5EC \uB9C1\uD06C\uC5D0 \uC811\uC18D\uD558\uC138\uC694" })] })), jsxRuntimeExports.jsxs("div", { className: "designbase-share__link-preview", children: [jsxRuntimeExports.jsx("h4", { className: "designbase-share__link-title", children: "\uACF5\uC720 \uB9C1\uD06C" }), jsxRuntimeExports.jsxs("div", { className: "designbase-share__link-container", children: [jsxRuntimeExports.jsx("input", { type: "text", value: url, readOnly: true, className: "designbase-share__link-input" }), jsxRuntimeExports.jsx(Button, { size: "s", variant: "primary", onClick: handleCopyLink, className: "designbase-share__copy-button", icon: isCopied ? icons.CopyIcon : icons.LinkIcon, children: isCopied ? '복사됨!' : '복사' })] })] })] }));
|
|
6721
6787
|
// 변형별 렌더링
|
|
6722
6788
|
switch (variant) {
|
|
6723
6789
|
case 'dropdown':
|
|
@@ -6734,7 +6800,7 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
|
|
|
6734
6800
|
position === 'bottom' ? 'bottom-left' :
|
|
6735
6801
|
position === 'left' ? 'top-left' : 'bottom-right', className: "designbase-share__dropdown" }) }));
|
|
6736
6802
|
case 'modal':
|
|
6737
|
-
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [renderShareButton(), jsxRuntimeExports.jsx(Modal, { isOpen: isOpen, onClose: () => setIsOpen(false), title: modalTitle, size: "
|
|
6803
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [renderShareButton(), jsxRuntimeExports.jsx(Modal, { isOpen: isOpen, onClose: () => setIsOpen(false), title: modalTitle, size: "m", className: "designbase-share__modal", children: renderShareContent() })] }));
|
|
6738
6804
|
case 'inline':
|
|
6739
6805
|
return (jsxRuntimeExports.jsx("div", { className: clsx('designbase-share', `designbase-share--${variant}`, className), style: style, children: renderShareContent() }));
|
|
6740
6806
|
default: // button
|
|
@@ -6742,7 +6808,9 @@ const Share = ({ url, title, description = '', imageUrl, hashtags = [], variant
|
|
|
6742
6808
|
}
|
|
6743
6809
|
};
|
|
6744
6810
|
|
|
6745
|
-
const Card = React.forwardRef(({ title, subtitle, description, children, image, icon: Icon, actions = [], tags = [], meta, variant = 'default', size = '
|
|
6811
|
+
const Card = React.forwardRef(({ title, subtitle, description, children, image, icon: Icon, actions = [], tags = [], meta, variant = 'default', size = 'm', layout = 'vertical', imagePosition = 'top', fullWidth = false, clickable = false, hoverable = false, selectable = false, selected = false, disabled = false, loading = false, className, style, onClick, onSelect, onAction, }, ref) => {
|
|
6812
|
+
// 아이콘 크기 계산 (m이 기본값) - 카드에 맞게 조정
|
|
6813
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
|
|
6746
6814
|
const handleClick = () => {
|
|
6747
6815
|
if (!disabled && !loading && onClick) {
|
|
6748
6816
|
onClick();
|
|
@@ -6781,7 +6849,7 @@ const Card = React.forwardRef(({ title, subtitle, description, children, image,
|
|
|
6781
6849
|
const renderIcon = () => {
|
|
6782
6850
|
if (!Icon)
|
|
6783
6851
|
return null;
|
|
6784
|
-
return (jsxRuntimeExports.jsx("div", { className: "designbase-card__icon", children: jsxRuntimeExports.jsx(Icon, { className: "designbase-card__icon-element" }) }));
|
|
6852
|
+
return (jsxRuntimeExports.jsx("div", { className: "designbase-card__icon", children: jsxRuntimeExports.jsx(Icon, { size: iconSize, color: "currentColor", className: "designbase-card__icon-element" }) }));
|
|
6785
6853
|
};
|
|
6786
6854
|
// 태그 렌더링
|
|
6787
6855
|
const renderTags = () => {
|
|
@@ -6801,7 +6869,7 @@ const Card = React.forwardRef(({ title, subtitle, description, children, image,
|
|
|
6801
6869
|
return null;
|
|
6802
6870
|
return (jsxRuntimeExports.jsx("div", { className: "designbase-card__actions", children: actions.map((action, index) => {
|
|
6803
6871
|
const ActionIcon = action.icon;
|
|
6804
|
-
return (jsxRuntimeExports.jsx(Button, { variant: action.variant || 'primary', size: action.size || '
|
|
6872
|
+
return (jsxRuntimeExports.jsx(Button, { variant: action.variant || 'primary', size: action.size || 's', onClick: () => handleActionClick(action, index), disabled: action.disabled || disabled, loading: action.loading, icon: ActionIcon, children: action.label }, index));
|
|
6805
6873
|
}) }));
|
|
6806
6874
|
};
|
|
6807
6875
|
// 카드 내용 렌더링
|
|
@@ -6815,7 +6883,7 @@ const Card = React.forwardRef(({ title, subtitle, description, children, image,
|
|
|
6815
6883
|
});
|
|
6816
6884
|
Card.displayName = 'Card';
|
|
6817
6885
|
|
|
6818
|
-
const Reorder = ({ items, variant = 'default', size = '
|
|
6886
|
+
const Reorder = ({ items, variant = 'default', size = 'm', orientation = 'vertical', showDragHandle = true, showDragIcon = true, selectable = false, multiSelect = false, fullWidth = false, disabled = false, className, style, onReorder, onSelect, onItemClick, onDragStart, onDragEnd, }) => {
|
|
6819
6887
|
const [reorderedItems, setReorderedItems] = React.useState(items);
|
|
6820
6888
|
const [draggedItem, setDraggedItem] = React.useState(null);
|
|
6821
6889
|
const [draggedIndex, setDraggedIndex] = React.useState(-1);
|
|
@@ -7147,7 +7215,7 @@ const SplitView = ({ direction = 'horizontal', mode = 'ratio', initialSplit = 0.
|
|
|
7147
7215
|
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: classes, style: style, children: [jsxRuntimeExports.jsx("div", { className: "designbase-split-view__first", children: first }), jsxRuntimeExports.jsx("div", { ref: splitterRef, className: splitterClasses, onMouseDown: handleMouseDown }), jsxRuntimeExports.jsx("div", { className: "designbase-split-view__second", children: second })] }));
|
|
7148
7216
|
};
|
|
7149
7217
|
|
|
7150
|
-
const Section = ({ title, subtitle, description, size = '
|
|
7218
|
+
const Section = ({ title, subtitle, description, size = 'm', variant = 'default', header, footer, actions, noPadding = false, fullWidth = false, fullHeight = false, className, children, }) => {
|
|
7151
7219
|
const classes = clsx('designbase-section', `designbase-section--size-${size}`, `designbase-section--variant-${variant}`, {
|
|
7152
7220
|
'designbase-section--no-padding': noPadding,
|
|
7153
7221
|
'designbase-section--full-width': fullWidth,
|
|
@@ -7157,7 +7225,7 @@ const Section = ({ title, subtitle, description, size = 'md', variant = 'default
|
|
|
7157
7225
|
return (jsxRuntimeExports.jsxs("section", { className: classes, children: [hasHeader && (jsxRuntimeExports.jsx("div", { className: "designbase-section__header", children: header || (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [(title || subtitle) && (jsxRuntimeExports.jsxs("div", { className: "designbase-section__title-area", children: [title && (jsxRuntimeExports.jsx("h2", { className: "designbase-section__title", children: title })), subtitle && (jsxRuntimeExports.jsx("h3", { className: "designbase-section__subtitle", children: subtitle })), description && (jsxRuntimeExports.jsx("p", { className: "designbase-section__description", children: description }))] })), actions && (jsxRuntimeExports.jsx("div", { className: "designbase-section__actions", children: actions }))] })) })), jsxRuntimeExports.jsx("div", { className: "designbase-section__content", children: children }), footer && (jsxRuntimeExports.jsx("div", { className: "designbase-section__footer", children: footer }))] }));
|
|
7158
7226
|
};
|
|
7159
7227
|
|
|
7160
|
-
const Timeline = ({ items, position = 'alternate', variant = 'default', size = '
|
|
7228
|
+
const Timeline = ({ items, position = 'alternate', variant = 'default', size = 'm', color = 'primary', clickable = false, fullWidth = false, disabled = false, className, style, onItemClick, }) => {
|
|
7161
7229
|
const handleItemClick = (item, index) => {
|
|
7162
7230
|
if (disabled || item.disabled || !clickable)
|
|
7163
7231
|
return;
|
|
@@ -7211,7 +7279,7 @@ const Timeline = ({ items, position = 'alternate', variant = 'default', size = '
|
|
|
7211
7279
|
}) }) }));
|
|
7212
7280
|
};
|
|
7213
7281
|
|
|
7214
|
-
const ProgressStep = ({ items, variant = 'default', size = '
|
|
7282
|
+
const ProgressStep = ({ items, variant = 'default', size = 'm', layout = 'vertical', currentStep = 0, clickable = false, fullWidth = false, disabled = false, className, style, onStepClick, }) => {
|
|
7215
7283
|
const handleStepClick = (item, index) => {
|
|
7216
7284
|
if (disabled || item.disabled || !clickable)
|
|
7217
7285
|
return;
|
|
@@ -7249,7 +7317,7 @@ const ProgressStep = ({ items, variant = 'default', size = 'md', layout = 'verti
|
|
|
7249
7317
|
}) }));
|
|
7250
7318
|
};
|
|
7251
7319
|
|
|
7252
|
-
const Stat = ({ value, label, icon, iconPosition = 'left', size = '
|
|
7320
|
+
const Stat = ({ value, label, icon, iconPosition = 'left', size = 'm', variant = 'default', layout = 'horizontal', color = 'primary', customColor, progress, showProgress = false, change, showChange = false, description, showDescription = false, clickable = false, disabled = false, animated = false, onClick, className, }) => {
|
|
7253
7321
|
// 변화율 텍스트 생성
|
|
7254
7322
|
const getChangeText = () => {
|
|
7255
7323
|
if (!change)
|
|
@@ -7284,7 +7352,7 @@ const Stat = ({ value, label, icon, iconPosition = 'left', size = 'md', variant
|
|
|
7284
7352
|
return (jsxRuntimeExports.jsxs("div", { className: classes, style: customStyle, onClick: handleClick, role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined, children: [icon && (jsxRuntimeExports.jsx("div", { className: clsx('designbase-stat__icon', `designbase-stat__icon--${iconPosition}`), children: icon })), jsxRuntimeExports.jsxs("div", { className: "designbase-stat__content", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-stat__main", children: [jsxRuntimeExports.jsx("div", { className: "designbase-stat__value", children: value }), jsxRuntimeExports.jsx("div", { className: "designbase-stat__label", children: label })] }), showChange && change && (jsxRuntimeExports.jsx("div", { className: clsx('designbase-stat__change', getChangeClass()), children: getChangeText() })), showDescription && description && (jsxRuntimeExports.jsx("div", { className: "designbase-stat__description", children: description }))] }), showProgress && progress !== undefined && (jsxRuntimeExports.jsx("div", { className: "designbase-stat__progress", children: jsxRuntimeExports.jsx("div", { className: "designbase-stat__progress-bar", style: { width: `${Math.min(Math.max(progress, 0), 100)}%` } }) }))] }));
|
|
7285
7353
|
};
|
|
7286
7354
|
|
|
7287
|
-
const Rating = ({ value, maxValue = 5, size = '
|
|
7355
|
+
const Rating = ({ value, maxValue = 5, size = 'm', variant = 'default', type = 'star', display = 'stars', reviewCount, ratingText, reviewText, allowHalf = false, readonly = false, disabled = false, clickable = false, color = 'primary', customColor, animated = false, hoverEffect = true, onChange, onHover, onClick, className, }) => {
|
|
7288
7356
|
const [hoverValue, setHoverValue] = React.useState(null);
|
|
7289
7357
|
const [isHovering, setIsHovering] = React.useState(false);
|
|
7290
7358
|
// 현재 표시할 값 (호버 중이면 호버 값, 아니면 실제 값)
|
|
@@ -7360,7 +7428,7 @@ const Rating = ({ value, maxValue = 5, size = 'md', variant = 'default', type =
|
|
|
7360
7428
|
const starValue = getStarValue(index);
|
|
7361
7429
|
const isClickable = clickable && !disabled && !readonly;
|
|
7362
7430
|
const starProps = {
|
|
7363
|
-
size: size === 'xs' ? 12 : size === '
|
|
7431
|
+
size: size === 'xs' ? 12 : size === 's' ? 16 : size === 'm' ? 20 : size === 'l' ? 24 : 32,
|
|
7364
7432
|
className: clsx('designbase-rating__star', {
|
|
7365
7433
|
'designbase-rating__star--clickable': isClickable,
|
|
7366
7434
|
'designbase-rating__star--animated': animated,
|
|
@@ -7407,7 +7475,7 @@ const Rating = ({ value, maxValue = 5, size = 'md', variant = 'default', type =
|
|
|
7407
7475
|
return (jsxRuntimeExports.jsxs("div", { className: classes, style: customStyle, children: [display === 'stars' || display === 'both' || display === 'detailed' ? (jsxRuntimeExports.jsx("div", { className: "designbase-rating__stars", children: Array.from({ length: 5 }, (_, index) => renderStar(index)) })) : null, display === 'number' || display === 'both' ? (jsxRuntimeExports.jsx("div", { className: "designbase-rating__number-container", children: renderNumberRating() })) : null, display === 'reviews' ? (jsxRuntimeExports.jsx("div", { className: "designbase-rating__reviews", children: renderReviewCount() })) : null, display === 'detailed' ? (renderDetailedInfo()) : null] }));
|
|
7408
7476
|
};
|
|
7409
7477
|
|
|
7410
|
-
const VideoPlayer = ({ src, poster, title, description, size = '
|
|
7478
|
+
const VideoPlayer = ({ src, poster, title, description, size = 'm', variant = 'default', theme = 'auto', autoPlay = false, loop = false, muted = false, showControls = true, enableFullscreen = true, enableKeyboard = true, enableTouch = 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, qualities = [], defaultQuality = '', subtitles = [], defaultSubtitle = '', onPlay, onPause, onEnded, onTimeUpdate, onVolumeChange, onFullscreenChange, onPlaylistChange, onPlaybackRateChange, onQualityChange, onSubtitleChange, onError, className, }) => {
|
|
7411
7479
|
const videoRef = React.useRef(null);
|
|
7412
7480
|
const containerRef = React.useRef(null);
|
|
7413
7481
|
const progressRef = React.useRef(null);
|
|
@@ -7651,7 +7719,7 @@ const VideoPlayer = ({ src, poster, title, description, size = 'md', variant = '
|
|
|
7651
7719
|
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: classes, onMouseEnter: () => setShowControlsOverlay(true), onMouseLeave: () => setShowControlsOverlay(false), children: [jsxRuntimeExports.jsxs("video", { ref: videoRef, src: currentSrc, poster: poster, autoPlay: autoPlay, loop: loop, muted: muted, playsInline: true, className: "designbase-video-player__video", children: [subtitles.map((subtitle, index) => (jsxRuntimeExports.jsx("track", { kind: "subtitles", src: subtitle.src, srcLang: subtitle.lang, label: subtitle.label, default: subtitle.label === currentSubtitle }, index))), "\uBE44\uB514\uC624\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uBE0C\uB77C\uC6B0\uC800\uC785\uB2C8\uB2E4."] }), isLoading && (jsxRuntimeExports.jsx("div", { className: "designbase-video-player__loading", children: jsxRuntimeExports.jsx("div", { className: "designbase-video-player__spinner" }) })), error && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__error", children: [jsxRuntimeExports.jsx("p", { children: error }), jsxRuntimeExports.jsx("button", { onClick: () => window.location.reload(), children: "\uB2E4\uC2DC \uC2DC\uB3C4" })] })), showControls && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__overlay", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__top-controls", children: [title && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__title", children: [jsxRuntimeExports.jsx("h3", { children: title }), description && jsxRuntimeExports.jsx("p", { children: description })] })), showSettings && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__settings", children: [jsxRuntimeExports.jsx("button", { className: "designbase-video-player__settings-button", onClick: () => setShowSettingsMenu(!showSettingsMenu), children: jsxRuntimeExports.jsx(icons.SettingsIcon, { size: 20 }) }), showSettingsMenu && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__settings-menu", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__setting-group", children: [jsxRuntimeExports.jsx("label", { children: "\uC7AC\uC0DD \uC18D\uB3C4" }), jsxRuntimeExports.jsx("select", { value: playbackRate, onChange: (e) => handlePlaybackRateChange(parseFloat(e.target.value)), children: playbackRates.map(rate => (jsxRuntimeExports.jsxs("option", { value: rate, children: [rate, "x"] }, rate))) })] }), qualities.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__setting-group", children: [jsxRuntimeExports.jsx("label", { children: "\uD488\uC9C8" }), jsxRuntimeExports.jsx("select", { value: currentQuality, onChange: (e) => handleQualityChange(e.target.value), children: qualities.map(quality => (jsxRuntimeExports.jsx("option", { value: quality.value, children: quality.label }, quality.value))) })] })), subtitles.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__setting-group", children: [jsxRuntimeExports.jsx("label", { children: "\uC790\uB9C9" }), jsxRuntimeExports.jsxs("select", { value: currentSubtitle, onChange: (e) => handleSubtitleChange(e.target.value), children: [jsxRuntimeExports.jsx("option", { value: "", children: "\uC790\uB9C9 \uC5C6\uC74C" }), subtitles.map(subtitle => (jsxRuntimeExports.jsx("option", { value: subtitle.label, children: subtitle.label }, subtitle.label)))] })] }))] }))] }))] }), jsxRuntimeExports.jsx("div", { className: "designbase-video-player__center-controls", children: jsxRuntimeExports.jsx("button", { className: "designbase-video-player__play-button", onClick: togglePlay, children: isPlaying ? jsxRuntimeExports.jsx(icons.PauseIcon, { size: 48 }) : jsxRuntimeExports.jsx(icons.PlayIcon, { size: 48 }) }) }), jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__bottom-controls", children: [showProgress && (jsxRuntimeExports.jsxs("div", { ref: progressRef, className: "designbase-video-player__progress", onClick: handleProgressChange, children: [jsxRuntimeExports.jsx("div", { className: "designbase-video-player__progress-bar", style: { width: `${progressPercentage}%` } }), jsxRuntimeExports.jsx("div", { className: "designbase-video-player__progress-handle", style: { left: `${progressPercentage}%` } })] })), jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__controls", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__left-controls", children: [jsxRuntimeExports.jsx("button", { className: "designbase-video-player__control-button", onClick: togglePlay, children: isPlaying ? jsxRuntimeExports.jsx(icons.PauseIcon, { size: 20 }) : jsxRuntimeExports.jsx(icons.PlayIcon, { size: 20 }) }), showVolume && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__volume", children: [jsxRuntimeExports.jsx("button", { className: "designbase-video-player__control-button", onClick: toggleMute, onMouseEnter: () => setShowVolumeSlider(true), onMouseLeave: () => setShowVolumeSlider(false), children: isMuted || volume === 0 ? jsxRuntimeExports.jsx(icons.MuteFilledIcon, { size: 20 }) : jsxRuntimeExports.jsx(icons.VolumeUpIcon, { size: 20 }) }), showVolumeSlider && (jsxRuntimeExports.jsx("div", { ref: volumeRef, className: "designbase-video-player__volume-slider", children: jsxRuntimeExports.jsx("input", { type: "range", min: "0", max: "1", step: "0.1", value: volume, onChange: handleVolumeSliderChange }) }))] })), showTime && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__time", children: [jsxRuntimeExports.jsx("span", { children: formatTime(currentTime) }), jsxRuntimeExports.jsx("span", { children: "/" }), jsxRuntimeExports.jsx("span", { children: formatTime(duration) })] }))] }), jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__right-controls", children: [playlist.length > 1 && (jsxRuntimeExports.jsxs("div", { className: "designbase-video-player__playlist-controls", children: [jsxRuntimeExports.jsx("button", { className: "designbase-video-player__control-button", disabled: playlistIndex === 0, onClick: () => handlePlaylistChange(playlistIndex - 1), children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: 16 }) }), jsxRuntimeExports.jsxs("span", { children: [playlistIndex + 1, " / ", playlist.length] }), jsxRuntimeExports.jsx("button", { className: "designbase-video-player__control-button", disabled: playlistIndex === playlist.length - 1, onClick: () => handlePlaylistChange(playlistIndex + 1), children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: 16 }) })] })), enableFullscreen && (jsxRuntimeExports.jsx("button", { className: "designbase-video-player__control-button", onClick: toggleFullscreen, children: isFullscreen ? jsxRuntimeExports.jsx(icons.ShrinkIcon, { size: 20 }) : jsxRuntimeExports.jsx(icons.ExpandIcon, { size: 20 }) }))] })] })] })] }))] }));
|
|
7652
7720
|
};
|
|
7653
7721
|
|
|
7654
|
-
const AudioPlayer = ({ src, title, artist, album, albumArt, size = '
|
|
7722
|
+
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, }) => {
|
|
7655
7723
|
const audioRef = React.useRef(null);
|
|
7656
7724
|
const progressRef = React.useRef(null);
|
|
7657
7725
|
const volumeRef = React.useRef(null);
|
|
@@ -7669,6 +7737,8 @@ const AudioPlayer = ({ src, title, artist, album, albumArt, size = 'md', variant
|
|
|
7669
7737
|
const [error, setError] = React.useState(null);
|
|
7670
7738
|
const [playlistIndex, setPlaylistIndex] = React.useState(currentIndex);
|
|
7671
7739
|
const [shuffledPlaylist, setShuffledPlaylist] = React.useState([]);
|
|
7740
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
7741
|
+
const iconSize = size === 's' ? 16 : size === 'm' ? 20 : size === 'l' ? 24 : 32; // xl은 32
|
|
7672
7742
|
// 셔플된 플레이리스트 인덱스 생성
|
|
7673
7743
|
React.useEffect(() => {
|
|
7674
7744
|
if (playlist.length > 0 && isShuffle) {
|
|
@@ -7936,12 +8006,12 @@ const AudioPlayer = ({ src, title, artist, album, albumArt, size = 'md', variant
|
|
|
7936
8006
|
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsx("audio", { ref: audioRef, src: currentSrc, autoPlay: autoPlay, loop: loop, muted: muted, preload: "metadata" }), isLoading && (jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__loading", children: jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__spinner" }) })), error && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__error", children: [jsxRuntimeExports.jsx("p", { children: error }), jsxRuntimeExports.jsx("button", { onClick: () => window.location.reload(), children: "\uB2E4\uC2DC \uC2DC\uB3C4" })] })), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__album-art", children: [currentTrack?.albumArt ? (jsxRuntimeExports.jsx("img", { src: currentTrack.albumArt, alt: currentTrack.title || 'Album Art', onError: (e) => {
|
|
7937
8007
|
e.currentTarget.style.display = 'none';
|
|
7938
8008
|
e.currentTarget.nextElementSibling?.classList.remove('album-placeholder');
|
|
7939
|
-
} })) : null, jsxRuntimeExports.jsx("div", { className: "album-placeholder", children: "\uD83C\uDFB5" })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__main", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__info", children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__title", children: currentTrack?.title || 'Unknown Track' }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__artist", children: currentTrack?.artist || 'Unknown Artist' }), currentTrack?.album && (jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__album", children: currentTrack.album }))] }), showProgress && (jsxRuntimeExports.jsxs("div", { ref: progressRef, className: "designbase-audio-player__progress", onClick: handleProgressChange, children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__progress-bar", style: { width: `${progressPercentage}%` } }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__progress-handle", style: { left: `${progressPercentage}%` } })] })), showControls && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__controls", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__left-controls", children: [playlist.length > 0 && (jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: toggleShuffle, children: jsxRuntimeExports.jsx(icons.RefreshIcon, { size:
|
|
8009
|
+
} })) : null, jsxRuntimeExports.jsx("div", { className: "album-placeholder", children: "\uD83C\uDFB5" })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__main", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__info", children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__title", children: currentTrack?.title || 'Unknown Track' }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__artist", children: currentTrack?.artist || 'Unknown Artist' }), currentTrack?.album && (jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__album", children: currentTrack.album }))] }), showProgress && (jsxRuntimeExports.jsxs("div", { ref: progressRef, className: "designbase-audio-player__progress", onClick: handleProgressChange, children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__progress-bar", style: { width: `${progressPercentage}%` } }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__progress-handle", style: { left: `${progressPercentage}%` } })] })), showControls && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__controls", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__left-controls", children: [playlist.length > 0 && (jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: toggleShuffle, children: jsxRuntimeExports.jsx(icons.RefreshIcon, { size: iconSize }) })), jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: handlePrevious, disabled: playlist.length > 0 && playlistIndex === 0, children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: iconSize }) })] }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__center-controls", children: jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__play-button", onClick: togglePlay, children: isPlaying ? jsxRuntimeExports.jsx(icons.PauseIcon, { size: iconSize * 1.2 }) : jsxRuntimeExports.jsx(icons.PlayIcon, { size: iconSize * 1.2 }) }) }), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__right-controls", children: [jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: handleNext, disabled: playlist.length > 0 && playlistIndex === playlist.length - 1, children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: iconSize }) }), playlist.length > 0 && (jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: toggleRepeatMode, children: jsxRuntimeExports.jsx(icons.RepeatIcon, { size: iconSize }) }))] })] })), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__bottom-controls", children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__left-bottom", children: showTime && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__time", children: [jsxRuntimeExports.jsx("span", { children: formatTime(currentTime) }), jsxRuntimeExports.jsx("span", { children: "/" }), jsxRuntimeExports.jsx("span", { children: formatTime(duration) })] })) }), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__right-bottom", children: [showVolume && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__volume", children: [jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: toggleMute, title: isMuted || volume === 0 ? '음소거 해제' : '음소거', children: isMuted || volume === 0 ? jsxRuntimeExports.jsx(icons.MuteFilledIcon, { size: iconSize }) : jsxRuntimeExports.jsx(icons.VolumeUpIcon, { size: iconSize }) }), jsxRuntimeExports.jsxs("div", { ref: volumeRef, className: "designbase-audio-player__volume-slider", children: [jsxRuntimeExports.jsxs("div", { className: "volume-label", children: [jsxRuntimeExports.jsx("span", { children: "\uD83D\uDD0A" }), jsxRuntimeExports.jsxs("span", { children: [Math.round(volume * 100), "%"] })] }), jsxRuntimeExports.jsx("input", { type: "range", min: "0", max: "1", step: "0.1", value: volume, onChange: handleVolumeSliderChange })] })] })), showSettings && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__settings", children: [jsxRuntimeExports.jsx("button", { className: "designbase-audio-player__control-button", onClick: () => setShowSettingsMenu(!showSettingsMenu), children: jsxRuntimeExports.jsx(icons.SettingsIcon, { size: iconSize }) }), showSettingsMenu && (jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__settings-menu", children: jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__setting-group", children: [jsxRuntimeExports.jsx("label", { children: "\uC7AC\uC0DD \uC18D\uB3C4" }), jsxRuntimeExports.jsx("select", { value: playbackRate, onChange: (e) => handlePlaybackRateChange(parseFloat(e.target.value)), children: playbackRates.map(rate => (jsxRuntimeExports.jsxs("option", { value: rate, children: [rate, "x"] }, rate))) })] }) }))] }))] })] })] }), variant === 'full' && playlist.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__playlist", children: [jsxRuntimeExports.jsx("h4", { children: "\uD50C\uB808\uC774\uB9AC\uC2A4\uD2B8" }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__playlist-tracks", children: playlist.map((track, index) => (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-audio-player__playlist-track', {
|
|
7940
8010
|
'designbase-audio-player__playlist-track--active': index === playlistIndex
|
|
7941
8011
|
}), onClick: () => handlePlaylistChange(index), children: [track.albumArt && (jsxRuntimeExports.jsx("img", { src: track.albumArt, alt: track.title || 'Album Art' })), jsxRuntimeExports.jsxs("div", { className: "designbase-audio-player__playlist-track-info", children: [jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__playlist-track-title", children: track.title || 'Unknown Track' }), jsxRuntimeExports.jsx("div", { className: "designbase-audio-player__playlist-track-artist", children: track.artist || 'Unknown Artist' })] })] }, index))) })] }))] }));
|
|
7942
8012
|
};
|
|
7943
8013
|
|
|
7944
|
-
const Dropzone = ({ size = '
|
|
8014
|
+
const Dropzone = ({ size = 'm', variant = 'default', showIcon = true, icon, image, title = '파일을 드래그하여 업로드하거나 클릭하여 선택하세요', description, buttonText = '파일 선택', showButton = false, accept, maxSize, multiple = false, isDragOver: controlledIsDragOver, disabled = false, readonly = false, onFileSelect, onDragOver, onDragLeave, onDrop, onClick, className, children, }) => {
|
|
7945
8015
|
const [internalIsDragOver, setInternalIsDragOver] = React.useState(false);
|
|
7946
8016
|
const fileInputRef = React.useRef(null);
|
|
7947
8017
|
// 드래그 오버 상태 관리
|
|
@@ -8056,7 +8126,7 @@ const Dropzone = ({ size = 'md', variant = 'default', showIcon = true, icon, ima
|
|
|
8056
8126
|
}, className), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, onClick: handleClick, children: [jsxRuntimeExports.jsx("input", { ref: fileInputRef, type: "file", accept: accept, multiple: multiple, onChange: handleFileInputChange, disabled: disabled || readonly, style: { display: 'none' } }), children || (jsxRuntimeExports.jsxs("div", { className: "designbase-dropzone__content", children: [image ? (jsxRuntimeExports.jsx("div", { className: "designbase-dropzone__image", children: jsxRuntimeExports.jsx("img", { src: image, alt: "Upload illustration" }) })) : showIcon && (jsxRuntimeExports.jsx("div", { className: "designbase-dropzone__icon", children: icon || defaultIcon })), title && (jsxRuntimeExports.jsx("div", { className: "designbase-dropzone__title", children: title })), getDescription() && (jsxRuntimeExports.jsx("div", { className: "designbase-dropzone__description", children: getDescription() })), showButton && (jsxRuntimeExports.jsx("button", { className: "designbase-dropzone__button", type: "button", disabled: disabled || readonly, children: buttonText }))] }))] }));
|
|
8057
8127
|
};
|
|
8058
8128
|
|
|
8059
|
-
const FileUploader = ({ size = '
|
|
8129
|
+
const FileUploader = ({ size = 'm', variant = 'default', accept, maxSize, multiple = false, showFileList = true, showProgress = true, disabled = false, readonly = false, onUpload, onRemove, onRetry, className, }) => {
|
|
8060
8130
|
const [uploadedFiles, setUploadedFiles] = React.useState([]);
|
|
8061
8131
|
const [isUploading, setIsUploading] = React.useState(false);
|
|
8062
8132
|
// 파일 선택 처리
|
|
@@ -8152,7 +8222,7 @@ const FileUploader = ({ size = 'md', variant = 'default', accept, maxSize, multi
|
|
|
8152
8222
|
case 'pending':
|
|
8153
8223
|
return (jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: jsxRuntimeExports.jsx("circle", { cx: "8", cy: "8", r: "7", stroke: "currentColor", strokeWidth: "2", fill: "none" }) }));
|
|
8154
8224
|
case 'uploading':
|
|
8155
|
-
return jsxRuntimeExports.jsx(Spinner, { type: "circular", size: "
|
|
8225
|
+
return jsxRuntimeExports.jsx(Spinner, { type: "circular", size: "s" });
|
|
8156
8226
|
case 'success':
|
|
8157
8227
|
return (jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: jsxRuntimeExports.jsx("path", { d: "M13 5L6 12L3 9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
8158
8228
|
case 'error':
|
|
@@ -8164,10 +8234,10 @@ const FileUploader = ({ size = 'md', variant = 'default', accept, maxSize, multi
|
|
|
8164
8234
|
return (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-file-uploader', `designbase-file-uploader--size-${size}`, `designbase-file-uploader--variant-${variant}`, {
|
|
8165
8235
|
'designbase-file-uploader--disabled': disabled,
|
|
8166
8236
|
'designbase-file-uploader--readonly': readonly,
|
|
8167
|
-
}, className), children: [jsxRuntimeExports.jsx(Dropzone, { size: size, variant: variant, accept: accept, maxSize: maxSize, multiple: multiple, disabled: disabled, readonly: readonly, onFileSelect: handleFileSelect }), showFileList && uploadedFiles.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-list", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-list-title", children: ["\uC5C5\uB85C\uB4DC\uB41C \uD30C\uC77C\uB4E4 (", uploadedFiles.length, "\uAC1C)"] }), jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-items", children: uploadedFiles.map((uploadFile) => (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-file-uploader__file-item', `designbase-file-uploader__file-item--${uploadFile.status}`), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-info", children: [jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-icon", children: getStatusIcon(uploadFile.status) }), jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-details", children: [jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-name", children: uploadFile.file.name }), jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-size", children: formatFileSize(uploadFile.file.size) }), uploadFile.error && (jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-error", children: uploadFile.error }))] })] }), showProgress && uploadFile.status === 'uploading' && (jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__progress", children: jsxRuntimeExports.jsx(Progressbar, { value: uploadFile.progress || 0, size: "
|
|
8237
|
+
}, className), children: [jsxRuntimeExports.jsx(Dropzone, { size: size, variant: variant, accept: accept, maxSize: maxSize, multiple: multiple, disabled: disabled, readonly: readonly, onFileSelect: handleFileSelect }), showFileList && uploadedFiles.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-list", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-list-title", children: ["\uC5C5\uB85C\uB4DC\uB41C \uD30C\uC77C\uB4E4 (", uploadedFiles.length, "\uAC1C)"] }), jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-items", children: uploadedFiles.map((uploadFile) => (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-file-uploader__file-item', `designbase-file-uploader__file-item--${uploadFile.status}`), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-info", children: [jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-icon", children: getStatusIcon(uploadFile.status) }), jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-details", children: [jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-name", children: uploadFile.file.name }), jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-size", children: formatFileSize(uploadFile.file.size) }), uploadFile.error && (jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__file-error", children: uploadFile.error }))] })] }), showProgress && uploadFile.status === 'uploading' && (jsxRuntimeExports.jsx("div", { className: "designbase-file-uploader__progress", children: jsxRuntimeExports.jsx(Progressbar, { value: uploadFile.progress || 0, size: "s", variant: "primary", style: "solid", showLabel: true, labelPosition: "inside", fullWidth: true }) })), jsxRuntimeExports.jsxs("div", { className: "designbase-file-uploader__file-actions", children: [uploadFile.status === 'error' && (jsxRuntimeExports.jsx("button", { className: "designbase-file-uploader__retry-button", onClick: () => handleRetry(uploadFile.id), disabled: disabled || readonly, type: "button", children: "\uC7AC\uC2DC\uB3C4" })), jsxRuntimeExports.jsx("button", { className: "designbase-file-uploader__remove-button", onClick: () => handleRemove(uploadFile.id), disabled: disabled || readonly, type: "button", children: "\uC0AD\uC81C" })] })] }, uploadFile.id))) })] }))] }));
|
|
8168
8238
|
};
|
|
8169
8239
|
|
|
8170
|
-
const Progress = ({ value, max = 100, size = '
|
|
8240
|
+
const Progress = ({ value, max = 100, size = 'm', variant = 'default', type = 'linear', showValue = false, valueFormatter, animated = false, striped = false, className, }) => {
|
|
8171
8241
|
const percentage = Math.min(Math.max((value / max) * 100, 0), 100);
|
|
8172
8242
|
const classes = clsx('designbase-progress', `designbase-progress--size-${size}`, `designbase-progress--variant-${variant}`, `designbase-progress--type-${type}`, {
|
|
8173
8243
|
'designbase-progress--animated': animated,
|
|
@@ -8185,7 +8255,7 @@ const Progress = ({ value, max = 100, size = 'md', variant = 'default', type = '
|
|
|
8185
8255
|
return (jsxRuntimeExports.jsx("div", { className: classes, children: type === 'linear' ? renderLinearProgress() : renderCircularProgress() }));
|
|
8186
8256
|
};
|
|
8187
8257
|
|
|
8188
|
-
const Stepper = ({ value = 0, min = 0, max = 100, step = 1, size = '
|
|
8258
|
+
const Stepper = ({ value = 0, min = 0, max = 100, step = 1, size = 'm', variant = 'default', disabled = false, readonly = false, onChange, onMinReached, onMaxReached, className, }) => {
|
|
8189
8259
|
const [internalValue, setInternalValue] = React.useState(value);
|
|
8190
8260
|
const currentValue = value !== undefined ? value : internalValue;
|
|
8191
8261
|
const isMinReached = currentValue <= min;
|
|
@@ -8253,7 +8323,7 @@ const Stepper = ({ value = 0, min = 0, max = 100, step = 1, size = 'md', variant
|
|
|
8253
8323
|
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsx("button", { type: "button", className: decrementClasses, onClick: handleDecrement, disabled: disabled || readonly || isMinReached, "aria-label": "\uAC10\uC18C", "aria-describedby": "stepper-description", children: jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) }) }), jsxRuntimeExports.jsx("div", { className: "designbase-stepper__value", children: jsxRuntimeExports.jsx("span", { className: "designbase-stepper__value-text", children: currentValue }) }), jsxRuntimeExports.jsx("button", { type: "button", className: incrementClasses, onClick: handleIncrement, disabled: disabled || readonly || isMaxReached, "aria-label": "\uC99D\uAC00", "aria-describedby": "stepper-description", children: jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }) }), jsxRuntimeExports.jsxs("div", { id: "stepper-description", className: "sr-only", children: ["\uC22B\uC790 \uC870\uC815\uAE30. \uD654\uC0B4\uD45C \uD0A4\uB098 +/- \uD0A4\uB97C \uC0AC\uC6A9\uD558\uC5EC \uAC12\uC744 \uC870\uC815\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uD604\uC7AC \uAC12: ", currentValue, ", \uCD5C\uC18C\uAC12: ", min, ", \uCD5C\uB300\uAC12: ", max, ", \uB2E8\uACC4: ", step] })] }));
|
|
8254
8324
|
};
|
|
8255
8325
|
|
|
8256
|
-
const Gradient = ({ colors, direction = 'to-right', size = '
|
|
8326
|
+
const Gradient = ({ colors, direction = 'to-right', size = 'm', variant = 'default', animationDuration = 3, animationDelay = 0, fullWidth = false, fullHeight = false, className, children, }) => {
|
|
8257
8327
|
const generateGradientStyle = () => {
|
|
8258
8328
|
if (colors.length === 0)
|
|
8259
8329
|
return {};
|
|
@@ -8346,7 +8416,7 @@ const Gradient = ({ colors, direction = 'to-right', size = 'md', variant = 'defa
|
|
|
8346
8416
|
return (jsxRuntimeExports.jsx("div", { className: classes, style: getStyle(), children: children }));
|
|
8347
8417
|
};
|
|
8348
8418
|
|
|
8349
|
-
const Toolbar = ({ items, size = '
|
|
8419
|
+
const Toolbar = ({ items, size = 'm', variant = 'default', position = 'top', fullWidth = false, fixed = false, shadow = true, rounded = true, className, children, }) => {
|
|
8350
8420
|
const [openDropdown, setOpenDropdown] = React.useState(null);
|
|
8351
8421
|
const handleItemClick = (item) => {
|
|
8352
8422
|
if (item.disabled)
|
|
@@ -8405,7 +8475,7 @@ const Toolbar = ({ items, size = 'md', variant = 'default', position = 'top', fu
|
|
|
8405
8475
|
return (jsxRuntimeExports.jsx("div", { className: classes, children: jsxRuntimeExports.jsxs("div", { className: "designbase-toolbar__content", children: [Object.entries(groupedItems).map(([groupName, groupItems], groupIndex) => (jsxRuntimeExports.jsxs("div", { className: "designbase-toolbar__group", children: [groupItems.map(renderItem), groupIndex < Object.keys(groupedItems).length - 1 && (jsxRuntimeExports.jsx("div", { className: "designbase-toolbar__group-separator" }))] }, groupName))), children && (jsxRuntimeExports.jsx("div", { className: "designbase-toolbar__children", children: children }))] }) }));
|
|
8406
8476
|
};
|
|
8407
8477
|
|
|
8408
|
-
const TimePicker = ({ value, onChange, format = '24h', mode = 'dropdown', hourStep = 1, minuteStep = 15, minTime, maxTime, size = '
|
|
8478
|
+
const TimePicker = ({ value, onChange, format = '24h', mode = 'dropdown', hourStep = 1, minuteStep = 15, minTime, maxTime, size = 'm', variant = 'default', disabled = false, readonly = false, placeholder = '시간을 선택하세요', displayFormat, className, }) => {
|
|
8409
8479
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
8410
8480
|
const [selectedHour, setSelectedHour] = React.useState(() => {
|
|
8411
8481
|
if (value) {
|
|
@@ -8598,11 +8668,13 @@ const TimePicker = ({ value, onChange, format = '24h', mode = 'dropdown', hourSt
|
|
|
8598
8668
|
}) })] }))] }) }))] }));
|
|
8599
8669
|
};
|
|
8600
8670
|
|
|
8601
|
-
const DatePicker = ({ mode = 'single', value, onChange, minDate, maxDate, events = [], showOutsideDays = true, startOfWeek = 'sunday', size = '
|
|
8671
|
+
const DatePicker = ({ mode = 'single', value, onChange, minDate, maxDate, events = [], showOutsideDays = true, startOfWeek = 'sunday', size = 'm', variant = 'default', highlightWeekends = true, highlightHolidays = false, today = new Date(), locale = 'ko-KR', format = 'yyyy-MM-dd', className, disabled = false, readonly = false,
|
|
8602
8672
|
// 드롭다운 관련 props
|
|
8603
8673
|
isOpen: controlledIsOpen, onOpenChange, trigger, placement = 'bottom',
|
|
8604
8674
|
// 인라인 모드
|
|
8605
8675
|
inline = false, }) => {
|
|
8676
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
8677
|
+
const iconSize = size === 's' ? 14 : size === 'l' ? 18 : 16;
|
|
8606
8678
|
const [currentDate, setCurrentDate] = React.useState(new Date());
|
|
8607
8679
|
const [hoveredDate, setHoveredDate] = React.useState(null);
|
|
8608
8680
|
const [internalIsOpen, setInternalIsOpen] = React.useState(false);
|
|
@@ -8849,16 +8921,16 @@ inline = false, }) => {
|
|
|
8849
8921
|
return (jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "designbase-date-picker-container", children: [jsxRuntimeExports.jsx("div", { onClick: () => !disabled && !readonly && setIsOpen(!isOpen), children: trigger }), isOpen && (jsxRuntimeExports.jsx("div", { className: clsx('designbase-date-picker-dropdown', `designbase-date-picker-dropdown--placement-${placement}`), children: jsxRuntimeExports.jsxs("div", { className: clsx('designbase-date-picker', `designbase-date-picker--size-${size}`, `designbase-date-picker--variant-${variant}`, {
|
|
8850
8922
|
'designbase-date-picker--disabled': disabled,
|
|
8851
8923
|
'designbase-date-picker--readonly': readonly,
|
|
8852
|
-
}, className), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-date-picker__header", children: [jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToPreviousMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uC774\uC804 \uB2EC", children: jsxRuntimeExports.jsx(
|
|
8924
|
+
}, className), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-date-picker__header", children: [jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToPreviousMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uC774\uC804 \uB2EC", children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: iconSize, color: "currentColor" }) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__current-month", children: currentDate.toLocaleDateString(locale, { year: 'numeric', month: 'long' }) }), jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToNextMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uB2E4\uC74C \uB2EC", children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: iconSize, color: "currentColor" }) })] }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__weekdays", children: weekdays.map(day => (jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__weekday", children: day }, day))) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__grid", children: calendarGrid.map(date => renderDateCell(date)) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__footer", children: jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__today-button", onClick: goToToday, disabled: disabled || readonly, type: "button", children: "\uC624\uB298" }) })] }) }))] }));
|
|
8853
8925
|
}
|
|
8854
8926
|
// 인라인 형태 (기존 방식)
|
|
8855
8927
|
return (jsxRuntimeExports.jsxs("div", { className: clsx('designbase-date-picker', `designbase-date-picker--size-${size}`, `designbase-date-picker--variant-${variant}`, {
|
|
8856
8928
|
'designbase-date-picker--disabled': disabled,
|
|
8857
8929
|
'designbase-date-picker--readonly': readonly,
|
|
8858
|
-
}, className), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-date-picker__header", children: [jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToPreviousMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uC774\uC804 \uB2EC", children: jsxRuntimeExports.jsx(
|
|
8930
|
+
}, className), children: [jsxRuntimeExports.jsxs("div", { className: "designbase-date-picker__header", children: [jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToPreviousMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uC774\uC804 \uB2EC", children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: iconSize, color: "currentColor" }) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__current-month", children: currentDate.toLocaleDateString(locale, { year: 'numeric', month: 'long' }) }), jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__nav-button", onClick: goToNextMonth, disabled: disabled || readonly, type: "button", "aria-label": "\uB2E4\uC74C \uB2EC", children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: iconSize, color: "currentColor" }) })] }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__weekdays", children: weekdays.map(day => (jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__weekday", children: day }, day))) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__grid", children: calendarGrid.map(date => renderDateCell(date)) }), jsxRuntimeExports.jsx("div", { className: "designbase-date-picker__footer", children: jsxRuntimeExports.jsx("button", { className: "designbase-date-picker__today-button", onClick: goToToday, disabled: disabled || readonly, type: "button", children: "\uC624\uB298" }) })] }));
|
|
8859
8931
|
};
|
|
8860
8932
|
|
|
8861
|
-
const MarkdownEditor = ({ size = '
|
|
8933
|
+
const MarkdownEditor = ({ size = 'm', variant = 'default', mode = 'preview', // 기본값을 preview로 변경
|
|
8862
8934
|
theme = 'light', value = '', placeholder = '마크다운을 입력하세요...', minHeight = 200, maxHeight = 600, autoHeight = false, readonly = false, disabled = false, showToolbar = true, toolbarItems = [], showStatus = true, showWordCount = true, showLineCount = true, autoSave = false, autoSaveInterval = 30000, // 30초
|
|
8863
8935
|
onFileUpload, onChange, onSave, onFocus, onBlur, className, }) => {
|
|
8864
8936
|
const [internalValue, setInternalValue] = React.useState(value);
|
|
@@ -9151,7 +9223,7 @@ onFileUpload, onChange, onSave, onFocus, onBlur, className, }) => {
|
|
|
9151
9223
|
}, className: "designbase-markdown-editor__textarea" }) })), (currentMode === 'preview' || currentMode === 'split') && (jsxRuntimeExports.jsx("div", { className: "designbase-markdown-editor__preview-panel", children: jsxRuntimeExports.jsx("div", { ref: previewRef, className: "designbase-markdown-editor__preview", dangerouslySetInnerHTML: { __html: markdownToHtml(internalValue) } }) })), currentMode === 'code' && (jsxRuntimeExports.jsx("div", { className: "designbase-markdown-editor__code-panel", children: jsxRuntimeExports.jsx("pre", { className: "designbase-markdown-editor__code-view", children: jsxRuntimeExports.jsx("code", { children: internalValue }) }) }))] }), renderStatus()] }));
|
|
9152
9224
|
};
|
|
9153
9225
|
|
|
9154
|
-
const Lightbox = ({ images, currentIndex = 0, size = '
|
|
9226
|
+
const Lightbox = ({ images, currentIndex = 0, size = 'l', variant = 'default', theme = 'light', isOpen, onOpenChange, onImageChange, enableZoom = true, enableRotate = true, enableDownload = true, enableFullscreen = true, enableKeyboard = true, enableWheelZoom = true, showThumbnails = true, showCounter = true, showCloseButton = true, showNavigationButtons = true, showToolbar = true, closeOnBackdropClick = true, closeOnEscape = true, readonly = false, disabled = false, className, }) => {
|
|
9155
9227
|
const [internalCurrentIndex, setInternalCurrentIndex] = React.useState(currentIndex);
|
|
9156
9228
|
const [zoomLevel, setZoomLevel] = React.useState(1);
|
|
9157
9229
|
const [rotation, setRotation] = React.useState(0);
|
|
@@ -9161,6 +9233,8 @@ const Lightbox = ({ images, currentIndex = 0, size = 'lg', variant = 'default',
|
|
|
9161
9233
|
const [imagePosition, setImagePosition] = React.useState({ x: 0, y: 0 });
|
|
9162
9234
|
const [isImageLoaded, setIsImageLoaded] = React.useState(false);
|
|
9163
9235
|
const [isImageError, setIsImageError] = React.useState(false);
|
|
9236
|
+
const [touchStart, setTouchStart] = React.useState({ x: 0, y: 0 });
|
|
9237
|
+
const [touchEnd, setTouchEnd] = React.useState({ x: 0, y: 0 });
|
|
9164
9238
|
const modalRef = React.useRef(null);
|
|
9165
9239
|
const imageRef = React.useRef(null);
|
|
9166
9240
|
const containerRef = React.useRef(null);
|
|
@@ -9334,6 +9408,38 @@ const Lightbox = ({ images, currentIndex = 0, size = 'lg', variant = 'default',
|
|
|
9334
9408
|
const handleMouseUp = React.useCallback(() => {
|
|
9335
9409
|
setIsDragging(false);
|
|
9336
9410
|
}, []);
|
|
9411
|
+
// 터치 시작 핸들러
|
|
9412
|
+
const handleTouchStart = React.useCallback((event) => {
|
|
9413
|
+
if (disabled || readonly)
|
|
9414
|
+
return;
|
|
9415
|
+
const touch = event.touches[0];
|
|
9416
|
+
setTouchStart({ x: touch.clientX, y: touch.clientY });
|
|
9417
|
+
}, [disabled, readonly]);
|
|
9418
|
+
// 터치 종료 핸들러
|
|
9419
|
+
const handleTouchEnd = React.useCallback((event) => {
|
|
9420
|
+
if (disabled || readonly)
|
|
9421
|
+
return;
|
|
9422
|
+
const touch = event.changedTouches[0];
|
|
9423
|
+
setTouchEnd({ x: touch.clientX, y: touch.clientY });
|
|
9424
|
+
handleSwipe();
|
|
9425
|
+
}, [disabled, readonly]);
|
|
9426
|
+
// 스와이프 처리
|
|
9427
|
+
const handleSwipe = React.useCallback(() => {
|
|
9428
|
+
const deltaX = touchStart.x - touchEnd.x;
|
|
9429
|
+
const deltaY = touchStart.y - touchEnd.y;
|
|
9430
|
+
const minSwipeDistance = 50;
|
|
9431
|
+
// 수평 스와이프가 수직 스와이프보다 크고, 최소 거리 이상일 때
|
|
9432
|
+
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > minSwipeDistance) {
|
|
9433
|
+
if (deltaX > 0) {
|
|
9434
|
+
// 왼쪽으로 스와이프 - 다음 이미지
|
|
9435
|
+
goToNext();
|
|
9436
|
+
}
|
|
9437
|
+
else {
|
|
9438
|
+
// 오른쪽으로 스와이프 - 이전 이미지
|
|
9439
|
+
goToPrevious();
|
|
9440
|
+
}
|
|
9441
|
+
}
|
|
9442
|
+
}, [touchStart, touchEnd, goToNext, goToPrevious]);
|
|
9337
9443
|
// 키보드 이벤트 핸들러
|
|
9338
9444
|
React.useEffect(() => {
|
|
9339
9445
|
if (!enableKeyboard || !isOpen || disabled || readonly)
|
|
@@ -9416,7 +9522,7 @@ const Lightbox = ({ images, currentIndex = 0, size = 'lg', variant = 'default',
|
|
|
9416
9522
|
'designbase-lightbox--fullscreen': isFullscreen,
|
|
9417
9523
|
'designbase-lightbox--disabled': disabled,
|
|
9418
9524
|
'designbase-lightbox--readonly': readonly,
|
|
9419
|
-
}, className), children: jsxRuntimeExports.jsx("div", { className: "designbase-lightbox__overlay", children: jsxRuntimeExports.jsxs("div", { ref: modalRef, className: "designbase-lightbox__modal", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__header", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__title", children: [currentImage.title && (jsxRuntimeExports.jsx("h3", { className: "designbase-lightbox__title-text", children: currentImage.title })), showCounter && (jsxRuntimeExports.jsxs("span", { className: "designbase-lightbox__counter", children: [internalCurrentIndex + 1, " / ", images.length] }))] }), jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__header-actions", children: [showToolbar && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [enableZoom && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomOut, disabled: disabled || readonly, title: "\uC90C \uC544\uC6C3", type: "button", children: jsxRuntimeExports.jsx(icons.MinusIcon, { size: 16 }) }), jsxRuntimeExports.jsxs("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomReset, disabled: disabled || readonly, title: "\uC90C \uB9AC\uC14B", type: "button", children: [Math.round(zoomLevel * 100), "%"] }), jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomIn, disabled: disabled || readonly, title: "\uC90C \uC778", type: "button", children: jsxRuntimeExports.jsx(icons.PlusIcon, { size: 16 }) })] })), enableRotate && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleRotate, disabled: disabled || readonly, title: "\uD68C\uC804", type: "button", children: jsxRuntimeExports.jsx(icons.RefreshIcon, { size: 16 }) })), enableDownload && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleDownload, disabled: disabled || readonly, title: "\uB2E4\uC6B4\uB85C\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.DownloadIcon, { size: 16 }) })), enableFullscreen && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleFullscreenToggle, disabled: disabled || readonly, title: isFullscreen ? "전체화면 해제" : "전체화면", type: "button", children: isFullscreen ? jsxRuntimeExports.jsx(icons.ShrinkIcon, { size: 16 }) : jsxRuntimeExports.jsx(icons.ExpandIcon, { size: 16 }) }))] })), showCloseButton && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__close-button", onClick: handleClose, disabled: disabled, title: "\uB2EB\uAE30", type: "button", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: 20 }) }))] })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__content", children: [showNavigationButtons && images.length > 1 && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__nav-button designbase-lightbox__nav-button--prev", onClick: goToPrevious, disabled: disabled || readonly, title: "\uC774\uC804 \uC774\uBBF8\uC9C0", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: 24 }) }), jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__nav-button designbase-lightbox__nav-button--next", onClick: goToNext, disabled: disabled || readonly, title: "\uB2E4\uC74C \uC774\uBBF8\uC9C0", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: 24 }) })] })), jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "designbase-lightbox__image-container", onWheel: handleWheel, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, children: [isImageError ? (jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__error", children: [jsxRuntimeExports.jsx("div", { className: "designbase-lightbox__error-icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("p", { className: "designbase-lightbox__error-text", children: "\uC774\uBBF8\uC9C0\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4." })] })) : (jsxRuntimeExports.jsx("img", { ref: imageRef, src: currentImage.src, alt: currentImage.alt || currentImage.title || `이미지 ${internalCurrentIndex + 1}`, className: clsx('designbase-lightbox__image', {
|
|
9525
|
+
}, className), children: jsxRuntimeExports.jsx("div", { className: "designbase-lightbox__overlay", children: jsxRuntimeExports.jsxs("div", { ref: modalRef, className: "designbase-lightbox__modal", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__header", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__title", children: [currentImage.title && (jsxRuntimeExports.jsx("h3", { className: "designbase-lightbox__title-text", children: currentImage.title })), showCounter && (jsxRuntimeExports.jsxs("span", { className: "designbase-lightbox__counter", children: [internalCurrentIndex + 1, " / ", images.length] }))] }), jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__header-actions", children: [showToolbar && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [enableZoom && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomOut, disabled: disabled || readonly, title: "\uC90C \uC544\uC6C3", type: "button", children: jsxRuntimeExports.jsx(icons.MinusIcon, { size: 16 }) }), jsxRuntimeExports.jsxs("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomReset, disabled: disabled || readonly, title: "\uC90C \uB9AC\uC14B", type: "button", children: [Math.round(zoomLevel * 100), "%"] }), jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleZoomIn, disabled: disabled || readonly, title: "\uC90C \uC778", type: "button", children: jsxRuntimeExports.jsx(icons.PlusIcon, { size: 16 }) })] })), enableRotate && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleRotate, disabled: disabled || readonly, title: "\uD68C\uC804", type: "button", children: jsxRuntimeExports.jsx(icons.RefreshIcon, { size: 16 }) })), enableDownload && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleDownload, disabled: disabled || readonly, title: "\uB2E4\uC6B4\uB85C\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.DownloadIcon, { size: 16 }) })), enableFullscreen && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__toolbar-button", onClick: handleFullscreenToggle, disabled: disabled || readonly, title: isFullscreen ? "전체화면 해제" : "전체화면", type: "button", children: isFullscreen ? jsxRuntimeExports.jsx(icons.ShrinkIcon, { size: 16 }) : jsxRuntimeExports.jsx(icons.ExpandIcon, { size: 16 }) }))] })), showCloseButton && (jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__close-button", onClick: handleClose, disabled: disabled, title: "\uB2EB\uAE30", type: "button", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: 20 }) }))] })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__content", children: [showNavigationButtons && images.length > 1 && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__nav-button designbase-lightbox__nav-button--prev", onClick: goToPrevious, disabled: disabled || readonly, title: "\uC774\uC804 \uC774\uBBF8\uC9C0", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: 24 }) }), jsxRuntimeExports.jsx("button", { className: "designbase-lightbox__nav-button designbase-lightbox__nav-button--next", onClick: goToNext, disabled: disabled || readonly, title: "\uB2E4\uC74C \uC774\uBBF8\uC9C0", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: 24 }) })] })), jsxRuntimeExports.jsxs("div", { ref: containerRef, className: "designbase-lightbox__image-container", onWheel: handleWheel, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onTouchStart: handleTouchStart, onTouchEnd: handleTouchEnd, children: [isImageError ? (jsxRuntimeExports.jsxs("div", { className: "designbase-lightbox__error", children: [jsxRuntimeExports.jsx("div", { className: "designbase-lightbox__error-icon", children: "\u26A0\uFE0F" }), jsxRuntimeExports.jsx("p", { className: "designbase-lightbox__error-text", children: "\uC774\uBBF8\uC9C0\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4." })] })) : (jsxRuntimeExports.jsx("img", { ref: imageRef, src: currentImage.src, alt: currentImage.alt || currentImage.title || `이미지 ${internalCurrentIndex + 1}`, className: clsx('designbase-lightbox__image', {
|
|
9420
9526
|
'designbase-lightbox__image--loaded': isImageLoaded,
|
|
9421
9527
|
'designbase-lightbox__image--dragging': isDragging,
|
|
9422
9528
|
}), style: {
|
|
@@ -9427,7 +9533,9 @@ const Lightbox = ({ images, currentIndex = 0, size = 'lg', variant = 'default',
|
|
|
9427
9533
|
}), onClick: () => handleImageChange(index), disabled: disabled || readonly, title: image.title || `이미지 ${index + 1}`, type: "button", children: jsxRuntimeExports.jsx("img", { src: image.thumbnail || image.src, alt: image.alt || image.title || `썸네일 ${index + 1}`, className: "designbase-lightbox__thumbnail-image" }) }, image.id))) }) }))] }) }) }));
|
|
9428
9534
|
};
|
|
9429
9535
|
|
|
9430
|
-
const Carousel = ({ items, size = '
|
|
9536
|
+
const Carousel = ({ items, size = 'm', variant = 'default', theme = 'light', transition = 'slide', autoPlay = false, autoPlayInterval = 5000, infinite = true, itemsPerView = 1, gap = 16, showNavigation = true, showIndicators = true, indicatorStyle = 'dots', showAutoPlayControl = true, showTitle = true, showDescription = true, enableTouch = true, enableKeyboard = true, enableWheel = false, enableFullscreen = false, enableDownload = false, enableShare = false, enableLike = false, enableBookmark = false, readonly = false, disabled = false, enablePaging = false, swipeSensitivity = 50, transitionDuration = 300, onItemClick, onSlideChange, onLike, onBookmark, onShare, onDownload, onFullscreenChange, className, }) => {
|
|
9537
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
9538
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : size === 'xl' ? 28 : 20;
|
|
9431
9539
|
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
9432
9540
|
const [isAutoPlaying, setIsAutoPlaying] = React.useState(autoPlay);
|
|
9433
9541
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
@@ -9713,27 +9821,35 @@ const Carousel = ({ items, size = 'md', variant = 'default', theme = 'light', tr
|
|
|
9713
9821
|
}), style: {
|
|
9714
9822
|
width: `${100 / itemsPerView}%`,
|
|
9715
9823
|
backgroundColor: item.backgroundColor,
|
|
9716
|
-
color: item.textColor,
|
|
9717
|
-
}, onClick: () => handleItemClick(item, index), children: [item.content ? (jsxRuntimeExports.jsx("div", { className: "designbase-carousel__slide-content", children: item.content })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [item.image && (jsxRuntimeExports.jsx("div", { className: "designbase-carousel__slide-image", children: jsxRuntimeExports.jsx("img", { src: item.image, alt: item.alt || item.title || `슬라이드 ${index + 1}`, className: "designbase-carousel__slide-img" }) })), (showTitle && item.title) || (showDescription && item.description) ? (jsxRuntimeExports.jsxs("div", { className: "designbase-carousel__slide-info",
|
|
9824
|
+
color: item.textColor || (item.image ? '#ffffff' : undefined),
|
|
9825
|
+
}, onClick: () => handleItemClick(item, index), children: [item.content ? (jsxRuntimeExports.jsx("div", { className: "designbase-carousel__slide-content", children: item.content })) : (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [item.image && (jsxRuntimeExports.jsx("div", { className: "designbase-carousel__slide-image", children: jsxRuntimeExports.jsx("img", { src: item.image, alt: item.alt || item.title || `슬라이드 ${index + 1}`, className: "designbase-carousel__slide-img" }) })), (showTitle && item.title) || (showDescription && item.description) ? (jsxRuntimeExports.jsxs("div", { className: "designbase-carousel__slide-info", style: {
|
|
9826
|
+
color: item.textColor || (item.image ? '#ffffff' : undefined),
|
|
9827
|
+
}, children: [showTitle && item.title && (jsxRuntimeExports.jsx("h3", { className: "designbase-carousel__slide-title", style: {
|
|
9828
|
+
color: item.textColor || (item.image ? '#ffffff' : undefined),
|
|
9829
|
+
}, children: item.title })), showDescription && item.description && (jsxRuntimeExports.jsx("p", { className: "designbase-carousel__slide-description", style: {
|
|
9830
|
+
color: item.textColor || (item.image ? '#ffffff' : undefined),
|
|
9831
|
+
}, children: item.description })), item.meta && (jsxRuntimeExports.jsxs("div", { className: "designbase-carousel__slide-meta", children: [item.meta.author && (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__slide-author", children: item.meta.author })), item.meta.date && (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__slide-date", children: item.meta.date })), item.meta.rating && (jsxRuntimeExports.jsxs("span", { className: "designbase-carousel__slide-rating", children: ["\u2B50 ", item.meta.rating] }))] }))] })) : null] })), jsxRuntimeExports.jsxs("div", { className: "designbase-carousel__slide-actions", children: [enableLike && (jsxRuntimeExports.jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--like', { 'designbase-carousel__action-button--active': isLiked }), onClick: (e) => {
|
|
9718
9832
|
e.stopPropagation();
|
|
9719
9833
|
handleLike(item, index);
|
|
9720
|
-
}, title: isLiked ? "좋아요 취소" : "좋아요", children: jsxRuntimeExports.jsx(icons.HeartIcon, { size:
|
|
9834
|
+
}, title: isLiked ? "좋아요 취소" : "좋아요", children: jsxRuntimeExports.jsx(icons.HeartIcon, { size: iconSize, color: "currentColor" }) })), enableBookmark && (jsxRuntimeExports.jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--bookmark', { 'designbase-carousel__action-button--active': isBookmarked }), onClick: (e) => {
|
|
9721
9835
|
e.stopPropagation();
|
|
9722
9836
|
handleBookmark(item, index);
|
|
9723
|
-
}, title: isBookmarked ? "북마크 해제" : "북마크", children: jsxRuntimeExports.jsx(icons.BookmarkIcon, { size:
|
|
9837
|
+
}, title: isBookmarked ? "북마크 해제" : "북마크", children: jsxRuntimeExports.jsx(icons.BookmarkIcon, { size: iconSize, color: "currentColor" }) })), enableShare && (jsxRuntimeExports.jsx("button", { className: "designbase-carousel__action-button designbase-carousel__action-button--share", onClick: (e) => {
|
|
9724
9838
|
e.stopPropagation();
|
|
9725
9839
|
handleShare(item, index);
|
|
9726
|
-
}, title: "\uACF5\uC720", children: jsxRuntimeExports.jsx(icons.ShareAltIcon, { size:
|
|
9840
|
+
}, title: "\uACF5\uC720", children: jsxRuntimeExports.jsx(icons.ShareAltIcon, { size: iconSize, color: "currentColor" }) })), enableDownload && item.image && (jsxRuntimeExports.jsx("button", { className: "designbase-carousel__action-button designbase-carousel__action-button--download", onClick: (e) => {
|
|
9727
9841
|
e.stopPropagation();
|
|
9728
9842
|
handleDownload(item, index);
|
|
9729
|
-
}, title: "\uB2E4\uC6B4\uB85C\uB4DC", children: jsxRuntimeExports.jsx(icons.DownloadIcon, { size:
|
|
9843
|
+
}, title: "\uB2E4\uC6B4\uB85C\uB4DC", children: jsxRuntimeExports.jsx(icons.DownloadIcon, { size: iconSize, color: "currentColor" }) }))] })] }, item.id))) }), showNavigation && items.length > 1 && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: clsx('designbase-carousel__nav-button', 'designbase-carousel__nav-button--prev'), onClick: goToPrevious, disabled: disabled || readonly || isPrevDisabled, title: "\uC774\uC804 \uC2AC\uB77C\uC774\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronLeftIcon, { size: iconSize, color: "currentColor" }) }), jsxRuntimeExports.jsx("button", { className: clsx('designbase-carousel__nav-button', 'designbase-carousel__nav-button--next'), onClick: goToNext, disabled: disabled || readonly || isNextDisabled, title: "\uB2E4\uC74C \uC2AC\uB77C\uC774\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.ChevronRightIcon, { size: iconSize, color: "currentColor" }) })] })), enablePaging && items.length > 1 && (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("button", { className: "designbase-carousel__quick-nav-button designbase-carousel__quick-nav-button--first", onClick: goToFirst, disabled: disabled || readonly || currentIndex === 0, title: "\uCCAB \uBC88\uC9F8 \uC2AC\uB77C\uC774\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.ArrowLeftIcon, { size: iconSize, color: "currentColor" }) }), jsxRuntimeExports.jsx("button", { className: "designbase-carousel__quick-nav-button designbase-carousel__quick-nav-button--last", onClick: goToLast, disabled: disabled || readonly || currentIndex === items.length - 1, title: "\uB9C8\uC9C0\uB9C9 \uC2AC\uB77C\uC774\uB4DC", type: "button", children: jsxRuntimeExports.jsx(icons.ArrowRightIcon, { size: iconSize, color: "currentColor" }) })] })), enableFullscreen && (jsxRuntimeExports.jsx("button", { className: "designbase-carousel__fullscreen-button", onClick: handleFullscreenToggle, disabled: disabled || readonly, title: isFullscreen ? "전체화면 해제" : "전체화면", type: "button", children: isFullscreen ? jsxRuntimeExports.jsx(icons.ShrinkIcon, { size: iconSize, color: "currentColor" }) : jsxRuntimeExports.jsx(icons.ExpandIcon, { size: iconSize, color: "currentColor" }) }))] }), jsxRuntimeExports.jsxs("div", { className: "designbase-carousel__controls", children: [showIndicators && items.length > 1 && (jsxRuntimeExports.jsx("div", { className: "designbase-carousel__indicators", children: items.map((item, index) => (jsxRuntimeExports.jsx("button", { className: clsx('designbase-carousel__indicator', {
|
|
9730
9844
|
'designbase-carousel__indicator--active': isIndicatorActive(index),
|
|
9731
|
-
}), onClick: () => goToSlide(index), disabled: disabled || readonly, title: `슬라이드 ${index + 1}로 이동`, type: "button", children: indicatorStyle === 'thumbnails' && item.thumbnail ? (jsxRuntimeExports.jsx("img", { src: item.thumbnail, alt: item.title || `썸네일 ${index + 1}`, className: "designbase-carousel__indicator-thumbnail" })) : indicatorStyle === 'numbers' ? (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-number", children: index + 1 })) : indicatorStyle === 'lines' ? (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-line" })) : (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-dot" })) }, index))) })), showAutoPlayControl && items.length > 1 && (jsxRuntimeExports.jsx("button", { className: "designbase-carousel__autoplay-button", onClick: handleAutoPlayToggle, disabled: disabled || readonly, title: isAutoPlaying ? "자동 재생 정지" : "자동 재생 시작", type: "button", children: isAutoPlaying ? jsxRuntimeExports.jsx(icons.PauseIcon, { size:
|
|
9845
|
+
}), onClick: () => goToSlide(index), disabled: disabled || readonly, title: `슬라이드 ${index + 1}로 이동`, type: "button", children: indicatorStyle === 'thumbnails' && item.thumbnail ? (jsxRuntimeExports.jsx("img", { src: item.thumbnail, alt: item.title || `썸네일 ${index + 1}`, className: "designbase-carousel__indicator-thumbnail" })) : indicatorStyle === 'numbers' ? (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-number", children: index + 1 })) : indicatorStyle === 'lines' ? (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-line" })) : (jsxRuntimeExports.jsx("span", { className: "designbase-carousel__indicator-dot" })) }, index))) })), showAutoPlayControl && items.length > 1 && (jsxRuntimeExports.jsx("button", { className: "designbase-carousel__autoplay-button", onClick: handleAutoPlayToggle, disabled: disabled || readonly, title: isAutoPlaying ? "자동 재생 정지" : "자동 재생 시작", type: "button", children: isAutoPlaying ? jsxRuntimeExports.jsx(icons.PauseIcon, { size: iconSize, color: "currentColor" }) : jsxRuntimeExports.jsx(icons.PlayIcon, { size: iconSize, color: "currentColor" }) }))] })] }));
|
|
9732
9846
|
};
|
|
9733
9847
|
|
|
9734
|
-
const List = ({ items, size = '
|
|
9848
|
+
const List = ({ items, size = 'm', variant = 'default', itemType = 'default', layout = 'vertical', selectable = false, multiple = false, selectedItems = [], draggable = false, spacing = 'm', alignment = 'start', onItemClick, onItemSelect, onItemDrag, emptyState, loading = false, loadingCount = 3, className, }) => {
|
|
9735
9849
|
const [internalSelectedItems, setInternalSelectedItems] = React.useState(selectedItems);
|
|
9736
9850
|
const [draggedItem, setDraggedItem] = React.useState(null);
|
|
9851
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
9852
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
9737
9853
|
// 외부에서 선택된 아이템이 변경되면 내부 상태 업데이트
|
|
9738
9854
|
React.useEffect(() => {
|
|
9739
9855
|
setInternalSelectedItems(selectedItems);
|
|
@@ -9810,7 +9926,10 @@ const List = ({ items, size = 'md', variant = 'default', itemType = 'default', l
|
|
|
9810
9926
|
'designbase-list__item--clickable': onItemClick || selectable,
|
|
9811
9927
|
'designbase-list__item--draggable': draggable,
|
|
9812
9928
|
});
|
|
9813
|
-
return (jsxRuntimeExports.jsxs("div", { className: itemClasses, onClick: () => handleItemClick(item, index), draggable: draggable, onDragStart: (e) => handleItemDragStart(e, item.id), onDragOver: handleItemDragOver, onDrop: (e) => handleItemDrop(e, item.id), onDragEnd: handleItemDragEnd, role: selectable ? 'button' : undefined, tabIndex: selectable ? 0 : undefined, "aria-selected": selectable ? isSelected : undefined, children: [selectable && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-checkbox", children: jsxRuntimeExports.jsx("input", { type: multiple ? 'checkbox' : 'radio', checked: isSelected, onChange: () => handleItemClick(item, index), disabled: item.disabled }) })), item.icon && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-icon", children:
|
|
9929
|
+
return (jsxRuntimeExports.jsxs("div", { className: itemClasses, onClick: () => handleItemClick(item, index), draggable: draggable, onDragStart: (e) => handleItemDragStart(e, item.id), onDragOver: handleItemDragOver, onDrop: (e) => handleItemDrop(e, item.id), onDragEnd: handleItemDragEnd, role: selectable ? 'button' : undefined, tabIndex: selectable ? 0 : undefined, "aria-selected": selectable ? isSelected : undefined, children: [selectable && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-checkbox", children: jsxRuntimeExports.jsx("input", { type: multiple ? 'checkbox' : 'radio', checked: isSelected, onChange: () => handleItemClick(item, index), disabled: item.disabled }) })), item.icon && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-icon", children: React.isValidElement(item.icon) ? (React.cloneElement(item.icon, {
|
|
9930
|
+
size: iconSize,
|
|
9931
|
+
color: 'currentColor'
|
|
9932
|
+
})) : item.icon })), item.image && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-image", children: jsxRuntimeExports.jsx("img", { src: item.image, alt: item.title }) })), jsxRuntimeExports.jsxs("div", { className: "designbase-list__item-content", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-list__item-header", children: [jsxRuntimeExports.jsx("h4", { className: "designbase-list__item-title", children: item.title }), item.badge && renderBadge(item.badge)] }), item.description && (jsxRuntimeExports.jsx("p", { className: "designbase-list__item-description", children: item.description })), item.meta && renderMeta(item.meta)] }), item.actions && renderActions(item.actions), draggable && (jsxRuntimeExports.jsx("div", { className: "designbase-list__item-drag-handle", children: "\u22EE\u22EE" }))] }, item.id));
|
|
9814
9933
|
};
|
|
9815
9934
|
const renderLoadingSkeleton = () => {
|
|
9816
9935
|
return Array.from({ length: loadingCount }, (_, index) => (jsxRuntimeExports.jsx("div", { className: "designbase-list__item designbase-list__item--loading", children: jsxRuntimeExports.jsxs("div", { className: "designbase-list__item-skeleton", children: [jsxRuntimeExports.jsx("div", { className: "designbase-list__item-skeleton-icon" }), jsxRuntimeExports.jsxs("div", { className: "designbase-list__item-skeleton-content", children: [jsxRuntimeExports.jsx("div", { className: "designbase-list__item-skeleton-title" }), jsxRuntimeExports.jsx("div", { className: "designbase-list__item-skeleton-description" })] })] }) }, index)));
|
|
@@ -9830,7 +9949,7 @@ const List = ({ items, size = 'md', variant = 'default', itemType = 'default', l
|
|
|
9830
9949
|
return (jsxRuntimeExports.jsx("div", { className: classes, children: items.map((item, index) => renderItem(item, index)) }));
|
|
9831
9950
|
};
|
|
9832
9951
|
|
|
9833
|
-
const HeroFeature = ({ title, subtitle, description, image, imageAlt, backgroundImage, backgroundVideo, overlayColor, overlayOpacity = 0.5, buttons = [], badge, stats = [], icon, size = '
|
|
9952
|
+
const HeroFeature = ({ title, subtitle, description, image, imageAlt, backgroundImage, backgroundVideo, overlayColor, overlayOpacity = 0.5, buttons = [], badge, stats = [], icon, size = 'l', variant = 'default', theme = 'light', alignment = 'left', animated = false, parallax = false, fullHeight = false, minHeight, maxHeight, className, }) => {
|
|
9834
9953
|
const renderBadge = () => {
|
|
9835
9954
|
if (!badge)
|
|
9836
9955
|
return null;
|
|
@@ -9854,7 +9973,7 @@ const HeroFeature = ({ title, subtitle, description, image, imageAlt, background
|
|
|
9854
9973
|
default: return 'text';
|
|
9855
9974
|
}
|
|
9856
9975
|
};
|
|
9857
|
-
return (jsxRuntimeExports.jsx(Badge, { variant: getBadgeVariant(badge.color || 'primary'), style: getBadgeStyle(badge.variant || 'solid'), size: "
|
|
9976
|
+
return (jsxRuntimeExports.jsx(Badge, { variant: getBadgeVariant(badge.color || 'primary'), style: getBadgeStyle(badge.variant || 'solid'), size: "m", className: "designbase-hero-feature__badge", children: badge.text }));
|
|
9858
9977
|
};
|
|
9859
9978
|
const renderButtons = () => {
|
|
9860
9979
|
if (buttons.length === 0)
|
|
@@ -9864,7 +9983,7 @@ const HeroFeature = ({ title, subtitle, description, image, imageAlt, background
|
|
|
9864
9983
|
const renderStats = () => {
|
|
9865
9984
|
if (stats.length === 0)
|
|
9866
9985
|
return null;
|
|
9867
|
-
return (jsxRuntimeExports.jsx("div", { className: "designbase-hero-feature__stats", children: stats.map((stat, index) => (jsxRuntimeExports.jsx(Stat, { value: stat.value, label: stat.label, description: stat.description, size: "
|
|
9986
|
+
return (jsxRuntimeExports.jsx("div", { className: "designbase-hero-feature__stats", children: stats.map((stat, index) => (jsxRuntimeExports.jsx(Stat, { value: stat.value, label: stat.label, description: stat.description, size: "m", variant: "minimal", layout: "vertical", className: "designbase-hero-feature__stat" }, index))) }));
|
|
9868
9987
|
};
|
|
9869
9988
|
const renderImage = () => {
|
|
9870
9989
|
if (!image)
|
|
@@ -9908,8 +10027,10 @@ const HeroFeature = ({ title, subtitle, description, image, imageAlt, background
|
|
|
9908
10027
|
return (jsxRuntimeExports.jsxs("section", { className: classes, style: containerStyle, children: [renderBackground(), renderOverlay(), jsxRuntimeExports.jsxs("div", { className: "designbase-hero-feature__container", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-hero-feature__content", children: [icon && (jsxRuntimeExports.jsx("div", { className: "designbase-hero-feature__icon", children: icon })), renderBadge(), jsxRuntimeExports.jsx("h1", { className: "designbase-hero-feature__title", children: title }), subtitle && (jsxRuntimeExports.jsx("h2", { className: "designbase-hero-feature__subtitle", children: subtitle })), description && (jsxRuntimeExports.jsx("p", { className: "designbase-hero-feature__description", children: description })), renderButtons(), renderStats()] }), variant === 'split' && renderImage()] }), variant !== 'split' && renderImage()] }));
|
|
9909
10028
|
};
|
|
9910
10029
|
|
|
9911
|
-
const Banner = ({ title, description, icon, image, imageAlt, actions = [], dismissible = false, autoDismiss, size = '
|
|
10030
|
+
const Banner = ({ title, description, icon, image, imageAlt, actions = [], dismissible = false, autoDismiss, size = 'm', variant = 'default', style = 'solid', position = 'top', alignment = 'left', animated = false, fullWidth = false, shadow = false, rounded = true, backgroundImage, overlayColor, overlayOpacity = 0.1, onDismiss, className, }) => {
|
|
9912
10031
|
const [isVisible, setIsVisible] = React.useState(true);
|
|
10032
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
10033
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
9913
10034
|
// 자동 닫기
|
|
9914
10035
|
React.useEffect(() => {
|
|
9915
10036
|
if (autoDismiss && autoDismiss > 0) {
|
|
@@ -9957,10 +10078,13 @@ const Banner = ({ title, description, icon, image, imageAlt, actions = [], dismi
|
|
|
9957
10078
|
}, className);
|
|
9958
10079
|
if (!isVisible)
|
|
9959
10080
|
return null;
|
|
9960
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [renderBackground(), renderOverlay(), jsxRuntimeExports.jsxs("div", { className: "designbase-banner__container", children: [icon && (jsxRuntimeExports.jsx("div", { className: "designbase-banner__icon", children:
|
|
10081
|
+
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [renderBackground(), renderOverlay(), jsxRuntimeExports.jsxs("div", { className: "designbase-banner__container", children: [icon && (jsxRuntimeExports.jsx("div", { className: "designbase-banner__icon", children: React.isValidElement(icon) ? (React.cloneElement(icon, {
|
|
10082
|
+
size: iconSize,
|
|
10083
|
+
color: 'currentColor'
|
|
10084
|
+
})) : icon })), image && (jsxRuntimeExports.jsx("div", { className: "designbase-banner__image", children: jsxRuntimeExports.jsx("img", { src: image, alt: imageAlt || title || 'Banner image' }) })), jsxRuntimeExports.jsxs("div", { className: "designbase-banner__content", children: [title && (jsxRuntimeExports.jsx("h3", { className: "designbase-banner__title", children: title })), description && (jsxRuntimeExports.jsx("p", { className: "designbase-banner__description", children: description }))] }), renderActions(), dismissible && (jsxRuntimeExports.jsx("button", { className: "designbase-banner__dismiss", onClick: handleDismiss, "aria-label": "\uB2EB\uAE30", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: iconSize }) }))] })] }));
|
|
9961
10085
|
};
|
|
9962
10086
|
|
|
9963
|
-
const Skeleton = React.forwardRef(({ variant = 'text', size = '
|
|
10087
|
+
const Skeleton = React.forwardRef(({ variant = 'text', size = 'm', width, height, animation = 'pulse', lines = 1, lineSpacing = '8px', lastLineWidth = '60%', className, style, 'aria-label': ariaLabel, ...props }, forwardedRef) => {
|
|
9964
10088
|
// 기본 크기 결정
|
|
9965
10089
|
const getDefaultSize = () => {
|
|
9966
10090
|
switch (size) {
|
|
@@ -10012,7 +10136,7 @@ const Skeleton = React.forwardRef(({ variant = 'text', size = 'md', width, heigh
|
|
|
10012
10136
|
});
|
|
10013
10137
|
Skeleton.displayName = 'Skeleton';
|
|
10014
10138
|
|
|
10015
|
-
const YouTubePlayer = ({ videoId, title, description, size = '
|
|
10139
|
+
const YouTubePlayer = ({ videoId, title, description, size = 'm', variant = 'default', theme = 'auto', autoPlay = false, loop = false, muted = false, showControls = true, enableFullscreen = true, enableKeyboard = true, enableTouch = true, showSubtitles = false, defaultSubtitleLang = 'ko', playbackRate = 1, startTime = 0, endTime, showRelatedVideos = true, showInfo = true, showChannelInfo = true, showLikeButtons = true, showComments = false, playlist = [], currentIndex = 0, autoPause = false, onPlay, onPause, onEnded, onTimeUpdate, onVolumeChange, onFullscreenChange, onPlaylistChange, onPlaybackRateChange, onError, className, style, }) => {
|
|
10016
10140
|
const [isPlaying, setIsPlaying] = React.useState(false);
|
|
10017
10141
|
React.useState(0);
|
|
10018
10142
|
React.useState(0);
|
|
@@ -10266,7 +10390,7 @@ const Backdrop = React.forwardRef(({ open = false, onClick, disableBackdropClick
|
|
|
10266
10390
|
});
|
|
10267
10391
|
Backdrop.displayName = 'Backdrop';
|
|
10268
10392
|
|
|
10269
|
-
const BottomSheet = React.forwardRef(({ open = false, onClose, title, subtitle, size = '
|
|
10393
|
+
const BottomSheet = React.forwardRef(({ open = false, onClose, title, subtitle, size = 'm', variant = 'default', disableBackdropClick = false, disableEscapeKeyDown = false, disableDrag = false, maxHeight = 80, animation = 'slide', animationDuration = 300, zIndex = 1000, backdropBlur = true, backdropOpacity = 0.5, stickyHeader = false, stickyFooter = false, className, style, header, footer, children, ...props }, forwardedRef) => {
|
|
10270
10394
|
const [sheetHeight, setSheetHeight] = React.useState(maxHeight);
|
|
10271
10395
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
10272
10396
|
const [dragStartY, setDragStartY] = React.useState(0);
|
|
@@ -10394,63 +10518,15 @@ const BottomSheet = React.forwardRef(({ open = false, onClose, title, subtitle,
|
|
|
10394
10518
|
});
|
|
10395
10519
|
BottomSheet.displayName = 'BottomSheet';
|
|
10396
10520
|
|
|
10397
|
-
const FloatingActionButton = React.forwardRef(({ size = '
|
|
10398
|
-
const
|
|
10399
|
-
const [isHovered, setIsHovered] = React.useState(false);
|
|
10400
|
-
// 클릭 핸들러
|
|
10401
|
-
const handleClick = React.useCallback((event) => {
|
|
10402
|
-
if (disabled || loading)
|
|
10403
|
-
return;
|
|
10404
|
-
setIsPressed(false);
|
|
10405
|
-
onClick?.(event);
|
|
10406
|
-
}, [disabled, loading, onClick]);
|
|
10407
|
-
// 마우스 다운 핸들러
|
|
10408
|
-
const handleMouseDown = React.useCallback(() => {
|
|
10409
|
-
if (!disabled && !loading) {
|
|
10410
|
-
setIsPressed(true);
|
|
10411
|
-
}
|
|
10412
|
-
}, [disabled, loading]);
|
|
10413
|
-
// 마우스 업 핸들러
|
|
10414
|
-
const handleMouseUp = React.useCallback(() => {
|
|
10415
|
-
setIsPressed(false);
|
|
10416
|
-
}, []);
|
|
10417
|
-
// 마우스 진입 핸들러
|
|
10418
|
-
const handleMouseEnter = React.useCallback((event) => {
|
|
10419
|
-
if (!disabled) {
|
|
10420
|
-
setIsHovered(true);
|
|
10421
|
-
onMouseEnter?.(event);
|
|
10422
|
-
}
|
|
10423
|
-
}, [disabled, onMouseEnter]);
|
|
10424
|
-
// 마우스 이탈 핸들러
|
|
10425
|
-
const handleMouseLeave = React.useCallback((event) => {
|
|
10426
|
-
setIsHovered(false);
|
|
10427
|
-
setIsPressed(false);
|
|
10428
|
-
onMouseLeave?.(event);
|
|
10429
|
-
}, [onMouseLeave]);
|
|
10430
|
-
// 포커스 핸들러
|
|
10431
|
-
const handleFocus = React.useCallback((event) => {
|
|
10432
|
-
if (!disabled) {
|
|
10433
|
-
onFocus?.(event);
|
|
10434
|
-
}
|
|
10435
|
-
}, [disabled, onFocus]);
|
|
10436
|
-
// 블러 핸들러
|
|
10437
|
-
const handleBlur = React.useCallback((event) => {
|
|
10438
|
-
setIsHovered(false);
|
|
10439
|
-
setIsPressed(false);
|
|
10440
|
-
onBlur?.(event);
|
|
10441
|
-
}, [onBlur]);
|
|
10442
|
-
const classes = clsx('designbase-fab', `designbase-fab--${size}`, `designbase-fab--${variant}`, `designbase-fab--${position}`, `designbase-fab--${animation}`, `designbase-fab--elevation-${elevation}`, {
|
|
10443
|
-
'designbase-fab--extended': extended,
|
|
10521
|
+
const FloatingActionButton = React.forwardRef(({ size = 'm', variant = 'primary', icon, disabled = false, onClick, className, style, ...props }, forwardedRef) => {
|
|
10522
|
+
const classes = clsx('designbase-fab', `designbase-fab--${size}`, `designbase-fab--${variant}`, {
|
|
10444
10523
|
'designbase-fab--disabled': disabled,
|
|
10445
|
-
'designbase-fab--loading': loading,
|
|
10446
|
-
'designbase-fab--pressed': isPressed,
|
|
10447
|
-
'designbase-fab--hovered': isHovered,
|
|
10448
10524
|
}, className);
|
|
10449
|
-
return (jsxRuntimeExports.
|
|
10525
|
+
return (jsxRuntimeExports.jsx("button", { ref: forwardedRef, className: classes, style: style, onClick: onClick, disabled: disabled, "aria-label": "Floating action button", ...props, children: icon && (jsxRuntimeExports.jsx("div", { className: "designbase-fab__icon", children: icon })) }));
|
|
10450
10526
|
});
|
|
10451
10527
|
FloatingActionButton.displayName = 'FloatingActionButton';
|
|
10452
10528
|
|
|
10453
|
-
const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEventAdd, onEventEdit, onEventDelete, onDateClick, onEventClick, onViewChange, onMonthChange, onYearChange, showWeekends = true, highlightToday = true, locale = 'ko-KR', className, style, ...props }) => {
|
|
10529
|
+
const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEventAdd, onEventEdit, onEventDelete, onDateClick, onEventClick, onViewChange, onMonthChange, onYearChange, showWeekends = true, highlightToday = true, showOutsideDays = true, locale = 'ko-KR', className, style, ...props }) => {
|
|
10454
10530
|
const [selectedDate, setSelectedDate] = React.useState(currentDate);
|
|
10455
10531
|
const [currentView, setCurrentView] = React.useState(view);
|
|
10456
10532
|
const [showEventModal, setShowEventModal] = React.useState(false);
|
|
@@ -10471,6 +10547,11 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10471
10547
|
// 드래그 관련 상태
|
|
10472
10548
|
const [draggedEvent, setDraggedEvent] = React.useState(null);
|
|
10473
10549
|
const [dragOverDate, setDragOverDate] = React.useState(null);
|
|
10550
|
+
// 날짜 범위 선택 상태
|
|
10551
|
+
const [selectedDateRange, setSelectedDateRange] = React.useState({
|
|
10552
|
+
start: null,
|
|
10553
|
+
end: null
|
|
10554
|
+
});
|
|
10474
10555
|
// 현재 년도와 월
|
|
10475
10556
|
const currentYear = selectedDate.getFullYear();
|
|
10476
10557
|
const currentMonth = selectedDate.getMonth();
|
|
@@ -10525,8 +10606,24 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10525
10606
|
const handleDateClick = React.useCallback((date) => {
|
|
10526
10607
|
setSelectedDate(date);
|
|
10527
10608
|
onDateClick?.(date);
|
|
10609
|
+
// 날짜 범위 선택 로직
|
|
10610
|
+
if (!selectedDateRange.start || (selectedDateRange.start && selectedDateRange.end)) {
|
|
10611
|
+
// 첫 번째 클릭이거나 이미 범위가 완성된 경우
|
|
10612
|
+
setSelectedDateRange({ start: date, end: null });
|
|
10613
|
+
}
|
|
10614
|
+
else if (selectedDateRange.start && !selectedDateRange.end) {
|
|
10615
|
+
// 두 번째 클릭
|
|
10616
|
+
if (date < selectedDateRange.start) {
|
|
10617
|
+
// 뒤로 클릭한 경우
|
|
10618
|
+
setSelectedDateRange({ start: date, end: selectedDateRange.start });
|
|
10619
|
+
}
|
|
10620
|
+
else {
|
|
10621
|
+
// 앞으로 클릭한 경우
|
|
10622
|
+
setSelectedDateRange({ start: selectedDateRange.start, end: date });
|
|
10623
|
+
}
|
|
10624
|
+
}
|
|
10528
10625
|
handleAddEvent(date);
|
|
10529
|
-
}, [onDateClick, handleAddEvent]);
|
|
10626
|
+
}, [onDateClick, handleAddEvent, selectedDateRange]);
|
|
10530
10627
|
// 이벤트 클릭 핸들러
|
|
10531
10628
|
const handleEventClick = React.useCallback((event) => {
|
|
10532
10629
|
setSelectedEvent(event);
|
|
@@ -10686,6 +10783,18 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10686
10783
|
const isCurrentMonth = date.getMonth() === currentMonth;
|
|
10687
10784
|
const isToday = date.toDateString() === today.toDateString();
|
|
10688
10785
|
const isSelected = date.toDateString() === selectedDate.toDateString();
|
|
10786
|
+
// 외부 날짜 숨기기 옵션
|
|
10787
|
+
if (!showOutsideDays && !isCurrentMonth) {
|
|
10788
|
+
continue;
|
|
10789
|
+
}
|
|
10790
|
+
// 날짜 범위 선택 상태 확인
|
|
10791
|
+
const isInRange = selectedDateRange.start && selectedDateRange.end &&
|
|
10792
|
+
date >= selectedDateRange.start && date <= selectedDateRange.end;
|
|
10793
|
+
const isRangeStart = selectedDateRange.start &&
|
|
10794
|
+
date.toDateString() === selectedDateRange.start.toDateString();
|
|
10795
|
+
const isRangeEnd = selectedDateRange.end &&
|
|
10796
|
+
date.toDateString() === selectedDateRange.end.toDateString();
|
|
10797
|
+
const isRangeMiddle = isInRange && !isRangeStart && !isRangeEnd;
|
|
10689
10798
|
// 해당 날짜의 이벤트들
|
|
10690
10799
|
const dayEvents = events.filter(event => {
|
|
10691
10800
|
const eventDate = new Date(event.date);
|
|
@@ -10696,6 +10805,9 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10696
10805
|
'designbase-calendar__day--today': isToday && highlightToday,
|
|
10697
10806
|
'designbase-calendar__day--selected': isSelected,
|
|
10698
10807
|
'designbase-calendar__day--weekend': !showWeekends && (date.getDay() === 0 || date.getDay() === 6),
|
|
10808
|
+
'designbase-calendar__day--selected--start': isRangeStart,
|
|
10809
|
+
'designbase-calendar__day--selected--end': isRangeEnd,
|
|
10810
|
+
'designbase-calendar__day--selected--middle': isRangeMiddle,
|
|
10699
10811
|
}), onClick: () => handleDateClick(date), children: [jsxRuntimeExports.jsx("span", { className: "designbase-calendar__day-number", children: date.getDate() }), dayEvents.length > 0 && (jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__day-events", children: [dayEvents.slice(0, 2).map((event) => (jsxRuntimeExports.jsx("div", { className: clsx('designbase-calendar__event-bar', `designbase-calendar__event-bar--${event.type}`, {
|
|
10700
10812
|
'designbase-calendar__event-bar--dragging': draggedEvent?.id === event.id,
|
|
10701
10813
|
}), style: {
|
|
@@ -10765,7 +10877,7 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10765
10877
|
{ value: 'year', label: '년' },
|
|
10766
10878
|
{ value: 'month', label: '월' },
|
|
10767
10879
|
{ value: 'week', label: '주' },
|
|
10768
|
-
], value: currentView, onChange: (value) => handleViewChange(value), size: "
|
|
10880
|
+
], value: currentView, onChange: (value) => handleViewChange(value), size: "s" })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__body", children: [currentView === 'year' && (jsxRuntimeExports.jsx("div", { className: "designbase-calendar__year-view", children: renderYearView })), currentView === 'month' && (jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__month-view", children: [jsxRuntimeExports.jsx("div", { className: "designbase-calendar__weekdays", children: ['일', '월', '화', '수', '목', '금', '토'].map(day => (jsxRuntimeExports.jsx("div", { className: "designbase-calendar__weekday", children: day }, day))) }), jsxRuntimeExports.jsx("div", { className: "designbase-calendar__days", children: renderMonthView })] })), currentView === 'week' && (jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__week-view", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__week-header", children: [jsxRuntimeExports.jsx("div", { className: "designbase-calendar__time-column-header" }), weekViewData.weekDays] }), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__week-grid", children: [jsxRuntimeExports.jsx("div", { className: "designbase-calendar__time-column", children: weekViewData.timeSlots }), jsxRuntimeExports.jsx("div", { className: "designbase-calendar__week-columns", children: Array.from({ length: 7 }, (_, i) => {
|
|
10769
10881
|
const date = new Date(weekViewData.startOfWeek);
|
|
10770
10882
|
date.setDate(weekViewData.startOfWeek.getDate() + i);
|
|
10771
10883
|
return (jsxRuntimeExports.jsx("div", { className: "designbase-calendar__week-column", children: weekViewData.timeSlots.map((_, index) => {
|
|
@@ -10841,7 +10953,7 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10841
10953
|
}, title: event.title, children: event.title }, event.id));
|
|
10842
10954
|
}) }, index));
|
|
10843
10955
|
}) }, i));
|
|
10844
|
-
}) })] })] }))] }), jsxRuntimeExports.jsxs(Modal, { isOpen: showEventModal, onClose: handleCloseModal, title: isEditing ? '일정 편집' : '새 일정 추가', size: "
|
|
10956
|
+
}) })] })] }))] }), jsxRuntimeExports.jsxs(Modal, { isOpen: showEventModal, onClose: handleCloseModal, title: isEditing ? '일정 편집' : '새 일정 추가', size: "l", children: [jsxRuntimeExports.jsx(ModalBody, { children: jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__event-form", children: [jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__form-row", children: [jsxRuntimeExports.jsx("label", { children: "\uC81C\uBAA9 *" }), jsxRuntimeExports.jsx(Input, { value: eventForm.title, onChange: (value) => setEventForm(prev => ({ ...prev, title: value })), placeholder: "\uC77C\uC815 \uC81C\uBAA9\uC744 \uC785\uB825\uD558\uC138\uC694" })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__form-row", children: [jsxRuntimeExports.jsx("label", { children: "\uC124\uBA85" }), jsxRuntimeExports.jsx(Input, { value: eventForm.description, onChange: (value) => setEventForm(prev => ({ ...prev, description: value })), placeholder: "\uC77C\uC815 \uC124\uBA85\uC744 \uC785\uB825\uD558\uC138\uC694" })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__form-row", children: [jsxRuntimeExports.jsx("label", { children: "\uB0A0\uC9DC" }), jsxRuntimeExports.jsx(Input, { type: "date", value: selectedDate.toISOString().split('T')[0], onChange: (value) => {
|
|
10845
10957
|
const newDate = new Date(value);
|
|
10846
10958
|
setSelectedDate(newDate);
|
|
10847
10959
|
} })] }), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__form-row", children: [jsxRuntimeExports.jsx("label", { children: "\uC77C\uC815 \uD0C0\uC785" }), jsxRuntimeExports.jsx(Select, { value: eventForm.type, onChange: (value) => {
|
|
@@ -10862,7 +10974,9 @@ const Calendar = ({ currentDate = new Date(), view = 'month', events = [], onEve
|
|
|
10862
10974
|
})), placeholder: "\uCC38\uC11D\uC790\uB4E4\uC744 \uC27C\uD45C\uB85C \uAD6C\uBD84\uD558\uC5EC \uC785\uB825\uD558\uC138\uC694" })] })] }) }), jsxRuntimeExports.jsx(ModalFooter, { children: jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__modal-actions", children: [isEditing && (jsxRuntimeExports.jsx(Button, { variant: "danger", onClick: handleDeleteEvent, children: "\uC0AD\uC81C" })), jsxRuntimeExports.jsxs("div", { className: "designbase-calendar__modal-buttons", children: [jsxRuntimeExports.jsx(Button, { variant: "secondary", onClick: handleCloseModal, children: "\uCDE8\uC18C" }), jsxRuntimeExports.jsx(Button, { variant: "primary", onClick: handleSaveEvent, children: isEditing ? '수정' : '추가' })] })] }) })] })] }));
|
|
10863
10975
|
};
|
|
10864
10976
|
|
|
10865
|
-
const Drawer = ({ isOpen, onClose, title, children, position = 'right', size = '
|
|
10977
|
+
const Drawer = ({ isOpen, onClose, title, children, position = 'right', size = 'm', showCloseButton = true, closeOnBackdropClick = true, closeOnEscape = true, animationDuration = 300, showOverlay = true, overlayClosable = true, className, style, zIndex = 1000, trapFocus = true, id, ...props }) => {
|
|
10978
|
+
// 아이콘 크기 계산 (m이 기본값)
|
|
10979
|
+
const iconSize = size === 's' ? 16 : size === 'l' ? 20 : size === 'xl' ? 24 : 18;
|
|
10866
10980
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
10867
10981
|
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
10868
10982
|
const drawerRef = React.useRef(null);
|
|
@@ -10934,7 +11048,7 @@ const Drawer = ({ isOpen, onClose, title, children, position = 'right', size = '
|
|
|
10934
11048
|
'designbase-drawer__overlay--open': isOpen,
|
|
10935
11049
|
}), onClick: handleBackdropClick, "aria-hidden": "true" })), jsxRuntimeExports.jsxs("div", { ref: drawerRef, className: clsx('designbase-drawer__container', `designbase-drawer__container--${position}`, {
|
|
10936
11050
|
'designbase-drawer__container--open': isOpen,
|
|
10937
|
-
}), onClick: handleDrawerClick, role: "dialog", "aria-modal": "true", "aria-labelledby": title ? `${id || 'drawer'}-title` : undefined, "aria-describedby": id ? `${id}-content` : undefined, tabIndex: -1, id: id, children: [(title || showCloseButton) && (jsxRuntimeExports.jsxs("div", { className: "designbase-drawer__header", children: [title && (jsxRuntimeExports.jsx("h2", { className: "designbase-drawer__title", id: id ? `${id}-title` : undefined, children: title })), showCloseButton && (jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "
|
|
11051
|
+
}), onClick: handleDrawerClick, role: "dialog", "aria-modal": "true", "aria-labelledby": title ? `${id || 'drawer'}-title` : undefined, "aria-describedby": id ? `${id}-content` : undefined, tabIndex: -1, id: id, children: [(title || showCloseButton) && (jsxRuntimeExports.jsxs("div", { className: "designbase-drawer__header", children: [title && (jsxRuntimeExports.jsx("h2", { className: "designbase-drawer__title", id: id ? `${id}-title` : undefined, children: title })), showCloseButton && (jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "s", onClick: handleClose, className: "designbase-drawer__close-button", "aria-label": "\uB2EB\uAE30", children: jsxRuntimeExports.jsx(icons.CloseIcon, { size: iconSize, color: "currentColor" }) }))] })), jsxRuntimeExports.jsx("div", { className: "designbase-drawer__content", id: id ? `${id}-content` : undefined, children: children })] })] }), document.body);
|
|
10938
11052
|
};
|
|
10939
11053
|
|
|
10940
11054
|
const ImageList = ({ images, layout = 'grid', columns = 3, spacing = 'md', ratio = '16:9', fit = 'cover', rounded = false, shadow = false, hover = true, clickable = true, lightbox = true, onImageClick, onImageLoad, onImageError, loading = 'lazy', responsive = true, className, style, }) => {
|
|
@@ -11191,7 +11305,7 @@ var classnames = {exports: {}};
|
|
|
11191
11305
|
var classnamesExports = classnames.exports;
|
|
11192
11306
|
var classNames = /*@__PURE__*/getDefaultExportFromCjs(classnamesExports);
|
|
11193
11307
|
|
|
11194
|
-
const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, delay = 0, direction = 'left', size = '
|
|
11308
|
+
const AnimationText = ({ children, type = 'fade', speed = 1000, repeat = 0, delay = 0, direction = 'left', size = 'm', color = 'primary', customColor, weight = 'normal', align = 'left', gradientColors = ['#667eea', '#764ba2'], waveColors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57'], glowColor = '#667eea', clickable = false, disabled = false, className, onClick, }) => {
|
|
11195
11309
|
const [isVisible, setIsVisible] = React.useState(false);
|
|
11196
11310
|
const [currentIndex, setCurrentIndex] = React.useState(0);
|
|
11197
11311
|
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
@@ -11711,81 +11825,14 @@ const ResizablePanels = ({ children, initialWidth = '100%', initialHeight = '100
|
|
|
11711
11825
|
}, children: handleIcon || defaultHandleIcon })] }));
|
|
11712
11826
|
};
|
|
11713
11827
|
|
|
11714
|
-
const ThemeToggle = ({ themes = ['light', 'dark'], defaultTheme = 'light', size = 'md', variant = 'button', onThemeChange, className, }) => {
|
|
11715
|
-
const [currentTheme, setCurrentTheme] = React.useState(defaultTheme);
|
|
11716
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
|
11717
|
-
React.useEffect(() => {
|
|
11718
|
-
// 초기 테마 설정
|
|
11719
|
-
const savedTheme = theme.getTheme();
|
|
11720
|
-
if (savedTheme && themes.includes(savedTheme)) {
|
|
11721
|
-
setCurrentTheme(savedTheme);
|
|
11722
|
-
}
|
|
11723
|
-
}, [themes]);
|
|
11724
|
-
const handleThemeChange = (theme$1) => {
|
|
11725
|
-
theme.setTheme(theme$1);
|
|
11726
|
-
setCurrentTheme(theme$1);
|
|
11727
|
-
setIsOpen(false);
|
|
11728
|
-
onThemeChange?.(theme$1);
|
|
11729
|
-
};
|
|
11730
|
-
const getThemeIcon = (theme) => {
|
|
11731
|
-
switch (theme) {
|
|
11732
|
-
case 'light':
|
|
11733
|
-
return (jsxRuntimeExports.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: [jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "5" }), jsxRuntimeExports.jsx("path", { d: "M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" })] }));
|
|
11734
|
-
case 'dark':
|
|
11735
|
-
return (jsxRuntimeExports.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }));
|
|
11736
|
-
default:
|
|
11737
|
-
return null;
|
|
11738
|
-
}
|
|
11739
|
-
};
|
|
11740
|
-
const getThemeLabel = (theme) => {
|
|
11741
|
-
switch (theme) {
|
|
11742
|
-
case 'light':
|
|
11743
|
-
return '라이트';
|
|
11744
|
-
case 'dark':
|
|
11745
|
-
return '다크';
|
|
11746
|
-
default:
|
|
11747
|
-
return theme;
|
|
11748
|
-
}
|
|
11749
|
-
};
|
|
11750
|
-
const classes = classNames('designbase-theme-toggle', `designbase-theme-toggle--${variant}`, `designbase-theme-toggle--${size}`, className);
|
|
11751
|
-
if (variant === 'button') {
|
|
11752
|
-
return (jsxRuntimeExports.jsx("div", { className: classes, children: themes.map((theme) => (jsxRuntimeExports.jsxs("button", { className: classNames('designbase-theme-toggle__button', {
|
|
11753
|
-
'designbase-theme-toggle__button--active': currentTheme === theme,
|
|
11754
|
-
}), onClick: () => handleThemeChange(theme), title: `${getThemeLabel(theme)} 테마로 변경`, children: [getThemeIcon(theme), jsxRuntimeExports.jsx("span", { className: "designbase-theme-toggle__label", children: getThemeLabel(theme) })] }, theme))) }));
|
|
11755
|
-
}
|
|
11756
|
-
if (variant === 'dropdown') {
|
|
11757
|
-
return (jsxRuntimeExports.jsxs("div", { className: classes, children: [jsxRuntimeExports.jsxs("button", { className: "designbase-theme-toggle__trigger", onClick: () => setIsOpen(!isOpen), title: "\uD14C\uB9C8 \uC120\uD0DD", children: [getThemeIcon(currentTheme), jsxRuntimeExports.jsx("span", { className: "designbase-theme-toggle__label", children: getThemeLabel(currentTheme) }), jsxRuntimeExports.jsx("svg", { className: classNames('designbase-theme-toggle__arrow', { 'designbase-theme-toggle__arrow--open': isOpen }), width: "12", height: "12", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntimeExports.jsx("path", { d: "M7 10l5 5 5-5z" }) })] }), isOpen && (jsxRuntimeExports.jsx("div", { className: "designbase-theme-toggle__dropdown", children: themes.map((theme) => (jsxRuntimeExports.jsxs("button", { className: classNames('designbase-theme-toggle__option', {
|
|
11758
|
-
'designbase-theme-toggle__option--active': currentTheme === theme,
|
|
11759
|
-
}), onClick: () => handleThemeChange(theme), children: [getThemeIcon(theme), jsxRuntimeExports.jsx("span", { children: getThemeLabel(theme) })] }, theme))) }))] }));
|
|
11760
|
-
}
|
|
11761
|
-
if (variant === 'tabs') {
|
|
11762
|
-
return (jsxRuntimeExports.jsx("div", { className: classes, children: themes.map((theme) => (jsxRuntimeExports.jsxs("button", { className: classNames('designbase-theme-toggle__tab', {
|
|
11763
|
-
'designbase-theme-toggle__tab--active': currentTheme === theme,
|
|
11764
|
-
}), onClick: () => handleThemeChange(theme), children: [getThemeIcon(theme), jsxRuntimeExports.jsx("span", { children: getThemeLabel(theme) })] }, theme))) }));
|
|
11765
|
-
}
|
|
11766
|
-
return null;
|
|
11767
|
-
};
|
|
11768
|
-
|
|
11769
11828
|
/**
|
|
11770
11829
|
* Designbase UI 컴포넌트 라이브러리 메인 엔트리 포인트
|
|
11771
11830
|
*
|
|
11772
11831
|
* 목적: 모든 UI 컴포넌트와 타입을 내보냄
|
|
11773
11832
|
* 기능: Tree-shaking 가능한 개별 컴포넌트 내보내기
|
|
11774
|
-
* 사용법: import { Button, Input } from '@
|
|
11833
|
+
* 사용법: import { Button, Input } from '@designbasekorea/ui'
|
|
11775
11834
|
*/
|
|
11776
|
-
// 테마
|
|
11777
|
-
// UI 패키지가 로드될 때 자동으로 토큰 CSS 로드
|
|
11778
|
-
if (typeof document !== 'undefined') {
|
|
11779
|
-
// DOM이 로드된 후 토큰 CSS 로드
|
|
11780
|
-
if (document.readyState === 'loading') {
|
|
11781
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
11782
|
-
theme.loadTokens().catch(console.warn);
|
|
11783
|
-
});
|
|
11784
|
-
}
|
|
11785
|
-
else {
|
|
11786
|
-
theme.loadTokens().catch(console.warn);
|
|
11787
|
-
}
|
|
11788
|
-
}
|
|
11835
|
+
// 테마 CSS 자동 로드 (로컬 복사본 사용)
|
|
11789
11836
|
// 테마 관련 유틸리티 재내보내기
|
|
11790
11837
|
// 임시로 theme 함수들을 정의
|
|
11791
11838
|
const setTheme = (theme) => {
|
|
@@ -11869,7 +11916,6 @@ exports.Table = Table;
|
|
|
11869
11916
|
exports.Tabs = Tabs;
|
|
11870
11917
|
exports.Textarea = Textarea;
|
|
11871
11918
|
exports.TextareaComponent = Textarea;
|
|
11872
|
-
exports.ThemeToggle = ThemeToggle;
|
|
11873
11919
|
exports.TimePicker = TimePicker;
|
|
11874
11920
|
exports.Timeline = Timeline;
|
|
11875
11921
|
exports.Toast = Toast;
|