@designbasekorea/ui 0.5.5 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +63 -4
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +122 -26
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +122 -25
- package/dist/index.js.map +1 -1
- package/dist/index.umd.css +1 -1
- package/dist/index.umd.css.map +1 -1
- package/dist/index.umd.js +122 -25
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4453,7 +4453,7 @@ const Checkbox = React.forwardRef(({ isSelected, defaultSelected, isIndeterminat
|
|
|
4453
4453
|
});
|
|
4454
4454
|
Checkbox.displayName = 'Checkbox';
|
|
4455
4455
|
|
|
4456
|
-
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = icons.SearchIcon, clearIcon: ClearIconComponent = icons.CloseIcon, enableRecentSearches = false, recentSearchesKey = 'searchbar-recent-searches', suggestedSearches = [], suggestionRollingInterval = 5000, onChange, onSearch, onFocus, onBlur, onKeyDown, className, ...rest }) => {
|
|
4456
|
+
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = icons.SearchIcon, clearIcon: ClearIconComponent = icons.CloseIcon, enableRecentSearches = false, recentSearchesKey = 'searchbar-recent-searches', suggestedSearches = [], suggestionRollingInterval = 5000, onChange, onSearch, onFocus, onBlur, onKeyDown, showShortcut = false, shortcutLabel = '⌘K', className, ...rest }) => {
|
|
4457
4457
|
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
4458
4458
|
const [recentSearches, setRecentSearches] = React.useState([]);
|
|
4459
4459
|
const [showRecentSearches, setShowRecentSearches] = React.useState(false);
|
|
@@ -4598,13 +4598,14 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
|
|
|
4598
4598
|
const currentPlaceholder = suggestedSearches.length > 0 && !currentValue && currentValue === ''
|
|
4599
4599
|
? suggestedSearches[currentSuggestion]
|
|
4600
4600
|
: placeholder;
|
|
4601
|
-
|
|
4601
|
+
const shortcutBadgeSize = size === 'l' ? 'm' : 's';
|
|
4602
|
+
return (jsxRuntime.jsxs("div", { className: classes, role: "search", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__container", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__search-icon", children: jsxRuntime.jsx(SearchIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }), jsxRuntime.jsx("input", { ref: inputRef, type: "text", className: inputClasses, value: currentValue, placeholder: currentPlaceholder, disabled: disabled, readOnly: readOnly, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, "aria-label": "\uAC80\uC0C9\uC5B4 \uC785\uB825", ...rest }), showShortcut && !currentValue && !disabled && !readOnly && (jsxRuntime.jsx(Badge, { className: "designbase-search-bar__shortcut-badge", size: shortcutBadgeSize, variant: "secondary", style: "text", "aria-hidden": "true", children: shortcutLabel })), currentValue && currentValue.length > 0 && !disabled && !readOnly && (jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-button", onClick: handleClear, "aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30", children: jsxRuntime.jsx(ClearIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }))] }), showRecentSearches && recentSearches.length > 0 && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-searches", children: [jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-header", children: [jsxRuntime.jsx("span", { className: "designbase-search-bar__recent-title", children: "\uCD5C\uADFC \uAC80\uC0C9\uC5B4" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__clear-all-button", onClick: handleClearAllRecentSearches, "aria-label": "\uBAA8\uB4E0 \uCD5C\uADFC \uAC80\uC0C9\uC5B4 \uC0AD\uC81C", children: "\uC804\uCCB4 \uC0AD\uC81C" })] }), jsxRuntime.jsx("div", { className: "designbase-search-bar__recent-list", children: recentSearches.map((searchTerm, index) => (jsxRuntime.jsxs("div", { className: "designbase-search-bar__recent-item", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-search-button", onClick: () => handleRecentSearchClick(searchTerm), children: searchTerm }), jsxRuntime.jsx("button", { type: "button", className: "designbase-search-bar__recent-remove-button", onClick: () => handleRemoveRecentSearch(searchTerm), "aria-label": `${searchTerm} 삭제`, children: jsxRuntime.jsx(icons.CloseIcon, { size: 16 }) })] }, index))) })] })), suggestedSearches.length > 0 && isFocused && !currentValue && (jsxRuntime.jsxs("div", { className: "designbase-search-bar__suggestions", children: [jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-header", children: jsxRuntime.jsx("span", { className: "designbase-search-bar__suggestions-title", children: "\uCD94\uCC9C \uAC80\uC0C9\uC5B4" }) }), jsxRuntime.jsx("div", { className: "designbase-search-bar__suggestions-list", children: suggestedSearches.map((suggestion, index) => (jsxRuntime.jsx("button", { type: "button", className: clsx('designbase-search-bar__suggestion-item', {
|
|
4602
4603
|
'designbase-search-bar__suggestion-item--active': index === currentSuggestion
|
|
4603
4604
|
}), onClick: () => handleSuggestionClick(suggestion), children: suggestion }, index))) })] }))] }));
|
|
4604
4605
|
};
|
|
4605
4606
|
SearchBar.displayName = 'SearchBar';
|
|
4606
4607
|
|
|
4607
|
-
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', position = 'bottom', maxHeight = 200, showClearButton =
|
|
4608
|
+
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', position = 'bottom', maxHeight = 200, showClearButton = false, useMobileBottomSheet = false, className, onChange, onFocus, onBlur, ...props }) => {
|
|
4608
4609
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
4609
4610
|
const [selectedValue, setSelectedValue] = React.useState(value ?? defaultValue ?? (multiple ? [] : ''));
|
|
4610
4611
|
const [searchTerm, setSearchTerm] = React.useState('');
|
|
@@ -5926,7 +5927,7 @@ const rgbToHsl = (r, g, b) => {
|
|
|
5926
5927
|
return { h, s: s * 100, l: l * 100 };
|
|
5927
5928
|
};
|
|
5928
5929
|
/* ----------------------- 컴포넌트 ----------------------- */
|
|
5929
|
-
const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-
|
|
5930
|
+
const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-start', value, defaultValue = '#006FFF', showInput = true, showAlpha = true, showFormatSelector = true, showCopyButton = true, showEyedropper = true, disabled = false, readonly = false, onChangeFormat = 'hex', fireOnInit = false, changeDebounceMs = 0, emitDuringDrag = true, onChange, onApply, onCancel, className, }) => {
|
|
5930
5931
|
/** 초기 HSV — StrictMode에서도 안전하도록 lazy init */
|
|
5931
5932
|
const initialHex = (isHex(value) ? normalizeHex(value) : normalizeHex(defaultValue)) || '#006FFF';
|
|
5932
5933
|
const initialRgb = hexToRgb(initialHex) || { r: 0, g: 111, b: 255 };
|
|
@@ -6300,14 +6301,14 @@ const ColorPicker = ({ size = 'm', type = 'dropdown', position = 'bottom-left',
|
|
|
6300
6301
|
const Trigger = (jsxRuntime.jsxs("div", { className: "designbase-color-picker__trigger", onClick: () => !disabled && !readonly && (type === 'modal' ? handleModalOpen() : setIsOpen(v => !v)), children: [jsxRuntime.jsx("div", { className: "designbase-color-picker__color-display", children: jsxRuntime.jsx("div", { className: "designbase-color-picker__color-box", style: {
|
|
6301
6302
|
backgroundColor: showAlpha ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${a / 100})` : hex
|
|
6302
6303
|
} }) }), showInput && (jsxRuntime.jsx("input", { type: "text", value: colorInput, onChange: (e) => setColorInput(e.target.value), onKeyDown: onColorKeyDown, onBlur: onColorBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-color-picker__input", placeholder: "#000000" })), showInput && showCopyButton && (jsxRuntime.jsx("button", { type: "button", className: "designbase-color-picker__copy-button-inline", onClick: (e) => { e.stopPropagation(); onCopy(); }, disabled: disabled, "aria-label": "Copy color value", children: isCopied ? jsxRuntime.jsx(icons.DoneIcon, { size: 14 }) : jsxRuntime.jsx(icons.CopyIcon, { size: 14 }) })), jsxRuntime.jsx("button", { type: "button", className: "designbase-color-picker__toggle", disabled: disabled, "aria-label": "Toggle color picker", children: jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] }));
|
|
6303
|
-
const Selector = (jsxRuntime.jsxs("div", { className: "designbase-color-picker__selector", children: [jsxRuntime.jsx("div", { className: "designbase-color-picker__color-area", children: jsxRuntime.jsx("div", { ref: areaRef, className: "designbase-color-picker__color-field", style: areaBackground, onMouseDown: onAreaMouseDown, onMouseMove: onAreaMouseMove, onMouseUp: onAreaMouseUp, onMouseLeave: onAreaLeave, onTouchStart: onAreaTouchStart, onTouchMove: onAreaTouchMove, onTouchEnd: onAreaTouchEnd, children: jsxRuntime.jsx("div", { className: "designbase-color-picker__color-pointer", style: { left: `${s}%`, top: `${100 - v}%`, backgroundColor: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` } }) }) }), jsxRuntime.jsxs("div", { className: "designbase-color-picker__controls", children: [showEyedropper && isEyedropperAvailable && (jsxRuntime.jsx(Button, { variant: "tertiary", size:
|
|
6304
|
+
const Selector = (jsxRuntime.jsxs("div", { className: "designbase-color-picker__selector", children: [jsxRuntime.jsx("div", { className: "designbase-color-picker__color-area", children: jsxRuntime.jsx("div", { ref: areaRef, className: "designbase-color-picker__color-field", style: areaBackground, onMouseDown: onAreaMouseDown, onMouseMove: onAreaMouseMove, onMouseUp: onAreaMouseUp, onMouseLeave: onAreaLeave, onTouchStart: onAreaTouchStart, onTouchMove: onAreaTouchMove, onTouchEnd: onAreaTouchEnd, children: jsxRuntime.jsx("div", { className: "designbase-color-picker__color-pointer", style: { left: `${s}%`, top: `${100 - v}%`, backgroundColor: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` } }) }) }), jsxRuntime.jsxs("div", { className: "designbase-color-picker__controls", children: [showEyedropper && isEyedropperAvailable && (jsxRuntime.jsx(Button, { variant: "tertiary", size: size === 's' ? 's' : 'm', iconOnly: true, onClick: onEyedrop, "aria-label": "Eyedropper tool", children: jsxRuntime.jsx(icons.EyedropperIcon, {}) })), jsxRuntime.jsxs("div", { className: "designbase-color-picker__slider-container", children: [jsxRuntime.jsx("div", { className: "designbase-color-picker__hue-slider", children: jsxRuntime.jsx("input", { type: "range", min: 0, max: 360, value: h, onChange: onHueChange, className: "designbase-color-picker__slider designbase-color-picker__slider--hue", style: hueTrackStyle }) }), showAlpha && (jsxRuntime.jsx("div", { className: "designbase-color-picker__alpha-slider", children: jsxRuntime.jsx("input", { type: "range", min: 0, max: 100, value: a, onChange: onAlphaChange, className: "designbase-color-picker__slider designbase-color-picker__slider--alpha", style: alphaTrackStyle }) }))] })] }), jsxRuntime.jsxs("div", { className: "designbase-color-picker__value-display", children: [showFormatSelector && (jsxRuntime.jsx(Select, { value: format, onChange: (v) => setFormat(v), showClearButton: false, options: [
|
|
6304
6305
|
{ label: 'HEX', value: 'hex' },
|
|
6305
6306
|
{ label: 'RGB', value: 'rgb' },
|
|
6306
6307
|
{ label: 'RGBA', value: 'rgba' },
|
|
6307
6308
|
{ label: 'HSL', value: 'hsl' },
|
|
6308
6309
|
{ label: 'HSLA', value: 'hsla' },
|
|
6309
|
-
], size: "s", position: "top" })), jsxRuntime.jsx(Input, { type: "text", value: colorInput, onChange: setColorInput, onKeyDown: onColorKeyDown, onBlur: onColorBlur, placeholder: "#000000", size: "s", className: "designbase-color-picker__value-input" }), showAlpha && (jsxRuntime.jsxs("div", { className: "designbase-color-picker__alpha-input-wrap", children: [jsxRuntime.jsx(Input, { type: "text", inputMode: "numeric", value: alphaInput, onChange: (value) => setAlphaInput(value.replace(/[^\d]/g, '').slice(0, 3)), onKeyDown: onAlphaInputKeyDown, onBlur: onAlphaInputBlur, placeholder: "100", size: "s", className: "designbase-color-picker__alpha-input", "aria-label": "Alpha percent" }), jsxRuntime.jsx("span", { className: "designbase-color-picker__alpha-suffix", children: "%" })] })), showCopyButton && (jsxRuntime.jsx(Button, { variant: "tertiary", size:
|
|
6310
|
-
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [Trigger, type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: "designbase-color-picker__dropdown", onClick: (e) => e.stopPropagation(), children: Selector })), type === 'modal' && (jsxRuntime.jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC0C9\uC0C1 \uC120\uD0DD", size: "s", children: [jsxRuntime.jsx(ModalBody, { children: Selector }), jsxRuntime.jsx(ModalFooter, { children: jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 8, justifyContent: 'flex-end' }, children: [jsxRuntime.jsx(Button, { variant: "tertiary", size: "m", onClick: handleModalCancel, children: "\uCDE8\uC18C" }), jsxRuntime.jsx(Button, { variant: "primary", size: "m", onClick: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
|
|
6310
|
+
], size: "s", position: "top" })), jsxRuntime.jsx(Input, { type: "text", value: colorInput, onChange: setColorInput, onKeyDown: onColorKeyDown, onBlur: onColorBlur, placeholder: "#000000", size: "s", className: "designbase-color-picker__value-input" }), showAlpha && (jsxRuntime.jsxs("div", { className: "designbase-color-picker__alpha-input-wrap", children: [jsxRuntime.jsx(Input, { type: "text", inputMode: "numeric", value: alphaInput, onChange: (value) => setAlphaInput(value.replace(/[^\d]/g, '').slice(0, 3)), onKeyDown: onAlphaInputKeyDown, onBlur: onAlphaInputBlur, placeholder: "100", size: "s", className: "designbase-color-picker__alpha-input", "aria-label": "Alpha percent" }), jsxRuntime.jsx("span", { className: "designbase-color-picker__alpha-suffix", children: "%" })] })), showCopyButton && (jsxRuntime.jsx(Button, { variant: "tertiary", size: size === 's' ? 's' : 'm', iconOnly: true, onClick: onCopy, "aria-label": "Copy color value", children: isCopied ? jsxRuntime.jsx(icons.DoneIcon, {}) : jsxRuntime.jsx(icons.CopyIcon, {}) }))] })] }));
|
|
6311
|
+
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [Trigger, type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: clsx("designbase-color-picker__dropdown", `designbase-color-picker__dropdown--${position}`), onClick: (e) => e.stopPropagation(), children: Selector })), type === 'modal' && (jsxRuntime.jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC0C9\uC0C1 \uC120\uD0DD", size: "s", children: [jsxRuntime.jsx(ModalBody, { children: Selector }), jsxRuntime.jsx(ModalFooter, { children: jsxRuntime.jsxs("div", { style: { display: 'flex', gap: 8, justifyContent: 'flex-end' }, children: [jsxRuntime.jsx(Button, { variant: "tertiary", size: "m", onClick: handleModalCancel, children: "\uCDE8\uC18C" }), jsxRuntime.jsx(Button, { variant: "primary", size: "m", onClick: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
|
|
6311
6312
|
};
|
|
6312
6313
|
ColorPicker.displayName = 'ColorPicker';
|
|
6313
6314
|
|
|
@@ -6672,7 +6673,7 @@ const ContextMenu = ({ items, open, x, y, onClose, className, }) => {
|
|
|
6672
6673
|
};
|
|
6673
6674
|
ContextMenu.displayName = 'ContextMenu';
|
|
6674
6675
|
|
|
6675
|
-
const DatePicker = ({ mode = 'single', type = 'dropdown', value, defaultValue, 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,
|
|
6676
|
+
const DatePicker = ({ mode = 'single', type = 'dropdown', value, defaultValue, 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, dropdownPosition = 'bottom-start',
|
|
6676
6677
|
// 인라인 모드
|
|
6677
6678
|
inline = false, }) => {
|
|
6678
6679
|
// 아이콘 크기 계산 (m이 기본값)
|
|
@@ -7012,7 +7013,7 @@ inline = false, }) => {
|
|
|
7012
7013
|
'designbase-date-picker--readonly': readonly,
|
|
7013
7014
|
'designbase-date-picker--open': isOpen,
|
|
7014
7015
|
}, className);
|
|
7015
|
-
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-date-picker__trigger", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-date-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.CalendarIcon, { size: 16 }) }), jsxRuntime.jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-date-picker__input", placeholder: "\uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694", "aria-label": "\uB0A0\uC9DC \uC785\uB825" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-date-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: "designbase-date-picker__dropdown", role: "dialog", "aria-modal": "false", children: renderCalendar(false) })), type === 'modal' && (jsxRuntime.jsx(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uB0A0\uC9DC \uC120\uD0DD", size: "s", children: renderCalendar(true) }))] }));
|
|
7016
|
+
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-date-picker__trigger", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-date-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.CalendarIcon, { size: 16 }) }), jsxRuntime.jsx("input", { type: "text", value: inputValue, onChange: handleInputChange, onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-date-picker__input", placeholder: "\uB0A0\uC9DC\uB97C \uC120\uD0DD\uD558\uC138\uC694", "aria-label": "\uB0A0\uC9DC \uC785\uB825" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-date-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uB0A0\uC9DC \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: clsx("designbase-date-picker__dropdown", `designbase-date-picker__dropdown--${dropdownPosition}`), role: "dialog", "aria-modal": "false", children: renderCalendar(false) })), type === 'modal' && (jsxRuntime.jsx(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uB0A0\uC9DC \uC120\uD0DD", size: "s", children: renderCalendar(true) }))] }));
|
|
7016
7017
|
};
|
|
7017
7018
|
|
|
7018
7019
|
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 }) => {
|
|
@@ -7622,7 +7623,7 @@ const Textarea = React.forwardRef(({ label, placeholder, defaultValue, value, si
|
|
|
7622
7623
|
Textarea.displayName = 'Textarea';
|
|
7623
7624
|
|
|
7624
7625
|
const ITEM_HEIGHT = 40;
|
|
7625
|
-
const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:00', format = '24h', minuteStep = 1, disabled = false, readonly = false, onChange, className, }) => {
|
|
7626
|
+
const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:00', format = '24h', minuteStep = 1, disabled = false, readonly = false, dropdownPosition = 'bottom-start', onChange, className, }) => {
|
|
7626
7627
|
const [selectedTime, setSelectedTime] = React.useState(value || defaultValue);
|
|
7627
7628
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
7628
7629
|
const [inputValue, setInputValue] = React.useState(value || defaultValue);
|
|
@@ -7861,7 +7862,7 @@ const TimePicker = ({ size = 'm', type = 'dropdown', value, defaultValue = '12:0
|
|
|
7861
7862
|
}, children: "\uC120\uD0DD" }) }))] }));
|
|
7862
7863
|
};
|
|
7863
7864
|
const classes = clsx('designbase-time-picker', `designbase-time-picker--${size}`, { 'designbase-time-picker--disabled': disabled, 'designbase-time-picker--readonly': readonly, 'designbase-time-picker--open': isOpen }, className);
|
|
7864
|
-
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-time-picker__trigger", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-time-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ClockIcon, { size: 16 }) }), jsxRuntime.jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-time-picker__input", placeholder: is12h ? (showSeconds ? '12:00:00 PM' : '12:00 PM') : (showSeconds ? '12:00:00' : '12:00'), "aria-label": "\uC2DC\uAC04 \uC785\uB825" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-time-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: "designbase-time-picker__dropdown", role: "dialog", "aria-modal": "false", children: renderTimeSelector(false) })), type === 'modal' && (jsxRuntime.jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC2DC\uAC04 \uC120\uD0DD", size: "s", children: [renderTimeSelector(true), jsxRuntime.jsx(ModalFooter, { children: jsxRuntime.jsxs("div", { className: "designbase-time-picker__modal-footer", children: [jsxRuntime.jsx(Button, { variant: "secondary", size: "m", onPress: handleModalCancel, children: "\uCDE8\uC18C" }), jsxRuntime.jsx(Button, { variant: "primary", size: "m", onPress: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
|
|
7865
|
+
return (jsxRuntime.jsxs("div", { ref: pickerRef, className: classes, children: [jsxRuntime.jsxs("div", { className: "designbase-time-picker__trigger", children: [jsxRuntime.jsx("button", { type: "button", className: "designbase-time-picker__icon-display", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ClockIcon, { size: 16 }) }), jsxRuntime.jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), onBlur: handleInputBlur, onClick: (e) => e.stopPropagation(), disabled: disabled, readOnly: readonly, className: "designbase-time-picker__input", placeholder: is12h ? (showSeconds ? '12:00:00 PM' : '12:00 PM') : (showSeconds ? '12:00:00' : '12:00'), "aria-label": "\uC2DC\uAC04 \uC785\uB825" }), jsxRuntime.jsx("button", { type: "button", className: "designbase-time-picker__toggle", onClick: togglePicker, disabled: disabled, "aria-label": "\uC2DC\uAC04 \uC120\uD0DD \uC5F4\uAE30", children: jsxRuntime.jsx(icons.ChevronDownIcon, { size: 16 }) })] }), type === 'dropdown' && isOpen && (jsxRuntime.jsx("div", { className: clsx("designbase-time-picker__dropdown", `designbase-time-picker__dropdown--${dropdownPosition}`), role: "dialog", "aria-modal": "false", children: renderTimeSelector(false) })), type === 'modal' && (jsxRuntime.jsxs(Modal, { isOpen: isOpen, onClose: handleModalCancel, title: "\uC2DC\uAC04 \uC120\uD0DD", size: "s", children: [renderTimeSelector(true), jsxRuntime.jsx(ModalFooter, { children: jsxRuntime.jsxs("div", { className: "designbase-time-picker__modal-footer", children: [jsxRuntime.jsx(Button, { variant: "secondary", size: "m", onPress: handleModalCancel, children: "\uCDE8\uC18C" }), jsxRuntime.jsx(Button, { variant: "primary", size: "m", onPress: handleModalApply, children: "\uC801\uC6A9" })] }) })] }))] }));
|
|
7865
7866
|
};
|
|
7866
7867
|
TimePicker.displayName = 'TimePicker';
|
|
7867
7868
|
|
|
@@ -8598,12 +8599,11 @@ const ImageList = ({ images, layout = 'grid', columns = 3, spacing = 'm', ratio
|
|
|
8598
8599
|
})), currentIndex: selectedImageIndex, isOpen: true, onOpenChange: handleLightboxClose, onImageChange: handleLightboxNavigate }))] }));
|
|
8599
8600
|
};
|
|
8600
8601
|
|
|
8601
|
-
const List = ({ items, size = 'm', variant = '
|
|
8602
|
+
const List = ({ items, size = 'm', variant = 'navigation', itemType = 'default', layout = 'vertical', selectable = false, multiple = false, selectedItems = [], draggable = false, spacing = 's', alignment = 'start', showLeadingIcon = true, showDescription = false, showMeta = false, showBadge = true, showArrow = true, clickableArea = 'item', onItemClick, onItemSelect, onItemDrag, emptyState, loading = false, loadingCount = 3, className, }) => {
|
|
8602
8603
|
const [internalSelectedItems, setInternalSelectedItems] = React.useState(selectedItems);
|
|
8603
8604
|
const [draggedItem, setDraggedItem] = React.useState(null);
|
|
8604
|
-
// 아이콘 크기 계산 (m이 기본값)
|
|
8605
8605
|
const iconSize = size === 's' ? 16 : size === 'l' ? 24 : 20;
|
|
8606
|
-
|
|
8606
|
+
const shouldShowArrow = showArrow;
|
|
8607
8607
|
React.useEffect(() => {
|
|
8608
8608
|
setInternalSelectedItems(selectedItems);
|
|
8609
8609
|
}, [selectedItems]);
|
|
@@ -8614,7 +8614,7 @@ const List = ({ items, size = 'm', variant = 'default', itemType = 'default', la
|
|
|
8614
8614
|
let newSelectedItems;
|
|
8615
8615
|
if (multiple) {
|
|
8616
8616
|
if (internalSelectedItems.includes(item.id)) {
|
|
8617
|
-
newSelectedItems = internalSelectedItems.filter(id => id !== item.id);
|
|
8617
|
+
newSelectedItems = internalSelectedItems.filter((id) => id !== item.id);
|
|
8618
8618
|
}
|
|
8619
8619
|
else {
|
|
8620
8620
|
newSelectedItems = [...internalSelectedItems, item.id];
|
|
@@ -8628,6 +8628,12 @@ const List = ({ items, size = 'm', variant = 'default', itemType = 'default', la
|
|
|
8628
8628
|
}
|
|
8629
8629
|
onItemClick?.(item, index);
|
|
8630
8630
|
};
|
|
8631
|
+
const handleItemKeyDown = (e, item, index) => {
|
|
8632
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
8633
|
+
e.preventDefault();
|
|
8634
|
+
handleItemClick(item, index);
|
|
8635
|
+
}
|
|
8636
|
+
};
|
|
8631
8637
|
const handleItemDragStart = (e, itemId) => {
|
|
8632
8638
|
if (!draggable)
|
|
8633
8639
|
return;
|
|
@@ -8650,9 +8656,7 @@ const List = ({ items, size = 'm', variant = 'default', itemType = 'default', la
|
|
|
8650
8656
|
const handleItemDragEnd = () => {
|
|
8651
8657
|
setDraggedItem(null);
|
|
8652
8658
|
};
|
|
8653
|
-
const isItemSelected = (itemId) =>
|
|
8654
|
-
return internalSelectedItems.includes(itemId);
|
|
8655
|
-
};
|
|
8659
|
+
const isItemSelected = (itemId) => internalSelectedItems.includes(itemId);
|
|
8656
8660
|
const renderBadge = (badge) => {
|
|
8657
8661
|
if (!badge)
|
|
8658
8662
|
return null;
|
|
@@ -8671,17 +8675,38 @@ const List = ({ items, size = 'm', variant = 'default', itemType = 'default', la
|
|
|
8671
8675
|
const renderItem = (item, index) => {
|
|
8672
8676
|
const isSelected = isItemSelected(item.id);
|
|
8673
8677
|
const isDragging = draggedItem === item.id;
|
|
8678
|
+
const isClickable = Boolean(onItemClick || selectable);
|
|
8679
|
+
const hasDescription = showDescription && Boolean(item.description);
|
|
8680
|
+
const hasMeta = showMeta && Boolean(item.meta?.length);
|
|
8681
|
+
const hasSecondaryInfo = hasDescription || hasMeta;
|
|
8682
|
+
const hasLeadingVisual = Boolean(item.image || (showLeadingIcon && item.icon));
|
|
8683
|
+
const hasTrailing = Boolean((showBadge && item.badge) ||
|
|
8684
|
+
item.actions?.length ||
|
|
8685
|
+
shouldShowArrow ||
|
|
8686
|
+
draggable);
|
|
8674
8687
|
const itemClasses = clsx('designbase-list__item', `designbase-list__item--size-${size}`, `designbase-list__item--variant-${variant}`, `designbase-list__item--type-${itemType}`, `designbase-list__item--layout-${layout}`, `designbase-list__item--spacing-${spacing}`, `designbase-list__item--alignment-${alignment}`, {
|
|
8675
8688
|
'designbase-list__item--selected': isSelected,
|
|
8676
8689
|
'designbase-list__item--disabled': item.disabled,
|
|
8677
8690
|
'designbase-list__item--dragging': isDragging,
|
|
8678
|
-
'designbase-list__item--clickable':
|
|
8691
|
+
'designbase-list__item--clickable': isClickable,
|
|
8679
8692
|
'designbase-list__item--draggable': draggable,
|
|
8693
|
+
'designbase-list__item--with-leading': hasLeadingVisual,
|
|
8694
|
+
'designbase-list__item--with-secondary': hasSecondaryInfo,
|
|
8695
|
+
'designbase-list__item--with-trailing': hasTrailing,
|
|
8680
8696
|
});
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8697
|
+
const itemIsInteractive = clickableArea === 'item' && isClickable && !item.disabled;
|
|
8698
|
+
const contentIsInteractive = clickableArea === 'content' && isClickable && !item.disabled;
|
|
8699
|
+
return (jsxRuntime.jsxs("div", { className: itemClasses, onClick: itemIsInteractive ? () => handleItemClick(item, index) : undefined, onKeyDown: itemIsInteractive ? (e) => handleItemKeyDown(e, item, index) : undefined, draggable: draggable, onDragStart: (e) => handleItemDragStart(e, item.id), onDragOver: handleItemDragOver, onDrop: (e) => handleItemDrop(e, item.id), onDragEnd: handleItemDragEnd, role: itemIsInteractive ? 'button' : undefined, tabIndex: itemIsInteractive ? 0 : undefined, "aria-selected": selectable ? isSelected : undefined, children: [selectable && (jsxRuntime.jsx("div", { className: "designbase-list__item-checkbox", onClick: (e) => e.stopPropagation(), children: jsxRuntime.jsx("input", { type: multiple ? 'checkbox' : 'radio', checked: isSelected, onChange: (e) => {
|
|
8700
|
+
e.stopPropagation();
|
|
8701
|
+
handleItemClick(item, index);
|
|
8702
|
+
}, disabled: item.disabled }) })), showLeadingIcon && item.icon && !item.image && (jsxRuntime.jsx("div", { className: "designbase-list__item-icon", children: React.isValidElement(item.icon)
|
|
8703
|
+
? React.cloneElement(item.icon, {
|
|
8704
|
+
size: iconSize,
|
|
8705
|
+
color: 'currentColor',
|
|
8706
|
+
})
|
|
8707
|
+
: item.icon })), item.image && (jsxRuntime.jsx("div", { className: "designbase-list__item-image", children: jsxRuntime.jsx("img", { src: item.image, alt: item.title }) })), jsxRuntime.jsxs("div", { className: clsx('designbase-list__item-content', {
|
|
8708
|
+
'designbase-list__item-content--clickable': contentIsInteractive,
|
|
8709
|
+
}), onClick: contentIsInteractive ? () => handleItemClick(item, index) : undefined, onKeyDown: contentIsInteractive ? (e) => handleItemKeyDown(e, item, index) : undefined, role: contentIsInteractive ? 'button' : undefined, tabIndex: contentIsInteractive ? 0 : undefined, children: [jsxRuntime.jsx("div", { className: "designbase-list__item-header", children: jsxRuntime.jsx("h4", { className: "designbase-list__item-title", children: item.title }) }), hasDescription && jsxRuntime.jsx("p", { className: "designbase-list__item-description", children: item.description }), hasMeta && renderMeta(item.meta)] }), (showBadge && item.badge) || item.actions || shouldShowArrow || draggable ? (jsxRuntime.jsxs("div", { className: "designbase-list__item-trailing", children: [showBadge && item.badge && renderBadge(item.badge), item.actions && renderActions(item.actions), shouldShowArrow && (jsxRuntime.jsx("div", { className: "designbase-list__item-arrow", "aria-hidden": "true", children: jsxRuntime.jsx(icons.ChevronRightIcon, { size: 16 }) })), draggable && jsxRuntime.jsx("div", { className: "designbase-list__item-drag-handle", children: "\u22EE\u22EE" })] })) : null] }, item.id));
|
|
8685
8710
|
};
|
|
8686
8711
|
const renderLoadingSkeleton = () => {
|
|
8687
8712
|
return Array.from({ length: loadingCount }, (_, index) => (jsxRuntime.jsx("div", { className: "designbase-list__item designbase-list__item--loading", children: jsxRuntime.jsxs("div", { className: "designbase-list__item-skeleton", children: [jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-icon" }), jsxRuntime.jsxs("div", { className: "designbase-list__item-skeleton-content", children: [jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-title" }), jsxRuntime.jsx("div", { className: "designbase-list__item-skeleton-description" })] })] }) }, index)));
|
|
@@ -8693,12 +8718,12 @@ const List = ({ items, size = 'm', variant = 'default', itemType = 'default', la
|
|
|
8693
8718
|
'designbase-list--loading': loading,
|
|
8694
8719
|
}, className);
|
|
8695
8720
|
if (loading) {
|
|
8696
|
-
return
|
|
8721
|
+
return jsxRuntime.jsx("div", { className: classes, children: renderLoadingSkeleton() });
|
|
8697
8722
|
}
|
|
8698
8723
|
if (items.length === 0 && emptyState) {
|
|
8699
8724
|
return (jsxRuntime.jsx("div", { className: classes, children: jsxRuntime.jsx("div", { className: "designbase-list__empty", children: emptyState }) }));
|
|
8700
8725
|
}
|
|
8701
|
-
return
|
|
8726
|
+
return jsxRuntime.jsx("div", { className: classes, children: items.map((item, index) => renderItem(item, index)) });
|
|
8702
8727
|
};
|
|
8703
8728
|
|
|
8704
8729
|
const DesignBaseLogo = ({ width = 193, height = 40, color, className, }) => {
|
|
@@ -8786,6 +8811,77 @@ const Logo = ({ type = 'designbase', text = 'Logo', src, alt, size = 'm', varian
|
|
|
8786
8811
|
};
|
|
8787
8812
|
Logo.displayName = 'Logo';
|
|
8788
8813
|
|
|
8814
|
+
const Marquee = ({ children, items, direction = 'left', duration = 20, speed = 1, size = 'm', variant = 'default', bordered, pauseOnHover = true, fadeEdges = false, fadeWidth = 48, edgePadding, gap = 24, alignY = 'center', className, ariaLabel = 'Scrolling content', }) => {
|
|
8815
|
+
const containerRef = React.useRef(null);
|
|
8816
|
+
const baseGroupRef = React.useRef(null);
|
|
8817
|
+
const [containerWidth, setContainerWidth] = React.useState(0);
|
|
8818
|
+
const [baseGroupWidth, setBaseGroupWidth] = React.useState(0);
|
|
8819
|
+
const resolvedItems = React.useMemo(() => ((items && items.length > 0) ? items : (children ? [children] : [])), [items, children]);
|
|
8820
|
+
if (resolvedItems.length === 0) {
|
|
8821
|
+
return null;
|
|
8822
|
+
}
|
|
8823
|
+
const resolvedSpeed = Number.isFinite(speed) && speed > 0 ? speed : 1;
|
|
8824
|
+
const resolvedDuration = Math.max(duration, 1) / resolvedSpeed;
|
|
8825
|
+
const resolvedFadeWidth = Math.max(fadeWidth, 0);
|
|
8826
|
+
const resolvedEdgePadding = edgePadding !== undefined
|
|
8827
|
+
? Math.max(edgePadding, 0)
|
|
8828
|
+
: (fadeEdges ? resolvedFadeWidth : 0);
|
|
8829
|
+
const resolvedGap = Math.max(gap, 0);
|
|
8830
|
+
React.useEffect(() => {
|
|
8831
|
+
const updateSize = () => {
|
|
8832
|
+
const nextContainerWidth = Math.ceil(containerRef.current?.clientWidth ?? 0);
|
|
8833
|
+
const nextBaseGroupWidth = Math.ceil(baseGroupRef.current?.scrollWidth ?? 0);
|
|
8834
|
+
setContainerWidth((prev) => (prev !== nextContainerWidth ? nextContainerWidth : prev));
|
|
8835
|
+
setBaseGroupWidth((prev) => (prev !== nextBaseGroupWidth ? nextBaseGroupWidth : prev));
|
|
8836
|
+
};
|
|
8837
|
+
updateSize();
|
|
8838
|
+
const observer = new ResizeObserver(updateSize);
|
|
8839
|
+
if (containerRef.current)
|
|
8840
|
+
observer.observe(containerRef.current);
|
|
8841
|
+
if (baseGroupRef.current)
|
|
8842
|
+
observer.observe(baseGroupRef.current);
|
|
8843
|
+
const images = baseGroupRef.current?.querySelectorAll('img') ?? [];
|
|
8844
|
+
images.forEach((img) => {
|
|
8845
|
+
img.addEventListener('load', updateSize);
|
|
8846
|
+
img.addEventListener('error', updateSize);
|
|
8847
|
+
});
|
|
8848
|
+
return () => {
|
|
8849
|
+
observer.disconnect();
|
|
8850
|
+
images.forEach((img) => {
|
|
8851
|
+
img.removeEventListener('load', updateSize);
|
|
8852
|
+
img.removeEventListener('error', updateSize);
|
|
8853
|
+
});
|
|
8854
|
+
};
|
|
8855
|
+
}, [resolvedItems, resolvedGap, size, fadeEdges, resolvedEdgePadding]);
|
|
8856
|
+
const duplicateCount = React.useMemo(() => {
|
|
8857
|
+
if (baseGroupWidth <= 0)
|
|
8858
|
+
return 1;
|
|
8859
|
+
return Math.max(1, Math.ceil(containerWidth / baseGroupWidth));
|
|
8860
|
+
}, [containerWidth, baseGroupWidth]);
|
|
8861
|
+
const isReady = baseGroupWidth > 0;
|
|
8862
|
+
const classes = clsx('designbase-marquee', `designbase-marquee--size-${size}`, `designbase-marquee--variant-${variant}`, `designbase-marquee--align-${alignY}`, {
|
|
8863
|
+
'designbase-marquee--pause-on-hover': pauseOnHover,
|
|
8864
|
+
'designbase-marquee--fade-edges': fadeEdges,
|
|
8865
|
+
'designbase-marquee--right': direction === 'right',
|
|
8866
|
+
'designbase-marquee--bordered': bordered ?? variant === 'outlined',
|
|
8867
|
+
'designbase-marquee--ready': isReady,
|
|
8868
|
+
}, className);
|
|
8869
|
+
const style = {
|
|
8870
|
+
'--db-marquee-duration': `${resolvedDuration}s`,
|
|
8871
|
+
// 그룹간 간격까지 포함해 이동 거리를 맞춰야 루프 경계 점프가 사라짐
|
|
8872
|
+
'--db-marquee-shift': `${baseGroupWidth + resolvedGap}px`,
|
|
8873
|
+
'--db-marquee-gap': `${resolvedGap}px`,
|
|
8874
|
+
'--db-marquee-fade-width': `${resolvedFadeWidth}px`,
|
|
8875
|
+
'--db-marquee-edge-padding': `${resolvedEdgePadding}px`,
|
|
8876
|
+
};
|
|
8877
|
+
const screenReaderText = (items && items.length > 0)
|
|
8878
|
+
? items.filter((item) => typeof item === 'string').join(' • ') || ariaLabel
|
|
8879
|
+
: (typeof children === 'string' ? children : ariaLabel);
|
|
8880
|
+
const renderGroup = (key, ref) => (jsxRuntime.jsx("div", { className: "designbase-marquee__group", "aria-hidden": "true", ref: ref, children: resolvedItems.map((item, index) => (jsxRuntime.jsx("div", { className: "designbase-marquee__item", children: item }, `${key}-${index}`))) }, key));
|
|
8881
|
+
return (jsxRuntime.jsxs("div", { className: classes, style: style, role: "region", "aria-label": ariaLabel, ref: containerRef, children: [jsxRuntime.jsx("span", { className: "designbase-marquee__sr-only", children: screenReaderText }), jsxRuntime.jsxs("div", { className: "designbase-marquee__track", children: [renderGroup('base', baseGroupRef), Array.from({ length: duplicateCount }).map((_, index) => renderGroup(`dup-${index}`))] })] }));
|
|
8882
|
+
};
|
|
8883
|
+
Marquee.displayName = 'Marquee';
|
|
8884
|
+
|
|
8789
8885
|
const MarkdownEditor = ({ size = 'm', variant = 'default', mode = 'preview', // 기본값을 preview로 변경
|
|
8790
8886
|
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초
|
|
8791
8887
|
onFileUpload, onChange, onSave, onFocus, onBlur, className, }) => {
|
|
@@ -12597,6 +12693,7 @@ exports.Lightbox = Lightbox;
|
|
|
12597
12693
|
exports.List = List;
|
|
12598
12694
|
exports.Logo = Logo;
|
|
12599
12695
|
exports.MarkdownEditor = MarkdownEditor;
|
|
12696
|
+
exports.Marquee = Marquee;
|
|
12600
12697
|
exports.Masonry = Masonry;
|
|
12601
12698
|
exports.MenuItem = MenuItem;
|
|
12602
12699
|
exports.Modal = Modal;
|