@designbasekorea/ui 0.2.41 → 0.3.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/dist/index.esm.js CHANGED
@@ -2402,7 +2402,7 @@ const Tooltip = ({ content, children, position = 'top', size = 'm', variant = 'd
2402
2402
  };
2403
2403
  Tooltip.displayName = 'Tooltip';
2404
2404
 
2405
- const Button = forwardRef(({ variant = 'primary', size = 'm', radius, fullWidth = false, disabled = false, loading = false, iconOnly = false, startIcon: StartIcon, endIcon: EndIcon, tooltip, tooltipProps, className, children, onPress, type = 'button', ...props }, forwardedRef) => {
2405
+ const Button = forwardRef(({ variant = 'primary', size = 'm', radius, fullWidth = false, disabled = false, loading = false, loadingText, iconOnly = false, startIcon: StartIcon, endIcon: EndIcon, tooltip, tooltipProps, className, children, onPress, type = 'button', ...props }, forwardedRef) => {
2406
2406
  const ref = $df56164dff5785e2$export$4338b53315abf666(forwardedRef);
2407
2407
  const { buttonProps } = $701a24aa0da5b062$export$ea18c227d4417cc3({
2408
2408
  ...props,
@@ -2416,23 +2416,18 @@ const Button = forwardRef(({ variant = 'primary', size = 'm', radius, fullWidth
2416
2416
  return `designbase-button--radius-${radius}`;
2417
2417
  }
2418
2418
  // 아이콘 전용 버튼도 일반 버튼과 동일한 radius 적용
2419
- return `designbase-button--radius-${size === 'xs' || size === 's' ? 's' : size === 'l' || size === 'xl' ? 'l' : 'm'}`;
2419
+ if (size === 's')
2420
+ return 'designbase-button--radius-s';
2421
+ if (size === 'l')
2422
+ return 'designbase-button--radius-l';
2423
+ return 'designbase-button--radius-m';
2420
2424
  };
2421
2425
  const classes = clsx('designbase-button', `designbase-button--${variant}`, `designbase-button--${size}`, getRadiusClass(), {
2422
2426
  'designbase-button--full-width': fullWidth,
2423
2427
  'designbase-button--loading': loading,
2424
2428
  'designbase-button--icon-only': iconOnly,
2425
2429
  }, className);
2426
- const iconSize = (() => {
2427
- switch (size) {
2428
- case 'xs': return 12;
2429
- case 's': return 14;
2430
- case 'm': return 16;
2431
- case 'l': return 18;
2432
- case 'xl': return 20;
2433
- default: return 16;
2434
- }
2435
- })();
2430
+ const iconSize = size === 's' ? 14 : size === 'l' ? 18 : 16;
2436
2431
  // 아이콘 색상 결정
2437
2432
  const getIconColor = () => {
2438
2433
  switch (variant) {
@@ -2452,7 +2447,13 @@ const Button = forwardRef(({ variant = 'primary', size = 'm', radius, fullWidth
2452
2447
  };
2453
2448
  const renderContent = () => {
2454
2449
  if (loading) {
2455
- return (jsxs(Fragment, { children: [jsx(Spinner, { type: "circular", size: size === 'xs' ? 'xs' : size === 's' ? 's' : 'm', color: getIconColor(), speed: 1, showLabel: false }), !iconOnly && jsx("span", { children: "\uB85C\uB529 \uC911..." })] }));
2450
+ // 로딩 표시할 텍스트 결정: loadingText > children > 기본값
2451
+ const displayText = loadingText !== undefined
2452
+ ? loadingText
2453
+ : (!iconOnly && children)
2454
+ ? children
2455
+ : null;
2456
+ return (jsxs(Fragment, { children: [jsx(Spinner, { type: "circular", size: size === 's' ? 's' : size === 'l' ? 'l' : 'm', color: getIconColor(), speed: 1, showLabel: false }), displayText && jsx("span", { children: displayText })] }));
2456
2457
  }
2457
2458
  // iconOnly 버튼일 때는 children을 아이콘으로 처리
2458
2459
  if (iconOnly && children && React.isValidElement(children)) {
@@ -4011,7 +4012,7 @@ ModalHeader.displayName = 'ModalHeader';
4011
4012
  ModalBody.displayName = 'ModalBody';
4012
4013
  ModalFooter.displayName = 'ModalFooter';
4013
4014
 
4014
- const Label = ({ children, htmlFor, required = false, size = 's', disabled = false, error = false, className, onClick, }) => {
4015
+ const Label = ({ children, htmlFor, id, required = false, size = 's', disabled = false, error = false, className, onClick, }) => {
4015
4016
  const classes = [
4016
4017
  'designbase-label',
4017
4018
  `designbase-label--${size}`,
@@ -4021,7 +4022,7 @@ const Label = ({ children, htmlFor, required = false, size = 's', disabled = fal
4021
4022
  ]
4022
4023
  .filter(Boolean)
4023
4024
  .join(' ');
4024
- return (jsxs("label", { htmlFor: htmlFor, className: classes, onClick: onClick, children: [children, required && jsx("span", { className: "designbase-label__required", children: "*" })] }));
4025
+ return (jsxs("label", { htmlFor: htmlFor, id: id, className: classes, onClick: onClick, children: [children, required && jsx("span", { className: "designbase-label__required", children: "*" })] }));
4025
4026
  };
4026
4027
  Label.displayName = 'Label';
4027
4028
 
@@ -4052,12 +4053,17 @@ const Input = forwardRef(({ type = 'text', label, placeholder, defaultValue, val
4052
4053
  'designbase-input--with-end-icon': EndIcon || isPassword,
4053
4054
  }, className);
4054
4055
  const inputClasses = clsx('designbase-input__field', inputClassName);
4055
- const iconSizeMap = {
4056
- sm: 14,
4057
- md: 16,
4058
- lg: 18,
4059
- };
4060
- const iconSize = iconSizeMap[size];
4056
+ const iconSize = React.useMemo(() => {
4057
+ switch (size) {
4058
+ case 's':
4059
+ return 16;
4060
+ case 'l':
4061
+ return 24;
4062
+ case 'm':
4063
+ default:
4064
+ return 20;
4065
+ }
4066
+ }, [size]);
4061
4067
  return (jsxs("div", { className: classes, children: [label && (jsx(Label, { htmlFor: inputId, required: required, error: error, disabled: disabled, size: size === 's' ? 's' : size === 'm' ? 'm' : 'l', children: label })), jsxs("div", { className: "designbase-input__wrapper", children: [actualStartIcon && (jsx("div", { className: "designbase-input__start-icon", children: React.createElement(actualStartIcon, { size: iconSize }) })), jsx("input", { ...props, ref: forwardedRef, id: inputId, type: actualType, value: value, defaultValue: defaultValue, placeholder: placeholder, disabled: disabled, readOnly: readOnly, required: required, className: inputClasses, onChange: handleChange, onFocus: onFocus, onBlur: onBlur, "aria-describedby": clsx(helperText && helperTextId, error && errorMessage && errorMessageId), "aria-invalid": error }), isPassword && (jsx("button", { type: "button", className: "designbase-input__password-toggle", onClick: handlePasswordToggle, disabled: disabled, "aria-label": showPassword ? '비밀번호 숨기기' : '비밀번호 보기', children: React.createElement(PasswordIcon, { size: iconSize }) })), EndIcon && !isPassword && (jsx("div", { className: "designbase-input__end-icon", children: React.createElement(EndIcon, { size: iconSize }) }))] }), helperText && !error && (jsx("p", { id: helperTextId, className: "designbase-input__helper-text", children: helperText })), error && errorMessage && (jsx("p", { id: errorMessageId, className: "designbase-input__error-message", children: errorMessage }))] }));
4062
4068
  });
4063
4069
  Input.displayName = 'Input';
@@ -4098,6 +4104,157 @@ const Checkbox = forwardRef(({ isSelected, defaultSelected, isIndeterminate = fa
4098
4104
  });
4099
4105
  Checkbox.displayName = 'Checkbox';
4100
4106
 
4107
+ 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, ...rest }) => {
4108
+ const [internalValue, setInternalValue] = useState(defaultValue);
4109
+ const [recentSearches, setRecentSearches] = useState([]);
4110
+ const [showRecentSearches, setShowRecentSearches] = useState(false);
4111
+ const [currentSuggestion, setCurrentSuggestion] = useState(0);
4112
+ const [isFocused, setIsFocused] = useState(false);
4113
+ const inputRef = useRef(null);
4114
+ const suggestionIntervalRef = useRef(null);
4115
+ const currentValue = value !== undefined ? value : internalValue;
4116
+ // 최근 검색어 로드
4117
+ useEffect(() => {
4118
+ if (enableRecentSearches) {
4119
+ try {
4120
+ const stored = localStorage.getItem(recentSearchesKey);
4121
+ if (stored) {
4122
+ setRecentSearches(JSON.parse(stored));
4123
+ }
4124
+ }
4125
+ catch (error) {
4126
+ console.warn('최근 검색어를 불러올 수 없습니다:', error);
4127
+ }
4128
+ }
4129
+ }, [enableRecentSearches, recentSearchesKey]);
4130
+ // 추천 검색어 롤링 (value가 없을 때만)
4131
+ useEffect(() => {
4132
+ if (suggestedSearches.length > 0 && !currentValue && currentValue === '') {
4133
+ suggestionIntervalRef.current = setInterval(() => {
4134
+ setCurrentSuggestion(prev => (prev + 1) % suggestedSearches.length);
4135
+ }, suggestionRollingInterval);
4136
+ }
4137
+ else {
4138
+ if (suggestionIntervalRef.current) {
4139
+ clearInterval(suggestionIntervalRef.current);
4140
+ suggestionIntervalRef.current = null;
4141
+ }
4142
+ }
4143
+ return () => {
4144
+ if (suggestionIntervalRef.current) {
4145
+ clearInterval(suggestionIntervalRef.current);
4146
+ }
4147
+ };
4148
+ }, [suggestedSearches.length, currentValue, suggestionRollingInterval]);
4149
+ useEffect(() => {
4150
+ if (value !== undefined) {
4151
+ setInternalValue(value);
4152
+ }
4153
+ }, [value]);
4154
+ const handleChange = (e) => {
4155
+ const newValue = e.target.value;
4156
+ setInternalValue(newValue);
4157
+ onChange?.(newValue);
4158
+ };
4159
+ const handleClear = () => {
4160
+ setInternalValue('');
4161
+ onChange?.('');
4162
+ inputRef.current?.focus();
4163
+ };
4164
+ const handleSearch = (searchValue) => {
4165
+ const searchTerm = searchValue || currentValue.trim();
4166
+ if (searchTerm) {
4167
+ onSearch?.(searchTerm);
4168
+ // 최근 검색어 저장
4169
+ if (enableRecentSearches) {
4170
+ const newRecentSearches = [
4171
+ searchTerm,
4172
+ ...recentSearches.filter(item => item !== searchTerm)
4173
+ ].slice(0, 10); // 최대 10개
4174
+ setRecentSearches(newRecentSearches);
4175
+ try {
4176
+ localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
4177
+ }
4178
+ catch (error) {
4179
+ console.warn('최근 검색어를 저장할 수 없습니다:', error);
4180
+ }
4181
+ }
4182
+ }
4183
+ };
4184
+ const handleKeyDown = (e) => {
4185
+ if (e.key === 'Enter') {
4186
+ handleSearch();
4187
+ }
4188
+ onKeyDown?.(e);
4189
+ };
4190
+ const handleFocus = (e) => {
4191
+ setIsFocused(true);
4192
+ setShowRecentSearches(enableRecentSearches && recentSearches.length > 0);
4193
+ onFocus?.(e);
4194
+ };
4195
+ const handleBlur = (e) => {
4196
+ setIsFocused(false);
4197
+ // 약간의 지연을 두어 클릭 이벤트가 처리되도록 함
4198
+ setTimeout(() => {
4199
+ setShowRecentSearches(false);
4200
+ }, 200);
4201
+ onBlur?.(e);
4202
+ };
4203
+ const handleRecentSearchClick = (searchTerm) => {
4204
+ setInternalValue(searchTerm);
4205
+ onChange?.(searchTerm);
4206
+ setShowRecentSearches(false);
4207
+ handleSearch(searchTerm);
4208
+ };
4209
+ const handleRemoveRecentSearch = (searchTerm) => {
4210
+ const newRecentSearches = recentSearches.filter(item => item !== searchTerm);
4211
+ setRecentSearches(newRecentSearches);
4212
+ try {
4213
+ localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
4214
+ }
4215
+ catch (error) {
4216
+ console.warn('최근 검색어를 삭제할 수 없습니다:', error);
4217
+ }
4218
+ };
4219
+ const handleClearAllRecentSearches = () => {
4220
+ setRecentSearches([]);
4221
+ try {
4222
+ localStorage.removeItem(recentSearchesKey);
4223
+ }
4224
+ catch (error) {
4225
+ console.warn('최근 검색어를 모두 삭제할 수 없습니다:', error);
4226
+ }
4227
+ };
4228
+ const handleSuggestionClick = (suggestion) => {
4229
+ setInternalValue(suggestion);
4230
+ onChange?.(suggestion);
4231
+ // 롤링 중단
4232
+ if (suggestionIntervalRef.current) {
4233
+ clearInterval(suggestionIntervalRef.current);
4234
+ suggestionIntervalRef.current = null;
4235
+ }
4236
+ handleSearch(suggestion);
4237
+ };
4238
+ const classes = clsx('designbase-search-bar', `designbase-search-bar--${size}`, `designbase-search-bar--${variant}`, {
4239
+ 'designbase-search-bar--disabled': disabled,
4240
+ 'designbase-search-bar--readonly': readOnly,
4241
+ 'designbase-search-bar--full-width': fullWidth,
4242
+ 'designbase-search-bar--has-value': currentValue && currentValue.length > 0,
4243
+ }, className);
4244
+ const inputClasses = clsx('designbase-search-bar__input', {
4245
+ 'designbase-search-bar__input--disabled': disabled,
4246
+ 'designbase-search-bar__input--readonly': readOnly,
4247
+ });
4248
+ // 현재 플레이스홀더 (value가 없을 때만 추천 검색어 롤링)
4249
+ const currentPlaceholder = suggestedSearches.length > 0 && !currentValue && currentValue === ''
4250
+ ? suggestedSearches[currentSuggestion]
4251
+ : placeholder;
4252
+ 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", ...rest }), 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(CloseIcon, { 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', {
4253
+ 'designbase-search-bar__suggestion-item--active': index === currentSuggestion
4254
+ }), onClick: () => handleSuggestionClick(suggestion), children: suggestion }, index))) })] }))] }));
4255
+ };
4256
+ SearchBar.displayName = 'SearchBar';
4257
+
4101
4258
  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 = true, className, onChange, onFocus, onBlur, ...props }) => {
4102
4259
  const [isOpen, setIsOpen] = useState(false);
4103
4260
  const [selectedValue, setSelectedValue] = useState(value ?? defaultValue ?? (multiple ? [] : ''));
@@ -4242,9 +4399,6 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
4242
4399
  setSelectedValue(newValue);
4243
4400
  onChange?.(newValue);
4244
4401
  };
