@designbasekorea/ui 0.1.41 → 0.1.43
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 +8 -0
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.css.map +1 -1
- package/dist/index.esm.js +127 -25
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +126 -24
- 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 +126 -24
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import React, { useState, useCallback, useEffect, useRef, useMemo, useContext, forwardRef, useId, useLayoutEffect } from 'react';
|
|
3
|
-
import { ChevronDownIcon, StarIcon, TrendingUpIcon, StarFilledIcon, CartIcon, CloseIcon, ArrowRightIcon, InfoFilledIcon, ErrorFilledIcon, WarningFilledIcon, CircleCheckFilledIcon, RefreshIcon, ChevronLeftIcon, PauseIcon, PlayIcon, ChevronRightIcon, RepeatIcon, MuteFilledIcon, VolumeUpIcon, SettingsIcon, UserIcon, HideIcon, ShowIcon, SearchIcon, ChevronUpIcon, GalleryIcon, HeartIcon, BookmarkIcon, ShareAltIcon, DownloadIcon, ArrowLeftIcon, ShrinkIcon, ExpandIcon, DoneIcon as DoneIcon$1, CopyIcon, BulbIcon, CloudCloseIcon, BellActiveIcon, AwardIcon, CalendarIcon, PlusIcon, ErrorIcon, ClockIcon, MinusIcon as MinusIcon$1, VideoIcon, CodeIcon, WriteIcon, UploadIcon, ArrowBarLeftIcon, ArrowBarRightIcon, StarHalfIcon, MoveIcon, MoreVerticalIcon, ArrowDownIcon, ArrowUpLeftIcon, ArrowUpRightIcon, ArrowDownLeftIcon, ArrowDownRightIcon, FacebookIcon,
|
|
3
|
+
import { ChevronDownIcon, StarIcon, TrendingUpIcon, StarFilledIcon, CartIcon, CloseIcon, ArrowRightIcon, InfoFilledIcon, ErrorFilledIcon, WarningFilledIcon, CircleCheckFilledIcon, RefreshIcon, ChevronLeftIcon, PauseIcon, PlayIcon, ChevronRightIcon, RepeatIcon, MuteFilledIcon, VolumeUpIcon, SettingsIcon, UserIcon, HideIcon, ShowIcon, SearchIcon, ChevronUpIcon, GalleryIcon, HeartIcon, BookmarkIcon, ShareAltIcon, DownloadIcon, ArrowLeftIcon, ShrinkIcon, ExpandIcon, DoneIcon as DoneIcon$1, CopyIcon, BulbIcon, CloudCloseIcon, BellActiveIcon, AwardIcon, CalendarIcon, PlusIcon, ErrorIcon, ClockIcon, MinusIcon as MinusIcon$1, VideoIcon, CodeIcon, WriteIcon, UploadIcon, XIcon, ArrowBarLeftIcon, ArrowBarRightIcon, StarHalfIcon, MoveIcon, MoreVerticalIcon, ArrowDownIcon, ArrowUpLeftIcon, ArrowUpRightIcon, ArrowDownLeftIcon, ArrowDownRightIcon, FacebookIcon, InstagramIcon, LinkedinIcon, PinterestIcon, WhatsappIcon, TelegramIcon, MailIcon, LinkIcon, ScanQrcodeIcon, VerticalArrowsIcon, CaretUpdownFilledIcon } from '@designbasekorea/icons';
|
|
4
4
|
import { flushSync, createPortal } from 'react-dom';
|
|
5
5
|
|
|
6
6
|
function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
|
|
@@ -2265,49 +2265,49 @@ Button.displayName = 'Button';
|
|
|
2265
2265
|
// 톤별 색상 팔레트
|
|
2266
2266
|
const colorPalettes = {
|
|
2267
2267
|
primary: {
|
|
2268
|
-
light: ['#
|
|
2268
|
+
light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd', '#60a5fa'], // blue-50 ~ blue-400 (더 밝게)
|
|
2269
2269
|
vivid: ['#3b82f6', '#2563eb', '#1d4ed8', '#1e40af', '#1e3a8a'], // blue-500 ~ blue-900
|
|
2270
|
-
dark: ['#
|
|
2270
|
+
dark: ['#0f172a', '#1e293b', '#334155', '#475569', '#64748b'], // slate-900 ~ slate-600 (더 어둡게)
|
|
2271
2271
|
},
|
|
2272
2272
|
secondary: {
|
|
2273
|
-
light: ['#
|
|
2273
|
+
light: ['#f8fafc', '#f1f5f9', '#e2e8f0', '#cbd5e1', '#94a3b8'], // slate-50 ~ slate-400 (더 밝게)
|
|
2274
2274
|
vivid: ['#6b7280', '#4b5563', '#374151', '#1f2937', '#111827'], // gray-500 ~ gray-900
|
|
2275
|
-
dark: ['#
|
|
2275
|
+
dark: ['#0f0f0f', '#1a1a1a', '#262626', '#404040', '#525252'], // neutral-950 ~ neutral-600 (더 어둡게)
|
|
2276
2276
|
},
|
|
2277
2277
|
success: {
|
|
2278
|
-
light: ['#
|
|
2278
|
+
light: ['#f0fdf4', '#dcfce7', '#bbf7d0', '#86efac', '#4ade80'], // green-50 ~ green-400 (더 밝게)
|
|
2279
2279
|
vivid: ['#22c55e', '#16a34a', '#15803d', '#166534', '#14532d'], // green-500 ~ green-900
|
|
2280
|
-
dark: ['#
|
|
2280
|
+
dark: ['#052e16', '#14532d', '#166534', '#15803d', '#16a34a'], // green-950 ~ green-600 (더 어둡게)
|
|
2281
2281
|
},
|
|
2282
2282
|
warning: {
|
|
2283
|
-
light: ['#
|
|
2284
|
-
vivid: ['#f59e0b', '#d97706', '#b45309', '#92400e', '#78350f'], //
|
|
2285
|
-
dark: ['#
|
|
2283
|
+
light: ['#fffbeb', '#fef3c7', '#fde68a', '#fcd34d', '#fbbf24'], // amber-50 ~ amber-400 (더 밝게)
|
|
2284
|
+
vivid: ['#f59e0b', '#d97706', '#b45309', '#92400e', '#78350f'], // amber-600 ~ amber-900
|
|
2285
|
+
dark: ['#451a03', '#78350f', '#92400e', '#b45309', '#d97706'], // amber-950 ~ amber-600 (더 어둡게)
|
|
2286
2286
|
},
|
|
2287
2287
|
error: {
|
|
2288
|
-
light: ['#
|
|
2288
|
+
light: ['#fef2f2', '#fecaca', '#fca5a5', '#f87171', '#f56565'], // red-50 ~ red-400 (더 밝게)
|
|
2289
2289
|
vivid: ['#ef4444', '#dc2626', '#b91c1c', '#991b1b', '#7f1d1d'], // red-500 ~ red-900
|
|
2290
|
-
dark: ['#
|
|
2290
|
+
dark: ['#450a0a', '#7f1d1d', '#991b1b', '#b91c1c', '#dc2626'], // red-950 ~ red-600 (더 어둡게)
|
|
2291
2291
|
},
|
|
2292
2292
|
info: {
|
|
2293
|
-
light: ['#
|
|
2293
|
+
light: ['#eff6ff', '#dbeafe', '#bfdbfe', '#93c5fd', '#60a5fa'], // blue-50 ~ blue-400 (더 밝게)
|
|
2294
2294
|
vivid: ['#3b82f6', '#2563eb', '#1d4ed8', '#1e40af', '#1e3a8a'], // blue-500 ~ blue-900
|
|
2295
|
-
dark: ['#
|
|
2295
|
+
dark: ['#0f172a', '#1e293b', '#334155', '#475569', '#64748b'], // slate-900 ~ slate-600 (더 어둡게)
|
|
2296
2296
|
},
|
|
2297
2297
|
purple: {
|
|
2298
|
-
light: ['#
|
|
2298
|
+
light: ['#faf5ff', '#f3e8ff', '#e9d5ff', '#d8b4fe', '#c084fc'], // purple-50 ~ purple-400 (더 밝게)
|
|
2299
2299
|
vivid: ['#a855f7', '#9333ea', '#7c3aed', '#6d28d9', '#5b21b6'], // purple-600 ~ purple-900
|
|
2300
|
-
dark: ['#
|
|
2300
|
+
dark: ['#3b0764', '#581c87', '#6b21a8', '#7c3aed', '#9333ea'], // purple-950 ~ purple-600 (더 어둡게)
|
|
2301
2301
|
},
|
|
2302
2302
|
ocean: {
|
|
2303
|
-
light: ['#
|
|
2303
|
+
light: ['#f0fdfa', '#ccfbf1', '#99f6e4', '#5eead4', '#2dd4bf'], // teal-50 ~ teal-400 (더 밝게)
|
|
2304
2304
|
vivid: ['#14b8a6', '#0d9488', '#0f766e', '#115e59', '#134e4a'], // teal-500 ~ teal-900
|
|
2305
|
-
dark: ['#
|
|
2305
|
+
dark: ['#042f2e', '#134e4a', '#115e59', '#0f766e', '#0d9488'], // teal-950 ~ teal-600 (더 어둡게)
|
|
2306
2306
|
},
|
|
2307
2307
|
sunset: {
|
|
2308
|
-
light: ['#
|
|
2308
|
+
light: ['#fff7ed', '#fed7aa', '#fdba74', '#fb923c', '#f97316'], // orange-50 ~ orange-500 (더 밝게)
|
|
2309
2309
|
vivid: ['#f97316', '#ea580c', '#c2410c', '#9a3412', '#7c2d12'], // orange-600 ~ orange-900
|
|
2310
|
-
dark: ['#
|
|
2310
|
+
dark: ['#431407', '#7c2d12', '#9a3412', '#c2410c', '#ea580c'], // orange-950 ~ orange-600 (더 어둡게)
|
|
2311
2311
|
},
|
|
2312
2312
|
};
|
|
2313
2313
|
const RandomGradient = ({ scheme = 'primary', tone = 'vivid', width = '100%', height = '600px', blur = 60, colorCount = 4, animated = false, animationDuration = 10, overlay = true, overlayOpacity = 0.2, children, className, }) => {
|
|
@@ -8144,10 +8144,48 @@ const Masonry = ({ images, columns = 3, spacing = 'm', ratio = 'auto', fit = 'co
|
|
|
8144
8144
|
})), currentIndex: selectedImageIndex, isOpen: true, onOpenChange: handleLightboxClose, onImageChange: handleLightboxNavigate }))] }));
|
|
8145
8145
|
};
|
|
8146
8146
|
|
|
8147
|
-
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = SearchIcon, clearIcon: ClearIconComponent = CloseIcon, onChange, onSearch, onFocus, onBlur, onKeyDown, className, ...props }) => {
|
|
8147
|
+
const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size = 'm', variant = 'default', disabled = false, readOnly = false, fullWidth = false, searchIcon: SearchIconComponent = SearchIcon, clearIcon: ClearIconComponent = CloseIcon, enableRecentSearches = false, recentSearchesKey = 'searchbar-recent-searches', suggestedSearches = [], suggestionRollingInterval = 5000, onChange, onSearch, onFocus, onBlur, onKeyDown, className, ...props }) => {
|
|
8148
8148
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
8149
|
+
const [recentSearches, setRecentSearches] = useState([]);
|
|
8150
|
+
const [showRecentSearches, setShowRecentSearches] = useState(false);
|
|
8151
|
+
const [currentSuggestion, setCurrentSuggestion] = useState(0);
|
|
8152
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
8149
8153
|
const inputRef = useRef(null);
|
|
8154
|
+
const suggestionIntervalRef = useRef(null);
|
|
8150
8155
|
const currentValue = value !== undefined ? value : internalValue;
|
|
8156
|
+
// 최근 검색어 로드
|
|
8157
|
+
useEffect(() => {
|
|
8158
|
+
if (enableRecentSearches) {
|
|
8159
|
+
try {
|
|
8160
|
+
const stored = localStorage.getItem(recentSearchesKey);
|
|
8161
|
+
if (stored) {
|
|
8162
|
+
setRecentSearches(JSON.parse(stored));
|
|
8163
|
+
}
|
|
8164
|
+
}
|
|
8165
|
+
catch (error) {
|
|
8166
|
+
console.warn('최근 검색어를 불러올 수 없습니다:', error);
|
|
8167
|
+
}
|
|
8168
|
+
}
|
|
8169
|
+
}, [enableRecentSearches, recentSearchesKey]);
|
|
8170
|
+
// 추천 검색어 롤링
|
|
8171
|
+
useEffect(() => {
|
|
8172
|
+
if (suggestedSearches.length > 0 && isFocused && !currentValue) {
|
|
8173
|
+
suggestionIntervalRef.current = setInterval(() => {
|
|
8174
|
+
setCurrentSuggestion(prev => (prev + 1) % suggestedSearches.length);
|
|
8175
|
+
}, suggestionRollingInterval);
|
|
8176
|
+
}
|
|
8177
|
+
else {
|
|
8178
|
+
if (suggestionIntervalRef.current) {
|
|
8179
|
+
clearInterval(suggestionIntervalRef.current);
|
|
8180
|
+
suggestionIntervalRef.current = null;
|
|
8181
|
+
}
|
|
8182
|
+
}
|
|
8183
|
+
return () => {
|
|
8184
|
+
if (suggestionIntervalRef.current) {
|
|
8185
|
+
clearInterval(suggestionIntervalRef.current);
|
|
8186
|
+
}
|
|
8187
|
+
};
|
|
8188
|
+
}, [suggestedSearches.length, isFocused, currentValue, suggestionRollingInterval]);
|
|
8151
8189
|
useEffect(() => {
|
|
8152
8190
|
if (value !== undefined) {
|
|
8153
8191
|
setInternalValue(value);
|
|
@@ -8163,9 +8201,24 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
|
|
|
8163
8201
|
onChange?.('');
|
|
8164
8202
|
inputRef.current?.focus();
|
|
8165
8203
|
};
|
|
8166
|
-
const handleSearch = () => {
|
|
8167
|
-
|
|
8168
|
-
|
|
8204
|
+
const handleSearch = (searchValue) => {
|
|
8205
|
+
const searchTerm = searchValue || currentValue.trim();
|
|
8206
|
+
if (searchTerm) {
|
|
8207
|
+
onSearch?.(searchTerm);
|
|
8208
|
+
// 최근 검색어 저장
|
|
8209
|
+
if (enableRecentSearches) {
|
|
8210
|
+
const newRecentSearches = [
|
|
8211
|
+
searchTerm,
|
|
8212
|
+
...recentSearches.filter(item => item !== searchTerm)
|
|
8213
|
+
].slice(0, 10); // 최대 10개
|
|
8214
|
+
setRecentSearches(newRecentSearches);
|
|
8215
|
+
try {
|
|
8216
|
+
localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
|
|
8217
|
+
}
|
|
8218
|
+
catch (error) {
|
|
8219
|
+
console.warn('최근 검색어를 저장할 수 없습니다:', error);
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8169
8222
|
}
|
|
8170
8223
|
};
|
|
8171
8224
|
const handleKeyDown = (e) => {
|
|
@@ -8174,6 +8227,49 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
|
|
|
8174
8227
|
}
|
|
8175
8228
|
onKeyDown?.(e);
|
|
8176
8229
|
};
|
|
8230
|
+
const handleFocus = (e) => {
|
|
8231
|
+
setIsFocused(true);
|
|
8232
|
+
setShowRecentSearches(enableRecentSearches && recentSearches.length > 0);
|
|
8233
|
+
onFocus?.(e);
|
|
8234
|
+
};
|
|
8235
|
+
const handleBlur = (e) => {
|
|
8236
|
+
setIsFocused(false);
|
|
8237
|
+
// 약간의 지연을 두어 클릭 이벤트가 처리되도록 함
|
|
8238
|
+
setTimeout(() => {
|
|
8239
|
+
setShowRecentSearches(false);
|
|
8240
|
+
}, 200);
|
|
8241
|
+
onBlur?.(e);
|
|
8242
|
+
};
|
|
8243
|
+
const handleRecentSearchClick = (searchTerm) => {
|
|
8244
|
+
setInternalValue(searchTerm);
|
|
8245
|
+
onChange?.(searchTerm);
|
|
8246
|
+
setShowRecentSearches(false);
|
|
8247
|
+
handleSearch(searchTerm);
|
|
8248
|
+
};
|
|
8249
|
+
const handleRemoveRecentSearch = (searchTerm) => {
|
|
8250
|
+
const newRecentSearches = recentSearches.filter(item => item !== searchTerm);
|
|
8251
|
+
setRecentSearches(newRecentSearches);
|
|
8252
|
+
try {
|
|
8253
|
+
localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
|
|
8254
|
+
}
|
|
8255
|
+
catch (error) {
|
|
8256
|
+
console.warn('최근 검색어를 삭제할 수 없습니다:', error);
|
|
8257
|
+
}
|
|
8258
|
+
};
|
|
8259
|
+
const handleClearAllRecentSearches = () => {
|
|
8260
|
+
setRecentSearches([]);
|
|
8261
|
+
try {
|
|
8262
|
+
localStorage.removeItem(recentSearchesKey);
|
|
8263
|
+
}
|
|
8264
|
+
catch (error) {
|
|
8265
|
+
console.warn('최근 검색어를 모두 삭제할 수 없습니다:', error);
|
|
8266
|
+
}
|
|
8267
|
+
};
|
|
8268
|
+
const handleSuggestionClick = (suggestion) => {
|
|
8269
|
+
setInternalValue(suggestion);
|
|
8270
|
+
onChange?.(suggestion);
|
|
8271
|
+
handleSearch(suggestion);
|
|
8272
|
+
};
|
|
8177
8273
|
const classes = clsx('designbase-search-bar', `designbase-search-bar--${size}`, `designbase-search-bar--${variant}`, {
|
|
8178
8274
|
'designbase-search-bar--disabled': disabled,
|
|
8179
8275
|
'designbase-search-bar--readonly': readOnly,
|
|
@@ -8184,7 +8280,13 @@ const SearchBar = ({ value, defaultValue = '', placeholder = '검색...', size =
|
|
|
8184
8280
|
'designbase-search-bar__input--disabled': disabled,
|
|
8185
8281
|
'designbase-search-bar__input--readonly': readOnly,
|
|
8186
8282
|
});
|
|
8187
|
-
|
|
8283
|
+
// 현재 플레이스홀더 (추천 검색어가 있으면 롤링)
|
|
8284
|
+
const currentPlaceholder = suggestedSearches.length > 0 && isFocused && !currentValue
|
|
8285
|
+
? suggestedSearches[currentSuggestion]
|
|
8286
|
+
: placeholder;
|
|
8287
|
+
return (jsxs("div", { className: classes, role: "search", children: [jsxs("div", { className: "designbase-search-bar__container", children: [jsx("div", { className: "designbase-search-bar__search-icon", children: jsx(SearchIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }), 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", ...props }), currentValue && currentValue.length > 0 && !disabled && !readOnly && (jsx("button", { type: "button", className: "designbase-search-bar__clear-button", onClick: handleClear, "aria-label": "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30", children: jsx(ClearIconComponent, { size: size === 's' ? 16 : size === 'l' ? 24 : 20 }) }))] }), showRecentSearches && recentSearches.length > 0 && (jsxs("div", { className: "designbase-search-bar__recent-searches", children: [jsxs("div", { className: "designbase-search-bar__recent-header", children: [jsx("span", { className: "designbase-search-bar__recent-title", children: "\uCD5C\uADFC \uAC80\uC0C9\uC5B4" }), 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" })] }), jsx("div", { className: "designbase-search-bar__recent-list", children: recentSearches.map((searchTerm, index) => (jsxs("div", { className: "designbase-search-bar__recent-item", children: [jsx("button", { type: "button", className: "designbase-search-bar__recent-search-button", onClick: () => handleRecentSearchClick(searchTerm), children: searchTerm }), jsx("button", { type: "button", className: "designbase-search-bar__recent-remove-button", onClick: () => handleRemoveRecentSearch(searchTerm), "aria-label": `${searchTerm} 삭제`, children: jsx(XIcon, { size: 16 }) })] }, index))) })] })), suggestedSearches.length > 0 && isFocused && !currentValue && (jsxs("div", { className: "designbase-search-bar__suggestions", children: [jsx("div", { className: "designbase-search-bar__suggestions-header", children: jsx("span", { className: "designbase-search-bar__suggestions-title", children: "\uCD94\uCC9C \uAC80\uC0C9\uC5B4" }) }), jsx("div", { className: "designbase-search-bar__suggestions-list", children: suggestedSearches.map((suggestion, index) => (jsx("button", { type: "button", className: clsx('designbase-search-bar__suggestion-item', {
|
|
8288
|
+
'designbase-search-bar__suggestion-item--active': index === currentSuggestion
|
|
8289
|
+
}), onClick: () => handleSuggestionClick(suggestion), children: suggestion }, index))) })] }))] }));
|
|
8188
8290
|
};
|
|
8189
8291
|
SearchBar.displayName = 'SearchBar';
|
|
8190
8292
|
|