4245
- const handleSearchChange = (e) => {
4246
- setSearchTerm(e.target.value);
4247
- };
4248
4402
  const classes = clsx('designbase-select', `designbase-select--${size}`, {
4249
4403
  'designbase-select--open': isOpen,
4250
4404
  'designbase-select--error': error,
@@ -4252,9 +4406,11 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
4252
4406
  'designbase-select--readonly': readOnly,
4253
4407
  'designbase-select--full-width': fullWidth,
4254
4408
  'designbase-select--multiple': multiple,
4409
+ 'designbase-select--searchable': searchable,
4255
4410
  }, className);
4256
4411
  const triggerClasses = clsx('designbase-select__trigger', {
4257
4412
  'designbase-select__trigger--focused': isOpen,
4413
+ 'designbase-select__trigger--searchable': searchable,
4258
4414
  });
4259
4415
  const dropdownClasses = clsx('designbase-select__dropdown', `designbase-select__dropdown--${dropdownWidth}`, `designbase-select__dropdown--${position}`, {
4260
4416
  'designbase-select__dropdown--open': isOpen,
@@ -4262,23 +4418,23 @@ const Select = ({ value, defaultValue, options, label, placeholder = '선택하
4262
4418
  const filteredOptions = getFilteredOptions();
4263
4419
  const selectedLabels = getSelectedLabels();
4264
4420
  const hasValue = multiple ? selectedValue.length > 0 : selectedValue !== '';
4265
- return (jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxs("label", { className: "designbase-select__label", children: [label, required && jsx("span", { className: "designbase-select__required", children: "*" })] })), jsxs("div", { className: triggerClasses, onClick: handleToggle, onFocus: onFocus, onBlur: onBlur, tabIndex: disabled || readOnly ? -1 : 0, role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-labelledby": label ? 'select-label' : undefined, ...props, children: [jsx("div", { className: "designbase-select__value", children: multiple ? (jsxs("div", { className: "designbase-select__tags", ref: tagsContainerRef, children: [selectedValue.map((value) => {
4266
- const option = options.find(opt => opt.value === value);
4267
- return (jsxs("span", { className: "designbase-select__tag", children: [jsx("span", { className: "designbase-select__tag-label", children: option?.label || value }), jsx("button", { type: "button", className: "designbase-select__tag-remove", onClick: (e) => {
4268
- e.stopPropagation();
4269
- handleRemoveValue(value);
4270
- }, children: jsx(CloseIcon, { size: 12 }) })] }, value));
4271
- }), searchable && isOpen && (jsx("input", { ref: inputRef, type: "text", className: "designbase-select__search-input", value: searchTerm, onChange: handleSearchChange, placeholder: "\uAC80\uC0C9...", onClick: (e) => e.stopPropagation() }))] })) : (jsx("span", { className: "designbase-select__single-value", children: selectedLabels || placeholder })) }), jsxs("div", { className: "designbase-select__indicators", children: [showClearButton && hasValue && !disabled && !readOnly && (jsx("button", { type: "button", className: "designbase-select__clear-button", onClick: handleClearAll, "aria-label": "\uBAA8\uB4E0 \uAC12 \uC9C0\uC6B0\uAE30", children: jsx(CloseIcon, { size: 16 }) })), jsx("div", { className: "designbase-select__chevron", children: isOpen ? jsx(ChevronUpIcon, { size: 16 }) : jsx(ChevronDownIcon, { size: 16 }) })] })] }), jsx("div", { className: dropdownClasses, ref: dropdownRef, children: jsx("div", { className: "designbase-select__options", style: { maxHeight: `${maxHeight}px` }, role: "listbox", children: filteredOptions.length === 0 ? (jsx("div", { className: "designbase-select__no-options", children: searchTerm ? '검색 결과가 없습니다.' : '옵션이 없습니다.' })) : (filteredOptions.map((option, index) => {
4272
- const isSelected = multiple
4273
- ? selectedValue.includes(option.value)
4274
- : selectedValue === option.value;
4275
- const isFocused = index === focusedIndex;
4276
- return (jsxs("div", { className: clsx('designbase-select__option', {
4277
- 'designbase-select__option--selected': isSelected,
4278
- 'designbase-select__option--focused': isFocused,
4279
- 'designbase-select__option--disabled': option.disabled,
4280
- }), onClick: () => handleOptionSelect(option), role: "option", "aria-selected": isSelected, children: [multiple && (jsx("div", { className: "designbase-select__checkbox", children: jsx(Checkbox, { isSelected: isSelected, isDisabled: option.disabled, size: "s", hasLabel: false, onChange: () => handleOptionSelect(option) }) })), jsx("span", { className: "designbase-select__option-label", children: option.label })] }, option.value));
4281
- })) }) }), helperText && !error && (jsx("p", { className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsx("p", { className: "designbase-select__error-message", children: errorMessage }))] }));
4421
+ return (jsxs("div", { className: classes, ref: containerRef, children: [label && (jsxs("label", { className: "designbase-select__label", children: [label, required && jsx("span", { className: "designbase-select__required", children: "*" })] })), jsxs("div", { className: triggerClasses, onClick: handleToggle, onFocus: onFocus, onBlur: onBlur, tabIndex: disabled || readOnly ? -1 : 0, role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-labelledby": label ? 'select-label' : undefined, ...props, children: [jsx("div", { className: "designbase-select__value", children: multiple ? (jsx("div", { className: "designbase-select__tags", ref: tagsContainerRef, children: selectedValue.map((value) => {
4422
+ const option = options.find(opt => opt.value === value);
4423
+ return (jsxs("span", { className: "designbase-select__tag", children: [jsx("span", { className: "designbase-select__tag-label", children: option?.label || value }), jsx("button", { type: "button", className: "designbase-select__tag-remove", onClick: (e) => {
4424
+ e.stopPropagation();
4425
+ handleRemoveValue(value);
4426
+ }, children: jsx(CloseIcon, { size: 12 }) })] }, value));
4427
+ }) })) : (jsx("span", { className: "designbase-select__single-value", children: selectedLabels || placeholder })) }), jsxs("div", { className: "designbase-select__indicators", children: [showClearButton && hasValue && !disabled && !readOnly && (jsx("button", { type: "button", className: "designbase-select__clear-button", onClick: handleClearAll, "aria-label": "\uBAA8\uB4E0 \uAC12 \uC9C0\uC6B0\uAE30", children: jsx(CloseIcon, { size: 16 }) })), jsx("div", { className: "designbase-select__chevron", children: isOpen ? jsx(ChevronUpIcon, { size: 16 }) : jsx(ChevronDownIcon, { size: 16 }) })] })] }), jsxs("div", { className: dropdownClasses, ref: dropdownRef, children: [searchable && (jsx("div", { className: "designbase-select__search", onMouseDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: jsx(SearchBar, { value: searchTerm, onChange: (value) => setSearchTerm(value), onSearch: (val) => setSearchTerm(val), placeholder: "\uC635\uC158 \uAC80\uC0C9", size: size, variant: "outlined", fullWidth: true, onFocus: (e) => e.stopPropagation(), onBlur: (e) => e.stopPropagation() }) })), jsx("div", { className: "designbase-select__options", style: { maxHeight: `${maxHeight}px` }, role: "listbox", children: filteredOptions.length === 0 ? (jsx("div", { className: "designbase-select__no-options", children: searchTerm ? '검색 결과가 없습니다.' : '옵션이 없습니다.' })) : (filteredOptions.map((option, index) => {
4428
+ const isSelected = multiple
4429
+ ? selectedValue.includes(option.value)
4430
+ : selectedValue === option.value;
4431
+ const isFocused = index === focusedIndex;
4432
+ return (jsxs("div", { className: clsx('designbase-select__option', {
4433
+ 'designbase-select__option--selected': isSelected,
4434
+ 'designbase-select__option--focused': isFocused,
4435
+ 'designbase-select__option--disabled': option.disabled,
4436
+ }), onClick: () => handleOptionSelect(option), role: "option", "aria-selected": isSelected, children: [multiple && (jsx("div", { className: "designbase-select__checkbox", children: jsx(Checkbox, { isSelected: isSelected, isDisabled: option.disabled, size: "s", hasLabel: false, onChange: () => handleOptionSelect(option) }) })), jsx("span", { className: "designbase-select__option-label", children: option.label })] }, option.value));
4437
+ })) })] }), helperText && !error && (jsx("p", { className: "designbase-select__helper-text", children: helperText })), error && errorMessage && (jsx("p", { className: "designbase-select__error-message", children: errorMessage }))] }));
4282
4438
  };
4283
4439
  Select.displayName = 'Select';
4284
4440
 
@@ -5219,8 +5375,6 @@ const Carousel = ({ items, size = 'm', variant = 'default', theme = 'light', tra
5219
5375
  const handleTouchEndEvent = useCallback(() => {
5220
5376
  handleTouchEnd();
5221
5377
  }, [handleTouchEnd]);
5222
- // 현재 아이템
5223
- const currentItem = items[currentIndex];
5224
5378
  // 슬라이드 스타일 계산
5225
5379
  const getSlideStyle = () => {
5226
5380
  const containerWidth = containerRef.current?.offsetWidth || 1;
@@ -5235,9 +5389,6 @@ const Carousel = ({ items, size = 'm', variant = 'default', theme = 'light', tra
5235
5389
  // 네비게이션 버튼 비활성화 상태
5236
5390
  const isPrevDisabled = !infinite && currentIndex === 0;
5237
5391
  const isNextDisabled = !infinite && currentIndex === items.length - 1;
5238
- // 좋아요/북마크 상태
5239
- const isLiked = currentItem ? likedItems.has(currentItem.id) : false;
5240
- const isBookmarked = currentItem ? bookmarkedItems.has(currentItem.id) : false;
5241
5392
  if (items.length === 0)
5242
5393
  return null;
5243
5394
  return (jsxs("div", { className: clsx('designbase-carousel', `designbase-carousel--size-${size}`, `designbase-carousel--variant-${variant}`, `designbase-carousel--theme-${theme}`, `designbase-carousel--transition-${transition}`, `designbase-carousel--indicator-${indicatorStyle}`, {
@@ -5258,13 +5409,17 @@ const Carousel = ({ items, size = 'm', variant = 'default', theme = 'light', tra
5258
5409
  color: item.textColor || (item.image ? '#ffffff' : undefined),
5259
5410
  }, children: item.title })), showDescription && item.description && (jsx("p", { className: "designbase-carousel__slide-description", style: {
5260
5411
  color: item.textColor || (item.image ? '#ffffff' : undefined),
5261
- }, children: item.description })), item.meta && (jsxs("div", { className: "designbase-carousel__slide-meta", children: [item.meta.author && (jsx("span", { className: "designbase-carousel__slide-author", children: item.meta.author })), item.meta.date && (jsx("span", { className: "designbase-carousel__slide-date", children: item.meta.date })), item.meta.rating && (jsxs("span", { className: "designbase-carousel__slide-rating", children: ["\u2B50 ", item.meta.rating] }))] }))] })) : null] })), jsxs("div", { className: "designbase-carousel__slide-actions", children: [enableLike && (jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--like', { 'designbase-carousel__action-button--active': isLiked }), onClick: (e) => {
5412
+ }, children: item.description })), item.meta && (jsxs("div", { className: "designbase-carousel__slide-meta", children: [item.meta.author && (jsx("span", { className: "designbase-carousel__slide-author", children: item.meta.author })), item.meta.date && (jsx("span", { className: "designbase-carousel__slide-date", children: item.meta.date })), item.meta.rating && (jsxs("span", { className: "designbase-carousel__slide-rating", children: ["\u2B50 ", item.meta.rating] }))] }))] })) : null] })), jsxs("div", { className: "designbase-carousel__slide-actions", children: [enableLike && (jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--like', {
5413
+ 'designbase-carousel__action-button--active': likedItems.has(item.id),
5414
+ }), onClick: (e) => {
5262
5415
  e.stopPropagation();
5263
5416
  handleLike(item, index);
5264
- }, title: isLiked ? "좋아요 취소" : "좋아요", children: jsx(HeartIcon, { size: iconSize, color: "currentColor" }) })), enableBookmark && (jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--bookmark', { 'designbase-carousel__action-button--active': isBookmarked }), onClick: (e) => {
5417
+ }, title: likedItems.has(item.id) ? "좋아요 취소" : "좋아요", children: jsx(HeartIcon, { size: iconSize, color: "currentColor" }) })), enableBookmark && (jsx("button", { className: clsx('designbase-carousel__action-button', 'designbase-carousel__action-button--bookmark', {
5418
+ 'designbase-carousel__action-button--active': bookmarkedItems.has(item.id),
5419
+ }), onClick: (e) => {
5265
5420
  e.stopPropagation();
5266
5421
  handleBookmark(item, index);
5267
- }, title: isBookmarked ? "북마크 해제" : "북마크", children: jsx(BookmarkIcon, { size: iconSize, color: "currentColor" }) })), enableShare && (jsx("button", { className: "designbase-carousel__action-button designbase-carousel__action-button--share", onClick: (e) => {
5422
+ }, title: bookmarkedItems.has(item.id) ? "북마크 해제" : "북마크", children: jsx(BookmarkIcon, { size: iconSize, color: "currentColor" }) })), enableShare && (jsx("button", { className: "designbase-carousel__action-button designbase-carousel__action-button--share", onClick: (e) => {
5268
5423
  e.stopPropagation();
5269
5424
  handleShare(item, index);
5270
5425
  }, title: "\uACF5\uC720", children: jsx(ShareAltIcon, { size: iconSize, color: "currentColor" }) })), enableDownload && item.image && (jsx("button", { className: "designbase-carousel__action-button designbase-carousel__action-button--download", onClick: (e) => {
@@ -8927,157 +9082,6 @@ const Tutorial = ({ steps, currentStep = 0, isActive, onStart, onEnd, onStepChan
8927
9082
  };
8928
9083
  Tutorial.displayName = 'Tutorial';
8929
9084
 
8930
- 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 }) => {
8931
- const [internalValue, setInternalValue] = useState(defaultValue);
8932
- const [recentSearches, setRecentSearches] = useState([]);
8933
- const [showRecentSearches, setShowRecentSearches] = useState(false);
8934
- const [currentSuggestion, setCurrentSuggestion] = useState(0);
8935
- const [isFocused, setIsFocused] = useState(false);
8936
- const inputRef = useRef(null);
8937
- const suggestionIntervalRef = useRef(null);
8938
- const currentValue = value !== undefined ? value : internalValue;
8939
- // 최근 검색어 로드
8940
- useEffect(() => {
8941
- if (enableRecentSearches) {
8942
- try {
8943
- const stored = localStorage.getItem(recentSearchesKey);
8944
- if (stored) {
8945
- setRecentSearches(JSON.parse(stored));
8946
- }
8947
- }
8948
- catch (error) {
8949
- console.warn('최근 검색어를 불러올 수 없습니다:', error);
8950
- }
8951
- }
8952
- }, [enableRecentSearches, recentSearchesKey]);
8953
- // 추천 검색어 롤링 (value가 없을 때만)
8954
- useEffect(() => {
8955
- if (suggestedSearches.length > 0 && !currentValue && currentValue === '') {
8956
- suggestionIntervalRef.current = setInterval(() => {
8957
- setCurrentSuggestion(prev => (prev + 1) % suggestedSearches.length);
8958
- }, suggestionRollingInterval);
8959
- }
8960
- else {
8961
- if (suggestionIntervalRef.current) {
8962
- clearInterval(suggestionIntervalRef.current);
8963
- suggestionIntervalRef.current = null;
8964
- }
8965
- }
8966
- return () => {
8967
- if (suggestionIntervalRef.current) {
8968
- clearInterval(suggestionIntervalRef.current);
8969
- }
8970
- };
8971
- }, [suggestedSearches.length, currentValue, suggestionRollingInterval]);
8972
- useEffect(() => {
8973
- if (value !== undefined) {
8974
- setInternalValue(value);
8975
- }
8976
- }, [value]);
8977
- const handleChange = (e) => {
8978
- const newValue = e.target.value;
8979
- setInternalValue(newValue);
8980
- onChange?.(newValue);
8981
- };
8982
- const handleClear = () => {
8983
- setInternalValue('');
8984
- onChange?.('');
8985
- inputRef.current?.focus();
8986
- };
8987
- const handleSearch = (searchValue) => {
8988
- const searchTerm = searchValue || currentValue.trim();
8989
- if (searchTerm) {
8990
- onSearch?.(searchTerm);
8991
- // 최근 검색어 저장
8992
- if (enableRecentSearches) {
8993
- const newRecentSearches = [
8994
- searchTerm,
8995
- ...recentSearches.filter(item => item !== searchTerm)
8996
- ].slice(0, 10); // 최대 10개
8997
- setRecentSearches(newRecentSearches);
8998
- try {
8999
- localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
9000
- }
9001
- catch (error) {
9002
- console.warn('최근 검색어를 저장할 수 없습니다:', error);
9003
- }
9004
- }
9005
- }
9006
- };
9007
- const handleKeyDown = (e) => {
9008
- if (e.key === 'Enter') {
9009
- handleSearch();
9010
- }
9011
- onKeyDown?.(e);
9012
- };
9013
- const handleFocus = (e) => {
9014
- setIsFocused(true);
9015
- setShowRecentSearches(enableRecentSearches && recentSearches.length > 0);
9016
- onFocus?.(e);
9017
- };
9018
- const handleBlur = (e) => {
9019
- setIsFocused(false);
9020
- // 약간의 지연을 두어 클릭 이벤트가 처리되도록 함
9021
- setTimeout(() => {
9022
- setShowRecentSearches(false);
9023
- }, 200);
9024
- onBlur?.(e);
9025
- };
9026
- const handleRecentSearchClick = (searchTerm) => {
9027
- setInternalValue(searchTerm);
9028
- onChange?.(searchTerm);
9029
- setShowRecentSearches(false);
9030
- handleSearch(searchTerm);
9031
- };
9032
- const handleRemoveRecentSearch = (searchTerm) => {
9033
- const newRecentSearches = recentSearches.filter(item => item !== searchTerm);
9034
- setRecentSearches(newRecentSearches);
9035
- try {
9036
- localStorage.setItem(recentSearchesKey, JSON.stringify(newRecentSearches));
9037
- }
9038
- catch (error) {
9039
- console.warn('최근 검색어를 삭제할 수 없습니다:', error);
9040
- }
9041
- };
9042
- const handleClearAllRecentSearches = () => {
9043
- setRecentSearches([]);
9044
- try {
9045
- localStorage.removeItem(recentSearchesKey);
9046
- }
9047
- catch (error) {
9048
- console.warn('최근 검색어를 모두 삭제할 수 없습니다:', error);
9049
- }
9050
- };
9051
- const handleSuggestionClick = (suggestion) => {
9052
- setInternalValue(suggestion);
9053
- onChange?.(suggestion);
9054
- // 롤링 중단
9055
- if (suggestionIntervalRef.current) {
9056
- clearInterval(suggestionIntervalRef.current);
9057
- suggestionIntervalRef.current = null;
9058
- }
9059
- handleSearch(suggestion);
9060
- };
9061
- const classes = clsx('designbase-search-bar', `designbase-search-bar--${size}`, `designbase-search-bar--${variant}`, {
9062
- 'designbase-search-bar--disabled': disabled,
9063
- 'designbase-search-bar--readonly': readOnly,
9064
- 'designbase-search-bar--full-width': fullWidth,
9065
- 'designbase-search-bar--has-value': currentValue && currentValue.length > 0,
9066
- }, className);
9067
- const inputClasses = clsx('designbase-search-bar__input', {
9068
- 'designbase-search-bar__input--disabled': disabled,
9069
- 'designbase-search-bar__input--readonly': readOnly,
9070
- });
9071
- // 현재 플레이스홀더 (value가 없을 때만 추천 검색어 롤링)
9072
- const currentPlaceholder = suggestedSearches.length > 0 && !currentValue && currentValue === ''
9073
- ? suggestedSearches[currentSuggestion]
9074
- : placeholder;
9075
- 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(CloseIcon, { 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', {
9076
- 'designbase-search-bar__suggestion-item--active': index === currentSuggestion
9077
- }), onClick: () => handleSuggestionClick(suggestion), children: suggestion }, index))) })] }))] }));
9078
- };
9079
- SearchBar.displayName = 'SearchBar';
9080
-
9081
9085
  const Navbar = ({ size = 'm', variant = 'default', position = 'static', logo, onLogoClick, items = [], onItemClick, userMenuItems = [], onUserMenuItemClick, userProfile, onLoginClick, onLogoutClick, isAuthenticated = false, showSearch = false, onSearch, searchPlaceholder = '검색...', fullWidth = false, shadow = false, className, ...props }) => {
9082
9086
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
9083
9087
  const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
@@ -11590,6 +11594,47 @@ const Toggle = forwardRef(({ isSelected, defaultSelected, isDisabled = false, is
11590
11594
  });
11591
11595
  Toggle.displayName = 'Toggle';
11592
11596
 
11597
+ const clampRating = (rating, maxRating) => {
11598
+ if (typeof rating !== 'number' || Number.isNaN(rating))
11599
+ return undefined;
11600
+ if (rating < 0)
11601
+ return 0;
11602
+ if (rating > maxRating)
11603
+ return maxRating;
11604
+ return Math.round(rating * 10) / 10;
11605
+ };
11606
+ const Testimonial = ({ quote, author, role, company, avatar, rating, maxRating = 5, size = 'm', align = 'left', badge, children, className, badgeProps, avatarProps, ratingProps, }) => {
11607
+ const clampedRating = clampRating(rating, maxRating);
11608
+ const avatarSizeMap = {
11609
+ s: 's',
11610
+ m: 'm',
11611
+ l: 'l',
11612
+ };
11613
+ const ratingSizeMap = {
11614
+ s: 's',
11615
+ m: 'm',
11616
+ l: 'l',
11617
+ };
11618
+ const { className: badgeCustomClassName, size: badgeSize, variant: badgeVariant, style: badgeStyle, ...restBadgeProps } = badgeProps ?? {};
11619
+ const { className: avatarCustomClassName, size: avatarSize, alt: avatarAlt, src: avatarSrc, ...restAvatarProps } = avatarProps ?? {};
11620
+ const { className: ratingCustomClassName, maxValue: ratingMaxValueOverride, size: ratingSize, display: ratingDisplay, allowHalf: ratingAllowHalf, readonly: ratingReadonly, color: ratingColor, customColor: ratingCustomColor, ...restRatingProps } = ratingProps ?? {};
11621
+ const computedBadgeSize = badgeSize ?? 's';
11622
+ const computedBadgeVariant = badgeVariant ?? 'primary';
11623
+ const computedBadgeStyle = badgeStyle ?? 'text';
11624
+ const computedAvatarSrc = avatarSrc ?? avatar;
11625
+ const computedAvatarAlt = avatarAlt ?? `${author} 프로필 이미지`;
11626
+ const computedAvatarSize = avatarSize ?? avatarSizeMap[size];
11627
+ const computedRatingMaxValue = ratingMaxValueOverride ?? maxRating;
11628
+ const computedRatingSize = ratingSize ?? ratingSizeMap[size];
11629
+ const computedRatingDisplay = ratingDisplay ?? 'both';
11630
+ const computedRatingAllowHalf = ratingAllowHalf ?? true;
11631
+ const computedRatingReadonly = ratingReadonly ?? true;
11632
+ const computedRatingColor = ratingColor ?? 'primary';
11633
+ const computedRatingCustomColor = computedRatingColor === 'custom' ? ratingCustomColor : undefined;
11634
+ const shouldRenderAvatar = Boolean(computedAvatarSrc || restAvatarProps.initials || restAvatarProps.icon);
11635
+ return (jsxs("figure", { className: clsx('designbase-testimonial', `designbase-testimonial--size-${size}`, `designbase-testimonial--align-${align}`, className), children: [badge && (jsx(Badge, { size: computedBadgeSize, variant: computedBadgeVariant, style: computedBadgeStyle, className: clsx('designbase-testimonial__badge', badgeCustomClassName), ...restBadgeProps, children: badge })), jsxs("blockquote", { className: "designbase-testimonial__quote", children: ["\u201C", quote, "\u201D"] }), jsxs("figcaption", { className: "designbase-testimonial__footer", children: [shouldRenderAvatar && (jsx("div", { className: "designbase-testimonial__avatar", children: jsx(Avatar, { src: computedAvatarSrc, alt: computedAvatarAlt, size: computedAvatarSize, className: clsx('designbase-testimonial__avatar-image', avatarCustomClassName), ...restAvatarProps }) })), jsxs("div", { className: "designbase-testimonial__meta", children: [jsx("span", { className: "designbase-testimonial__author", children: author }), (role || company) && (jsx("span", { className: "designbase-testimonial__role", children: [role, company].filter(Boolean).join(' · ') }))] }), typeof clampedRating === 'number' && (jsx(Rating, { value: clampedRating, maxValue: computedRatingMaxValue, size: computedRatingSize, display: computedRatingDisplay, allowHalf: computedRatingAllowHalf, readonly: computedRatingReadonly, color: computedRatingColor, customColor: computedRatingCustomColor, className: clsx('designbase-testimonial__rating', ratingCustomClassName), ...restRatingProps }))] }), children && jsx("div", { className: "designbase-testimonial__extra", children: children })] }));
11636
+ };
11637
+
11593
11638
  const Toolbar = ({ items, size = 'm', variant = 'default', position = 'top', fullWidth = false, fixed = false, shadow = true, rounded = true, className, children, }) => {
11594
11639
  const [openDropdown, setOpenDropdown] = React.useState(null);
11595
11640
  const mapSizeToButtonSize = (size) => {
@@ -12140,5 +12185,5 @@ const toggleTheme = () => {
12140
12185
  console.log('toggleTheme called');
12141
12186
  };
12142
12187
 
12143
- export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, Tutorial, VideoPlayer, YouTubePlayer, getTheme, setTheme, toggleTheme, useToast };
12188
+ export { Accordion, AdBanner, Alert, AnimationBackground, AnimationText, AudioPlayer, Avatar, Backdrop, Badge, Banner, BottomNavigation, BottomSheet, Breadcrumbs, Button, Calendar, Card, Carousel, Checkbox, Chip, ColorPicker, Confirm, Container, ContextMenu, Countdown, DatePicker, Divider, Drawer, Dropdown, Dropzone, EmptyState, FileUploader, FloatingActionButton, Form, Gradient, Grid, HeroFeature, Image$1 as Image, ImageList, Indicator, Input, Label, Lightbox, List, Logo, MarkdownEditor, Masonry, MenuItem, Modal, ModalBody, ModalFooter, ModalHeader, Navbar, OnboardingModal, Pagination, Popover, Progress, ProgressStep, Progressbar, Radio, RandomGradient, RangeSlider, Rating, Reorder, ResizablePanels, ScrollArea, SearchBar, Section, SegmentControl, Select, Share, Sidebar, Skeleton, Spinner, SplitView, Stack, Stat, Stepper, Table, Tabs, Testimonial, Textarea, TimePicker, Timeline, Toast, ToastContainer, ToastProvider, Toggle, Toolbar, Tooltip, Tutorial, VideoPlayer, YouTubePlayer, getTheme, setTheme, toggleTheme, useToast };
12144
12189
  //# sourceMappingURL=index.esm.js.map