@mezzanine-ui/react 1.0.0-rc.5 → 1.0.0-rc.7
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/Accordion/Accordion.d.ts +36 -0
- package/Accordion/Accordion.js +37 -1
- package/AlertBanner/AlertBanner.d.ts +30 -1
- package/AlertBanner/AlertBanner.js +56 -12
- package/AutoComplete/AutoComplete.d.ts +75 -11
- package/AutoComplete/AutoComplete.js +145 -25
- package/AutoComplete/AutoCompleteInside.d.ts +54 -0
- package/AutoComplete/AutoCompleteInside.js +17 -0
- package/AutoComplete/useAutoCompleteKeyboard.d.ts +2 -1
- package/AutoComplete/useAutoCompleteKeyboard.js +4 -1
- package/Backdrop/Backdrop.d.ts +33 -1
- package/Backdrop/Backdrop.js +33 -1
- package/Badge/Badge.d.ts +26 -1
- package/Badge/Badge.js +26 -1
- package/Badge/typings.d.ts +15 -0
- package/Breadcrumb/BreadcrumbDropdown.d.ts +1 -1
- package/Breadcrumb/BreadcrumbOverflowMenuDropdown.d.ts +1 -1
- package/Breadcrumb/typings.d.ts +1 -1
- package/Button/Button.d.ts +26 -1
- package/Button/Button.js +33 -5
- package/COMPONENTS.md +267 -0
- package/Calendar/useCalendarControls.d.ts +18 -0
- package/Calendar/useCalendarControls.js +18 -0
- package/Card/FourThumbnailCard.js +1 -1
- package/Card/SingleThumbnailCard.js +1 -1
- package/Checkbox/Checkbox.d.ts +30 -1
- package/Checkbox/Checkbox.js +54 -4
- package/Checkbox/CheckboxGroup.d.ts +39 -1
- package/Checkbox/CheckboxGroup.js +49 -3
- package/Cropper/Cropper.d.ts +2 -2
- package/Cropper/Cropper.js +2 -3
- package/Cropper/CropperElement.js +1 -1
- package/Cropper/utils/cropper-calculations.d.ts +1 -1
- package/Cropper/utils/cropper-calculations.js +16 -14
- package/DatePicker/DatePicker.d.ts +36 -2
- package/DatePicker/DatePicker.js +36 -2
- package/DateRangePicker/useDateRangePickerValue.d.ts +24 -0
- package/DateRangePicker/useDateRangePickerValue.js +24 -0
- package/Description/Description.d.ts +1 -1
- package/Description/Description.js +1 -1
- package/Description/DescriptionTitle.d.ts +6 -1
- package/Description/DescriptionTitle.js +2 -2
- package/Drawer/Drawer.d.ts +78 -33
- package/Drawer/Drawer.js +72 -34
- package/Dropdown/Dropdown.d.ts +63 -1
- package/Dropdown/Dropdown.js +203 -9
- package/Dropdown/DropdownItem.d.ts +26 -2
- package/Dropdown/DropdownItem.js +91 -43
- package/Dropdown/DropdownItemCard.d.ts +3 -2
- package/Dropdown/DropdownItemCard.js +8 -5
- package/Dropdown/DropdownStatus.d.ts +2 -2
- package/Dropdown/DropdownStatus.js +3 -2
- package/Dropdown/dropdownKeydownHandler.d.ts +6 -0
- package/Dropdown/dropdownKeydownHandler.js +14 -7
- package/Empty/icons/EmptyMainInitialDataIcon.js +1 -1
- package/Empty/icons/EmptyMainNotificationIcon.js +1 -1
- package/Empty/icons/EmptyMainResultIcon.js +1 -1
- package/Empty/icons/EmptyMainSystemIcon.js +1 -1
- package/FilterArea/Filter.d.ts +25 -2
- package/FilterArea/Filter.js +43 -2
- package/FilterArea/FilterArea.d.ts +43 -4
- package/FilterArea/FilterArea.js +39 -4
- package/FilterArea/FilterAreaContext.d.ts +6 -0
- package/FilterArea/FilterAreaContext.js +6 -0
- package/FilterArea/FilterLine.d.ts +19 -0
- package/FilterArea/FilterLine.js +19 -0
- package/FilterArea/index.d.ts +2 -2
- package/FilterArea/index.js +1 -1
- package/Form/FormField.d.ts +43 -2
- package/Form/FormField.js +40 -3
- package/Form/typings.d.ts +2 -0
- package/Form/useAutoCompleteValueControl.d.ts +20 -0
- package/Form/useAutoCompleteValueControl.js +20 -0
- package/Form/useCheckboxControlValue.d.ts +19 -0
- package/Form/useCheckboxControlValue.js +19 -0
- package/Form/useControlValueState.d.ts +16 -0
- package/Form/useControlValueState.js +16 -0
- package/Form/useCustomControlValue.d.ts +17 -0
- package/Form/useCustomControlValue.js +17 -0
- package/Form/useInputControlValue.d.ts +19 -0
- package/Form/useInputControlValue.js +19 -0
- package/Form/useInputWithClearControlValue.d.ts +20 -0
- package/Form/useInputWithClearControlValue.js +20 -0
- package/Form/useRadioControlValue.d.ts +19 -0
- package/Form/useRadioControlValue.js +19 -0
- package/Form/useSelectValueControl.d.ts +19 -0
- package/Form/useSelectValueControl.js +19 -0
- package/Form/useSwitchControlValue.d.ts +18 -0
- package/Form/useSwitchControlValue.js +18 -0
- package/Icon/Icon.d.ts +23 -1
- package/Icon/Icon.js +23 -1
- package/Input/Input.d.ts +31 -1
- package/Input/Input.js +31 -1
- package/Input/SpinnerButton/SpinnerButton.js +1 -1
- package/Message/Message.d.ts +56 -6
- package/Message/Message.js +59 -52
- package/Modal/Modal.d.ts +76 -4
- package/Modal/Modal.js +117 -6
- package/Modal/ModalBodyForVerification.js +3 -1
- package/Modal/ModalFooter.d.ts +21 -6
- package/Modal/ModalHeader.d.ts +50 -11
- package/Modal/ModalHeader.js +1 -1
- package/Modal/index.d.ts +1 -1
- package/Navigation/Navigation.js +20 -11
- package/Navigation/NavigationHeader.js +2 -1
- package/Navigation/NavigationIconButton.d.ts +8 -0
- package/Navigation/NavigationIconButton.js +2 -2
- package/Navigation/NavigationOption.js +6 -3
- package/Navigation/NavigationOverflowMenu.js +9 -6
- package/Navigation/NavigationUserMenu.js +3 -1
- package/Navigation/context.d.ts +1 -0
- package/NotificationCenter/NotificationCenter.d.ts +59 -9
- package/NotificationCenter/NotificationCenter.js +150 -54
- package/NotificationCenter/NotificationCenterDrawer.d.ts +56 -6
- package/NotificationCenter/NotificationCenterDrawer.js +6 -8
- package/NotificationCenter/index.d.ts +1 -1
- package/OverflowTooltip/OverflowTooltip.js +46 -5
- package/PageFooter/PageFooter.d.ts +1 -1
- package/PageFooter/PageFooter.js +8 -16
- package/Pagination/Pagination.d.ts +38 -1
- package/Pagination/Pagination.js +38 -1
- package/Pagination/PaginationPageSize.js +1 -1
- package/Pagination/usePagination.d.ts +20 -0
- package/Pagination/usePagination.js +20 -0
- package/Progress/Progress.d.ts +24 -1
- package/Progress/Progress.js +24 -1
- package/README.md +82 -0
- package/Radio/Radio.d.ts +35 -1
- package/Radio/Radio.js +50 -12
- package/Radio/RadioGroup.d.ts +2 -2
- package/Radio/RadioGroupContext.d.ts +3 -2
- package/Section/SectionGroup.d.ts +20 -0
- package/Section/SectionGroup.js +16 -0
- package/Section/index.d.ts +2 -0
- package/Section/index.js +1 -0
- package/Select/Select.d.ts +55 -1
- package/Select/Select.js +37 -2
- package/Select/typings.d.ts +9 -0
- package/{Selection/Selection.d.ts → SelectionCard/SelectionCard.d.ts} +23 -11
- package/{Selection/Selection.js → SelectionCard/SelectionCard.js} +14 -14
- package/SelectionCard/SelectionCardGroup.d.ts +28 -0
- package/SelectionCard/index.d.ts +12 -0
- package/SelectionCard/index.js +5 -0
- package/Separator/Separator.d.ts +19 -1
- package/Separator/Separator.js +19 -1
- package/Slider/Slider.d.ts +11 -0
- package/Slider/useSlider.d.ts +21 -0
- package/Spin/Spin.d.ts +14 -5
- package/Spin/Spin.js +6 -8
- package/Stepper/Stepper.d.ts +34 -1
- package/Stepper/Stepper.js +34 -1
- package/Stepper/useStepper.d.ts +18 -0
- package/Stepper/useStepper.js +18 -0
- package/Tab/Tab.d.ts +33 -1
- package/Tab/Tab.js +33 -1
- package/Table/Table.d.ts +51 -3
- package/Table/Table.js +52 -4
- package/Table/hooks/useTableDataSource.d.ts +4 -4
- package/Table/hooks/useTableDataSource.js +1 -1
- package/Tag/Tag.d.ts +27 -1
- package/Tag/Tag.js +27 -1
- package/Tag/typings.d.ts +28 -0
- package/Textarea/Textarea.d.ts +28 -1
- package/Textarea/Textarea.js +25 -1
- package/TimePicker/TimePicker.js +1 -1
- package/TimeRangePicker/TimeRangePicker.js +1 -1
- package/Toggle/Toggle.d.ts +34 -1
- package/Toggle/Toggle.js +34 -1
- package/Tooltip/Tooltip.d.ts +39 -1
- package/Tooltip/Tooltip.js +39 -1
- package/Tooltip/useDelayMouseEnterLeave.d.ts +17 -0
- package/Tooltip/useDelayMouseEnterLeave.js +17 -0
- package/Typography/Typography.d.ts +23 -1
- package/Typography/Typography.js +23 -1
- package/Upload/Upload.d.ts +13 -7
- package/Upload/Upload.js +55 -20
- package/Upload/UploadItem.d.ts +3 -3
- package/Upload/UploadItem.js +11 -8
- package/Upload/UploadPictureCard.d.ts +5 -0
- package/Upload/UploadPictureCard.js +10 -6
- package/Upload/Uploader.d.ts +32 -31
- package/Upload/Uploader.js +10 -9
- package/hooks/useClickAway.d.ts +16 -0
- package/hooks/useClickAway.js +16 -0
- package/hooks/useComposeRefs.d.ts +15 -0
- package/hooks/useComposeRefs.js +15 -0
- package/hooks/useDocumentEscapeKeyDown.d.ts +15 -0
- package/hooks/useDocumentEscapeKeyDown.js +15 -0
- package/hooks/useDocumentEvents.d.ts +16 -0
- package/hooks/useDocumentEvents.js +16 -0
- package/hooks/useDocumentTabKeyDown.d.ts +15 -0
- package/hooks/useDocumentTabKeyDown.js +15 -0
- package/hooks/useIsomorphicLayoutEffect.d.ts +16 -0
- package/hooks/useIsomorphicLayoutEffect.js +16 -0
- package/hooks/useLastCallback.d.ts +15 -0
- package/hooks/useLastCallback.js +15 -0
- package/hooks/useLastValue.d.ts +18 -0
- package/hooks/useLastValue.js +18 -0
- package/hooks/usePreviousValue.d.ts +14 -0
- package/hooks/usePreviousValue.js +14 -0
- package/hooks/useScrollLock.d.ts +6 -4
- package/hooks/useScrollLock.js +6 -4
- package/hooks/useTopStack.d.ts +17 -0
- package/hooks/useTopStack.js +17 -0
- package/hooks/useWindowWidth.d.ts +14 -0
- package/hooks/useWindowWidth.js +14 -0
- package/index.d.ts +6 -4
- package/index.js +3 -2
- package/llms.txt +200 -0
- package/package.json +5 -4
- package/Selection/SelectionGroup.d.ts +0 -28
- package/Selection/index.d.ts +0 -12
- package/Selection/index.js +0 -5
|
@@ -11,6 +11,7 @@ import { useAutoCompleteCreation, getFullParsedList } from './useAutoCompleteCre
|
|
|
11
11
|
import { useAutoCompleteKeyboard } from './useAutoCompleteKeyboard.js';
|
|
12
12
|
import { useAutoCompleteSearch } from './useAutoCompleteSearch.js';
|
|
13
13
|
import { useCreationTracker } from './useCreationTracker.js';
|
|
14
|
+
import AutoCompleteInsideTrigger from './AutoCompleteInside.js';
|
|
14
15
|
import { FormControlContext } from '../Form/FormControlContext.js';
|
|
15
16
|
import Dropdown from '../Dropdown/Dropdown.js';
|
|
16
17
|
import cx from 'clsx';
|
|
@@ -30,9 +31,67 @@ function isSingleValue(value) {
|
|
|
30
31
|
return value !== null && value !== undefined && !Array.isArray(value);
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* 自動完成輸入元件,在使用者輸入時即時顯示符合的下拉選項。
|
|
35
|
+
*
|
|
36
|
+
* 支援 `single`(單選)與 `multiple`(多選標籤)兩種模式;`inputPosition` 控制搜尋輸入框
|
|
37
|
+
* 位於下拉選單外(`'outside'`,預設)或內(`'inside'`)。設定 `addable` 與 `onInsert`
|
|
38
|
+
* 可讓使用者動態建立不在選項清單中的項目。`asyncData` 搭配 `onSearch` 可實現非同步搜尋,
|
|
39
|
+
* 輸入時觸發 debounce 查詢並顯示 loading 狀態。若僅需從固定選項中搜尋,請改用 `Select` 元件。
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* import AutoComplete from '@mezzanine-ui/react/AutoComplete';
|
|
44
|
+
*
|
|
45
|
+
* // 單選基本用法
|
|
46
|
+
* <AutoComplete
|
|
47
|
+
* mode="single"
|
|
48
|
+
* options={[{ id: '1', name: 'Apple' }, { id: '2', name: 'Banana' }]}
|
|
49
|
+
* value={selected}
|
|
50
|
+
* onChange={setSelected}
|
|
51
|
+
* placeholder="請搜尋..."
|
|
52
|
+
* />
|
|
53
|
+
*
|
|
54
|
+
* // 多選模式
|
|
55
|
+
* <AutoComplete
|
|
56
|
+
* mode="multiple"
|
|
57
|
+
* options={options}
|
|
58
|
+
* value={selectedList}
|
|
59
|
+
* onChange={setSelectedList}
|
|
60
|
+
* />
|
|
61
|
+
*
|
|
62
|
+
* // 搜尋框置於下拉選單內(inside 模式)
|
|
63
|
+
* <AutoComplete
|
|
64
|
+
* mode="multiple"
|
|
65
|
+
* inputPosition="inside"
|
|
66
|
+
* options={options}
|
|
67
|
+
* value={selectedList}
|
|
68
|
+
* onChange={setSelectedList}
|
|
69
|
+
* />
|
|
70
|
+
*
|
|
71
|
+
* // 非同步搜尋
|
|
72
|
+
* <AutoComplete
|
|
73
|
+
* mode="single"
|
|
74
|
+
* asyncData
|
|
75
|
+
* options={asyncOptions}
|
|
76
|
+
* onSearch={async (text) => { const res = await fetchOptions(text); setAsyncOptions(res); }}
|
|
77
|
+
* value={selected}
|
|
78
|
+
* onChange={setSelected}
|
|
79
|
+
* />
|
|
80
|
+
*
|
|
81
|
+
* // 可新增選項
|
|
82
|
+
* <AutoComplete
|
|
83
|
+
* mode="multiple"
|
|
84
|
+
* addable
|
|
85
|
+
* options={options}
|
|
86
|
+
* onInsert={(text, current) => [...current, { id: text, name: text }]}
|
|
87
|
+
* value={selectedList}
|
|
88
|
+
* onChange={setSelectedList}
|
|
89
|
+
* />
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @see {@link Select} 從固定選項清單中選取時使用
|
|
93
|
+
* @see {@link Input} 純文字輸入欄位
|
|
94
|
+
* @see {@link useAutoCompleteValueControl} 管理 AutoComplete 內部值狀態的 hook
|
|
36
95
|
*/
|
|
37
96
|
const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
38
97
|
const { disabled: disabledFromFormControl, fullWidth: fullWidthFromFormControl, required: requiredFromFormControl, severity, } = useContext(FormControlContext) || {};
|
|
@@ -60,7 +119,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
60
119
|
? (st) => {
|
|
61
120
|
var _a;
|
|
62
121
|
const full = getFullParsedList(st, createSeparators, trimOnCreate);
|
|
63
|
-
return full.length > 1 ? (_a = full[0]) !== null && _a !== void 0 ? _a : undefined : undefined;
|
|
122
|
+
return full.length > 1 ? ((_a = full[0]) !== null && _a !== void 0 ? _a : undefined) : undefined;
|
|
64
123
|
}
|
|
65
124
|
: undefined,
|
|
66
125
|
mode: 'multiple',
|
|
@@ -208,13 +267,22 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
208
267
|
return;
|
|
209
268
|
clearUnselected();
|
|
210
269
|
onRemoveCreated(cleanedOptions);
|
|
211
|
-
}, [
|
|
270
|
+
}, [
|
|
271
|
+
clearUnselected,
|
|
272
|
+
creationEnabled,
|
|
273
|
+
filterUnselected,
|
|
274
|
+
onRemoveCreated,
|
|
275
|
+
optionsProp,
|
|
276
|
+
]);
|
|
212
277
|
useEffect(() => () => {
|
|
213
278
|
clearPendingOptionsReset();
|
|
214
279
|
}, [clearPendingOptionsReset]);
|
|
215
280
|
useEffect(() => {
|
|
216
281
|
var _a;
|
|
217
|
-
|
|
282
|
+
// Multiple mode bridge only applies to SelectTrigger (tags) rendering.
|
|
283
|
+
// In `inputPosition="inside"` we render a plain Input trigger, so the hidden
|
|
284
|
+
// SelectTrigger input bridge is not needed.
|
|
285
|
+
if (!isMultiple || inputPosition === 'inside')
|
|
218
286
|
return;
|
|
219
287
|
const hiddenTriggerInput = (_a = nodeRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(`.${selectClasses.triggerInput}`);
|
|
220
288
|
if (!hiddenTriggerInput)
|
|
@@ -225,7 +293,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
225
293
|
return;
|
|
226
294
|
hiddenTriggerInput.value = bridgeValue;
|
|
227
295
|
hiddenTriggerInput.dispatchEvent(new Event('change', { bubbles: true }));
|
|
228
|
-
}, [isMultiple, searchText, value]);
|
|
296
|
+
}, [inputPosition, isMultiple, searchText, value]);
|
|
229
297
|
// In single mode, show searchText when focused, otherwise show selected value
|
|
230
298
|
// In multiple mode, always return empty string to avoid displaying "0"
|
|
231
299
|
const renderValue = useMemo(() => {
|
|
@@ -245,6 +313,27 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
245
313
|
shouldClearSearchTextOnBlur,
|
|
246
314
|
value,
|
|
247
315
|
]);
|
|
316
|
+
const insideInputValue = useMemo(() => {
|
|
317
|
+
// Inside trigger is a plain Input, so we must decide what to display.
|
|
318
|
+
// - multiple: always show current search text
|
|
319
|
+
// - single: show search text when focused (or when clear-on-blur is disabled)
|
|
320
|
+
if (isMultiple)
|
|
321
|
+
return searchText;
|
|
322
|
+
if (isSingle &&
|
|
323
|
+
(focused || (!shouldClearSearchTextOnBlur && !value && searchText))) {
|
|
324
|
+
return searchText;
|
|
325
|
+
}
|
|
326
|
+
if (isSingleValue(value))
|
|
327
|
+
return value.name;
|
|
328
|
+
return '';
|
|
329
|
+
}, [
|
|
330
|
+
focused,
|
|
331
|
+
isMultiple,
|
|
332
|
+
isSingle,
|
|
333
|
+
searchText,
|
|
334
|
+
shouldClearSearchTextOnBlur,
|
|
335
|
+
value,
|
|
336
|
+
]);
|
|
248
337
|
function getPlaceholder() {
|
|
249
338
|
if (isSingle && focused && isSingleValue(value)) {
|
|
250
339
|
return value.name;
|
|
@@ -276,8 +365,8 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
276
365
|
e.stopPropagation();
|
|
277
366
|
}
|
|
278
367
|
// Only open if not already open to avoid flickering
|
|
279
|
-
//
|
|
280
|
-
if (
|
|
368
|
+
// Ensure inside/uncontrolled can open from the native input focus.
|
|
369
|
+
if (!open) {
|
|
281
370
|
toggleOpen(true);
|
|
282
371
|
}
|
|
283
372
|
onFocus(true);
|
|
@@ -337,12 +426,11 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
337
426
|
const firstPendingText = hasStepByStepBulkSeparator
|
|
338
427
|
? getPendingCreateList(insertText)[0]
|
|
339
428
|
: undefined;
|
|
340
|
-
const searchTextExistWithoutOption = !!(
|
|
429
|
+
const searchTextExistWithoutOption = !!(firstPendingText
|
|
341
430
|
? firstPendingText &&
|
|
342
|
-
options.find((option) => option.name === firstPendingText) ===
|
|
343
|
-
undefined
|
|
431
|
+
options.find((option) => option.name === firstPendingText) === undefined
|
|
344
432
|
: searchText &&
|
|
345
|
-
options.find((option) => option.name === searchText) === undefined)
|
|
433
|
+
options.find((option) => option.name === searchText) === undefined);
|
|
346
434
|
const shouldShowCreateAction = !!(searchTextExistWithoutOption &&
|
|
347
435
|
creationEnabled &&
|
|
348
436
|
(firstPendingText !== null && firstPendingText !== void 0 ? firstPendingText : insertText));
|
|
@@ -359,11 +447,13 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
359
447
|
id: option.id,
|
|
360
448
|
name: option.name,
|
|
361
449
|
};
|
|
362
|
-
// Set checkSite based on mode
|
|
363
|
-
//
|
|
364
|
-
//
|
|
450
|
+
// Set checkSite based on mode and input position.
|
|
451
|
+
// - inside + multiple: keep multiple behavior, but render single-like checked icon
|
|
452
|
+
// at suffix to match product visual expectation.
|
|
453
|
+
// - outside + multiple: render checkbox at prefix.
|
|
454
|
+
// - single: render checked icon at suffix.
|
|
365
455
|
if (mode === 'multiple') {
|
|
366
|
-
result.checkSite = 'prefix';
|
|
456
|
+
result.checkSite = inputPosition === 'inside' ? 'suffix' : 'prefix';
|
|
367
457
|
}
|
|
368
458
|
else {
|
|
369
459
|
result.checkSite = 'suffix';
|
|
@@ -374,7 +464,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
374
464
|
}
|
|
375
465
|
return result;
|
|
376
466
|
});
|
|
377
|
-
}, [isCreated, mode, options]);
|
|
467
|
+
}, [inputPosition, isCreated, mode, options]);
|
|
378
468
|
// Get selected value for dropdown
|
|
379
469
|
const dropdownValue = useMemo(() => {
|
|
380
470
|
if (mode === 'multiple') {
|
|
@@ -392,7 +482,8 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
392
482
|
const shouldForceClearable = isMultiple
|
|
393
483
|
? (isMultipleValue(value) && value.length > 0) ||
|
|
394
484
|
searchText.trim().length > 0
|
|
395
|
-
: isSingleValue(value)
|
|
485
|
+
: isSingleValue(value) ||
|
|
486
|
+
(!shouldClearSearchTextOnBlur && searchText.trim().length > 0);
|
|
396
487
|
// Handle dropdown option selection
|
|
397
488
|
const handleDropdownSelect = useCallback((option) => {
|
|
398
489
|
const selectedValue = options.find((opt) => opt.id === option.id);
|
|
@@ -425,11 +516,15 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
425
516
|
]);
|
|
426
517
|
// Active index for dropdown keyboard navigation
|
|
427
518
|
const [activeIndex, setActiveIndex] = useState(null);
|
|
519
|
+
// Keyboard-only active index: only set by arrow key navigation, not mouse hover.
|
|
520
|
+
// Drives the focus ring (--keyboard-active CSS class) separately from hover highlight.
|
|
521
|
+
const [keyboardActiveIndex, setKeyboardActiveIndex] = useState(null);
|
|
428
522
|
const setListboxHasVisualFocus = useCallback((_focus) => { }, []);
|
|
429
|
-
// Reset activeIndex when options change
|
|
523
|
+
// Reset activeIndex and keyboardActiveIndex when options change
|
|
430
524
|
useEffect(() => {
|
|
431
525
|
if (!dropdownOptions.length) {
|
|
432
526
|
setActiveIndex(null);
|
|
527
|
+
setKeyboardActiveIndex(null);
|
|
433
528
|
return;
|
|
434
529
|
}
|
|
435
530
|
setActiveIndex((prev) => {
|
|
@@ -437,6 +532,11 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
437
532
|
return null;
|
|
438
533
|
return Math.min(prev, dropdownOptions.length - 1);
|
|
439
534
|
});
|
|
535
|
+
setKeyboardActiveIndex((prev) => {
|
|
536
|
+
if (prev === null)
|
|
537
|
+
return null;
|
|
538
|
+
return Math.min(prev, dropdownOptions.length - 1);
|
|
539
|
+
});
|
|
440
540
|
}, [dropdownOptions.length]);
|
|
441
541
|
// Scroll to active option when activeIndex changes
|
|
442
542
|
useEffect(() => {
|
|
@@ -471,6 +571,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
471
571
|
searchText,
|
|
472
572
|
searchTextExistWithoutOption,
|
|
473
573
|
setActiveIndex,
|
|
574
|
+
setKeyboardActiveIndex,
|
|
474
575
|
setInsertText,
|
|
475
576
|
setListboxHasVisualFocus,
|
|
476
577
|
setSearchText,
|
|
@@ -486,19 +587,29 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
486
587
|
e.stopPropagation();
|
|
487
588
|
toggleOpen(false);
|
|
488
589
|
setActiveIndex(null);
|
|
590
|
+
setKeyboardActiveIndex(null);
|
|
489
591
|
setListboxHasVisualFocus(false);
|
|
490
592
|
onFocus(false);
|
|
593
|
+
if (isMultiple && shouldClearSearchTextOnBlur) {
|
|
594
|
+
resetSearchInputsAndOptions();
|
|
595
|
+
cleanupUnselectedCreated();
|
|
596
|
+
}
|
|
491
597
|
(_a = inputElementRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
492
598
|
(_b = inputProps === null || inputProps === void 0 ? void 0 : inputProps.onKeyDown) === null || _b === void 0 ? void 0 : _b.call(inputProps, e);
|
|
493
599
|
return;
|
|
494
600
|
}
|
|
495
601
|
handleInputKeyDown(e);
|
|
496
602
|
}, [
|
|
603
|
+
cleanupUnselectedCreated,
|
|
497
604
|
handleInputKeyDown,
|
|
498
605
|
inputProps,
|
|
606
|
+
isMultiple,
|
|
499
607
|
onFocus,
|
|
608
|
+
resetSearchInputsAndOptions,
|
|
500
609
|
setActiveIndex,
|
|
610
|
+
setKeyboardActiveIndex,
|
|
501
611
|
setListboxHasVisualFocus,
|
|
612
|
+
shouldClearSearchTextOnBlur,
|
|
502
613
|
toggleOpen,
|
|
503
614
|
]);
|
|
504
615
|
// Handle visibility change from Dropdown to prevent flickering
|
|
@@ -515,6 +626,9 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
515
626
|
}
|
|
516
627
|
// In multiple mode, blur/close can be driven by Dropdown visibility updates.
|
|
517
628
|
// Keep input text cleanup consistent even when native input blur is not triggered.
|
|
629
|
+
if (!newOpen) {
|
|
630
|
+
setKeyboardActiveIndex(null);
|
|
631
|
+
}
|
|
518
632
|
if (!newOpen && isMultiple && shouldClearSearchTextOnBlur) {
|
|
519
633
|
if (skipNextMultipleCloseResetRef.current) {
|
|
520
634
|
const menuElement = document.getElementById(menuId);
|
|
@@ -536,6 +650,7 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
536
650
|
menuId,
|
|
537
651
|
open,
|
|
538
652
|
resetSearchInputsAndOptions,
|
|
653
|
+
setKeyboardActiveIndex,
|
|
539
654
|
shouldClearSearchTextOnBlur,
|
|
540
655
|
toggleOpen,
|
|
541
656
|
]);
|
|
@@ -568,22 +683,27 @@ const AutoComplete = forwardRef(function AutoComplete(props, ref) {
|
|
|
568
683
|
? createActionText
|
|
569
684
|
? createActionText(createActionDisplayText)
|
|
570
685
|
: createActionTextTemplate.replace('{text}', createActionDisplayText)
|
|
571
|
-
: undefined, activeIndex: activeIndex, disabled: isInputDisabled, emptyText: emptyText, followText: searchText, inputPosition: inputPosition, isMatchInputValue: true, listboxId: menuId, loadingText: loadingText, loadingPosition: loadingPosition, maxHeight: menuMaxHeight, mode: mode, onActionCustom: shouldShowCreateAction ? handleActionCustom : undefined, onItemHover: setActiveIndex, onSelect: handleDropdownSelect, onVisibilityChange: handleVisibilityChange, open: open, options: asyncData && isLoading ? [] : dropdownOptions, placement: "bottom", sameWidth: true, showDropdownActions: shouldShowCreateAction, showActionShowTopBar: shouldShowCreateAction, status: dropdownStatus, type: "default", value: dropdownValue, zIndex: dropdownZIndex, globalPortal: globalPortal, onReachBottom: onReachBottom, onLeaveBottom: onLeaveBottom, children: jsx(
|
|
686
|
+
: undefined, activeIndex: activeIndex, keyboardActiveIndex: keyboardActiveIndex, disabled: isInputDisabled, emptyText: emptyText, followText: searchText, inputPosition: inputPosition, isMatchInputValue: true, listboxId: menuId, loadingText: loadingText, loadingPosition: loadingPosition, maxHeight: menuMaxHeight, mode: mode, onActionCustom: shouldShowCreateAction ? handleActionCustom : undefined, onItemHover: setActiveIndex, onSelect: handleDropdownSelect, onVisibilityChange: handleVisibilityChange, open: open, options: asyncData && isLoading ? [] : dropdownOptions, placement: "bottom", sameWidth: true, showDropdownActions: shouldShowCreateAction, showActionShowTopBar: shouldShowCreateAction, status: dropdownStatus, toggleCheckedOnClick: inputPosition === 'inside' && mode === 'multiple' ? false : undefined, type: "default", value: dropdownValue, zIndex: dropdownZIndex, globalPortal: globalPortal, onReachBottom: onReachBottom, onLeaveBottom: onLeaveBottom, children: inputPosition === 'inside' ? (jsx(AutoCompleteInsideTrigger, { active: open, className: className, clearable: shouldForceClearable, disabled: isInputDisabled, error: error, fullWidth: fullWidth, inputRef: composedInputRef, onClear: handleClear, placeholder: getPlaceholder(), resolvedInputProps: {
|
|
687
|
+
...resolvedInputProps,
|
|
688
|
+
onClick: (e) => {
|
|
689
|
+
var _a;
|
|
690
|
+
(_a = resolvedInputProps.onClick) === null || _a === void 0 ? void 0 : _a.call(resolvedInputProps, e);
|
|
691
|
+
},
|
|
692
|
+
}, size: size, value: insideInputValue })) : (jsx(SelectTrigger, { ref: composedRef, active: open, className: className, clearable: true, disabled: isInputDisabled, fullWidth: fullWidth, isForceClearable: shouldForceClearable, inputRef: composedInputRef, mode: mode, onTagClose: wrappedOnChange, onClear: handleClear, overflowStrategy: isMultiple ? (overflowStrategy !== null && overflowStrategy !== void 0 ? overflowStrategy : 'wrap') : overflowStrategy, placeholder: getPlaceholder(), prefix: prefix, readOnly: false, required: required, type: error ? 'error' : 'default', inputProps: {
|
|
572
693
|
...resolvedInputProps,
|
|
573
694
|
onClick: (e) => {
|
|
574
695
|
var _a;
|
|
575
696
|
// When inputPosition is inside, let Dropdown handle the click event
|
|
576
697
|
// Otherwise, stop propagation to prevent conflicts
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
}
|
|
698
|
+
// This branch is only rendered when `inputPosition !== 'inside'`.
|
|
699
|
+
e.stopPropagation();
|
|
580
700
|
(_a = resolvedInputProps.onClick) === null || _a === void 0 ? void 0 : _a.call(resolvedInputProps, e);
|
|
581
701
|
},
|
|
582
702
|
}, searchText: searchText, size: size, showTextInputAfterTags: true, suffixAction: onClickSuffixActionIcon, value: mode === 'multiple' &&
|
|
583
703
|
isMultipleValue(value) &&
|
|
584
704
|
value.length === 0
|
|
585
705
|
? undefined
|
|
586
|
-
: (value !== null && value !== void 0 ? value : undefined), ...(mode === 'single' && renderValue ? { renderValue } : {}) }) }) }) }));
|
|
706
|
+
: (value !== null && value !== void 0 ? value : undefined), ...(mode === 'single' && renderValue ? { renderValue } : {}) })) }) }) }));
|
|
587
707
|
});
|
|
588
708
|
|
|
589
709
|
export { AutoComplete as default };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type MouseEventHandler, type Ref } from 'react';
|
|
2
|
+
import type { InputProps } from '../Input';
|
|
3
|
+
import type { SelectTriggerInputProps } from '../Select/typings';
|
|
4
|
+
export interface AutoCompleteInsideTriggerProps {
|
|
5
|
+
/**
|
|
6
|
+
* Disabled state for the input.
|
|
7
|
+
*/
|
|
8
|
+
disabled: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Error state for the input.
|
|
11
|
+
*/
|
|
12
|
+
error: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the trigger should render as active (focused/open).
|
|
15
|
+
*/
|
|
16
|
+
active: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Input display value (usually the current search text).
|
|
19
|
+
*/
|
|
20
|
+
value: string;
|
|
21
|
+
/**
|
|
22
|
+
* Input placeholder text.
|
|
23
|
+
*/
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Input variant sizing.
|
|
27
|
+
*/
|
|
28
|
+
size?: InputProps['size'];
|
|
29
|
+
/**
|
|
30
|
+
* Whether the input should occupy full width.
|
|
31
|
+
*/
|
|
32
|
+
fullWidth?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Additional class name for the trigger.
|
|
35
|
+
*/
|
|
36
|
+
className?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Input ref (points to the underlying <input/> element).
|
|
39
|
+
*/
|
|
40
|
+
inputRef?: Ref<HTMLInputElement>;
|
|
41
|
+
/**
|
|
42
|
+
* Props forwarded to the underlying input element.
|
|
43
|
+
*/
|
|
44
|
+
resolvedInputProps: SelectTriggerInputProps;
|
|
45
|
+
/**
|
|
46
|
+
* Whether to show the clear icon.
|
|
47
|
+
*/
|
|
48
|
+
clearable: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Input clear handler.
|
|
51
|
+
*/
|
|
52
|
+
onClear?: MouseEventHandler;
|
|
53
|
+
}
|
|
54
|
+
export default function AutoCompleteInsideTrigger(props: AutoCompleteInsideTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import Input from '../Input/Input.js';
|
|
4
|
+
|
|
5
|
+
function extractIdAndName(props) {
|
|
6
|
+
const { id, name, readOnly, onChange, ...rest } = props;
|
|
7
|
+
return { id, name, readOnly, onChange, rest };
|
|
8
|
+
}
|
|
9
|
+
function AutoCompleteInsideTrigger(props) {
|
|
10
|
+
const { active, className, clearable, disabled, error, fullWidth, inputRef, onClear, placeholder, resolvedInputProps, size, value, } = props;
|
|
11
|
+
const { id, name, readOnly, onChange, rest } = extractIdAndName(resolvedInputProps);
|
|
12
|
+
return (jsx(Input, { active: active, className: className, ...(disabled ? { disabled: true } : {}), error: error, fullWidth: fullWidth, id: id, name: name, placeholder: placeholder, readonly: readOnly || undefined, onChange: onChange, size: size, value: value, clearable: clearable, onClear: onClear,
|
|
13
|
+
// keep clear icon visibility behavior consistent with SelectTrigger
|
|
14
|
+
forceShowClearable: clearable, inputRef: inputRef, inputProps: rest }));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { AutoCompleteInsideTrigger as default };
|
|
@@ -19,6 +19,7 @@ type UseAutoCompleteKeyboardParams = {
|
|
|
19
19
|
searchText: string;
|
|
20
20
|
searchTextExistWithoutOption: boolean;
|
|
21
21
|
setActiveIndex: Dispatch<SetStateAction<number | null>>;
|
|
22
|
+
setKeyboardActiveIndex?: Dispatch<SetStateAction<number | null>>;
|
|
22
23
|
setListboxHasVisualFocus: (focus: boolean) => void;
|
|
23
24
|
setInsertText: (value: string) => void;
|
|
24
25
|
setSearchText: (value: string) => void;
|
|
@@ -27,7 +28,7 @@ type UseAutoCompleteKeyboardParams = {
|
|
|
27
28
|
value: SelectValue[] | SelectValue | null | undefined;
|
|
28
29
|
wrappedOnChange: (chooseOption: SelectValue | null) => SelectValue[] | SelectValue | null;
|
|
29
30
|
};
|
|
30
|
-
export declare function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropdownOptions, handleActionCustom, handleBulkCreate, handleDropdownSelect, inputPropsOnKeyDown, inputRef, mode, onFocus, open, processBulkCreate, searchText, searchTextExistWithoutOption, setActiveIndex, setInsertText, setListboxHasVisualFocus, setSearchText, stepByStepBulkCreate, toggleOpen, value, wrappedOnChange, }: UseAutoCompleteKeyboardParams): {
|
|
31
|
+
export declare function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropdownOptions, handleActionCustom, handleBulkCreate, handleDropdownSelect, inputPropsOnKeyDown, inputRef, mode, onFocus, open, processBulkCreate, searchText, searchTextExistWithoutOption, setActiveIndex, setKeyboardActiveIndex, setInsertText, setListboxHasVisualFocus, setSearchText, stepByStepBulkCreate, toggleOpen, value, wrappedOnChange, }: UseAutoCompleteKeyboardParams): {
|
|
31
32
|
handleInputKeyDown: (e: KeyboardEvent<HTMLInputElement>) => void;
|
|
32
33
|
};
|
|
33
34
|
export {};
|
|
@@ -4,7 +4,7 @@ import { createDropdownKeydownHandler } from '../Dropdown/dropdownKeydownHandler
|
|
|
4
4
|
function isMultipleValue(value) {
|
|
5
5
|
return Array.isArray(value);
|
|
6
6
|
}
|
|
7
|
-
function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropdownOptions, handleActionCustom, handleBulkCreate, handleDropdownSelect, inputPropsOnKeyDown, inputRef, mode, onFocus, open, processBulkCreate, searchText, searchTextExistWithoutOption, setActiveIndex, setInsertText, setListboxHasVisualFocus, setSearchText, stepByStepBulkCreate = false, toggleOpen, value, wrappedOnChange, }) {
|
|
7
|
+
function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropdownOptions, handleActionCustom, handleBulkCreate, handleDropdownSelect, inputPropsOnKeyDown, inputRef, mode, onFocus, open, processBulkCreate, searchText, searchTextExistWithoutOption, setActiveIndex, setKeyboardActiveIndex, setInsertText, setListboxHasVisualFocus, setSearchText, stepByStepBulkCreate = false, toggleOpen, value, wrappedOnChange, }) {
|
|
8
8
|
const handleKeyDown = useCallback((e) => createDropdownKeydownHandler({
|
|
9
9
|
activeIndex,
|
|
10
10
|
onEnterSelect: (option) => {
|
|
@@ -18,6 +18,7 @@ function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropd
|
|
|
18
18
|
var _a;
|
|
19
19
|
toggleOpen(false);
|
|
20
20
|
setActiveIndex(null);
|
|
21
|
+
setKeyboardActiveIndex === null || setKeyboardActiveIndex === void 0 ? void 0 : setKeyboardActiveIndex(null);
|
|
21
22
|
setListboxHasVisualFocus(false);
|
|
22
23
|
if (inputRef && typeof inputRef !== 'function') {
|
|
23
24
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
@@ -26,6 +27,7 @@ function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropd
|
|
|
26
27
|
open,
|
|
27
28
|
options: dropdownOptions,
|
|
28
29
|
setActiveIndex,
|
|
30
|
+
setKeyboardActiveIndex,
|
|
29
31
|
setListboxHasVisualFocus,
|
|
30
32
|
setOpen: (newOpen) => {
|
|
31
33
|
if (newOpen && !open) {
|
|
@@ -44,6 +46,7 @@ function useAutoCompleteKeyboard({ activeIndex, addable, createSeparators, dropd
|
|
|
44
46
|
onFocus,
|
|
45
47
|
open,
|
|
46
48
|
setActiveIndex,
|
|
49
|
+
setKeyboardActiveIndex,
|
|
47
50
|
setListboxHasVisualFocus,
|
|
48
51
|
toggleOpen,
|
|
49
52
|
]);
|
package/Backdrop/Backdrop.d.ts
CHANGED
|
@@ -33,7 +33,39 @@ export interface BackdropProps extends Pick<PortalProps, 'children' | 'container
|
|
|
33
33
|
variant?: BackdropVariant;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* 用於 Modal、Drawer 等覆蓋層元件的遮罩底層元件。
|
|
37
|
+
*
|
|
38
|
+
* 透過 `Portal` 渲染至指定的 DOM 容器,並使用 `Fade` 動畫處理顯示與隱藏過渡。
|
|
39
|
+
* 開啟時會自動鎖定 body 捲動(可透過 `disableScrollLock` 停用)。
|
|
40
|
+
* 點擊遮罩時預設觸發 `onClose`,可透過 `disableCloseOnBackdropClick` 停用此行為。
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* import Backdrop from '@mezzanine-ui/react/Backdrop';
|
|
45
|
+
*
|
|
46
|
+
* // 基本用法
|
|
47
|
+
* <Backdrop open={open} onClose={() => setOpen(false)}>
|
|
48
|
+
* <div>浮層內容</div>
|
|
49
|
+
* </Backdrop>
|
|
50
|
+
*
|
|
51
|
+
* // 使用淺色遮罩並停用點擊關閉
|
|
52
|
+
* <Backdrop
|
|
53
|
+
* open={open}
|
|
54
|
+
* onClose={() => setOpen(false)}
|
|
55
|
+
* variant="light"
|
|
56
|
+
* disableCloseOnBackdropClick
|
|
57
|
+
* >
|
|
58
|
+
* <div>強制顯示的內容</div>
|
|
59
|
+
* </Backdrop>
|
|
60
|
+
*
|
|
61
|
+
* // 渲染至自訂容器
|
|
62
|
+
* <Backdrop open={open} onClose={() => setOpen(false)} container={containerRef}>
|
|
63
|
+
* <div>相對定位的浮層</div>
|
|
64
|
+
* </Backdrop>
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @see {@link Modal} 對話框元件
|
|
68
|
+
* @see {@link Drawer} 抽屜面板元件
|
|
37
69
|
*/
|
|
38
70
|
declare const Backdrop: import("react").ForwardRefExoticComponent<BackdropProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
39
71
|
export default Backdrop;
|
package/Backdrop/Backdrop.js
CHANGED
|
@@ -9,7 +9,39 @@ import Fade from '../Transition/Fade.js';
|
|
|
9
9
|
import cx from 'clsx';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* 用於 Modal、Drawer 等覆蓋層元件的遮罩底層元件。
|
|
13
|
+
*
|
|
14
|
+
* 透過 `Portal` 渲染至指定的 DOM 容器,並使用 `Fade` 動畫處理顯示與隱藏過渡。
|
|
15
|
+
* 開啟時會自動鎖定 body 捲動(可透過 `disableScrollLock` 停用)。
|
|
16
|
+
* 點擊遮罩時預設觸發 `onClose`,可透過 `disableCloseOnBackdropClick` 停用此行為。
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import Backdrop from '@mezzanine-ui/react/Backdrop';
|
|
21
|
+
*
|
|
22
|
+
* // 基本用法
|
|
23
|
+
* <Backdrop open={open} onClose={() => setOpen(false)}>
|
|
24
|
+
* <div>浮層內容</div>
|
|
25
|
+
* </Backdrop>
|
|
26
|
+
*
|
|
27
|
+
* // 使用淺色遮罩並停用點擊關閉
|
|
28
|
+
* <Backdrop
|
|
29
|
+
* open={open}
|
|
30
|
+
* onClose={() => setOpen(false)}
|
|
31
|
+
* variant="light"
|
|
32
|
+
* disableCloseOnBackdropClick
|
|
33
|
+
* >
|
|
34
|
+
* <div>強制顯示的內容</div>
|
|
35
|
+
* </Backdrop>
|
|
36
|
+
*
|
|
37
|
+
* // 渲染至自訂容器
|
|
38
|
+
* <Backdrop open={open} onClose={() => setOpen(false)} container={containerRef}>
|
|
39
|
+
* <div>相對定位的浮層</div>
|
|
40
|
+
* </Backdrop>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @see {@link Modal} 對話框元件
|
|
44
|
+
* @see {@link Drawer} 抽屜面板元件
|
|
13
45
|
*/
|
|
14
46
|
const Backdrop = forwardRef(function Backdrop(props, ref) {
|
|
15
47
|
const { children, className, container, disableCloseOnBackdropClick = false, disablePortal, disableScrollLock = false, onBackdropClick, onClose, open = false, variant = 'dark', ...rest } = props;
|
package/Badge/Badge.d.ts
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { BadgeCountVariant } from '@mezzanine-ui/core/badge';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* 徽章元件,用於顯示數字計數、狀態圓點或文字標籤。
|
|
4
|
+
*
|
|
5
|
+
* 支援四種 variant 類型:count(數字計數)、dot(狀態圓點)、dot 含文字以及 text(純文字標籤)。
|
|
6
|
+
* 計數型徽章可設定 `overflowCount` 限制最大顯示數值;當 `count` 為 0 時徽章自動隱藏。
|
|
7
|
+
* 使用 `children` 時(僅限 dot 型),徽章會以覆疊方式出現在子元素右上角。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* import Badge from '@mezzanine-ui/react/Badge';
|
|
12
|
+
*
|
|
13
|
+
* // 數字計數徽章
|
|
14
|
+
* <Badge variant="count-alert" count={5} />
|
|
15
|
+
*
|
|
16
|
+
* // 超出上限顯示 99+
|
|
17
|
+
* <Badge variant="count-brand" count={120} overflowCount={99} />
|
|
18
|
+
*
|
|
19
|
+
* // 狀態圓點(附著於圖示右上角)
|
|
20
|
+
* <Badge variant="dot-alert">
|
|
21
|
+
* <BellIcon />
|
|
22
|
+
* </Badge>
|
|
23
|
+
*
|
|
24
|
+
* // 文字徽章
|
|
25
|
+
* <Badge variant="text-brand" text="NEW" />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @see {@link BadgeContainer} 搭配容器元件使用絕對定位覆疊效果
|
|
4
29
|
*/
|
|
5
30
|
declare const Badge: import("react").ForwardRefExoticComponent<(Omit<Omit<NativeElementPropsWithoutKeyAndRef<"span">, "children"> & {
|
|
6
31
|
children?: never;
|
package/Badge/Badge.js
CHANGED
|
@@ -11,7 +11,32 @@ const isCountVariant = (variant) => [
|
|
|
11
11
|
'count-info',
|
|
12
12
|
].includes(variant);
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* 徽章元件,用於顯示數字計數、狀態圓點或文字標籤。
|
|
15
|
+
*
|
|
16
|
+
* 支援四種 variant 類型:count(數字計數)、dot(狀態圓點)、dot 含文字以及 text(純文字標籤)。
|
|
17
|
+
* 計數型徽章可設定 `overflowCount` 限制最大顯示數值;當 `count` 為 0 時徽章自動隱藏。
|
|
18
|
+
* 使用 `children` 時(僅限 dot 型),徽章會以覆疊方式出現在子元素右上角。
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import Badge from '@mezzanine-ui/react/Badge';
|
|
23
|
+
*
|
|
24
|
+
* // 數字計數徽章
|
|
25
|
+
* <Badge variant="count-alert" count={5} />
|
|
26
|
+
*
|
|
27
|
+
* // 超出上限顯示 99+
|
|
28
|
+
* <Badge variant="count-brand" count={120} overflowCount={99} />
|
|
29
|
+
*
|
|
30
|
+
* // 狀態圓點(附著於圖示右上角)
|
|
31
|
+
* <Badge variant="dot-alert">
|
|
32
|
+
* <BellIcon />
|
|
33
|
+
* </Badge>
|
|
34
|
+
*
|
|
35
|
+
* // 文字徽章
|
|
36
|
+
* <Badge variant="text-brand" text="NEW" />
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @see {@link BadgeContainer} 搭配容器元件使用絕對定位覆疊效果
|
|
15
40
|
*/
|
|
16
41
|
const Badge = forwardRef(function Badge(props, ref) {
|
|
17
42
|
const { children, count, className, overflowCount, size, text, variant, ...rest } = props;
|
package/Badge/typings.d.ts
CHANGED
|
@@ -37,11 +37,20 @@ type BadgeCountProps = {
|
|
|
37
37
|
variant: BadgeCountVariant;
|
|
38
38
|
};
|
|
39
39
|
type BadgeTextProps = {
|
|
40
|
+
/** 此變體下不適用。 */
|
|
40
41
|
children?: never;
|
|
42
|
+
/** 此變體下不適用。 */
|
|
41
43
|
count?: never;
|
|
44
|
+
/** 此變體下不適用。 */
|
|
42
45
|
overflowCount?: never;
|
|
46
|
+
/**
|
|
47
|
+
* 文字徽章的尺寸。
|
|
48
|
+
* @default 'main'
|
|
49
|
+
*/
|
|
43
50
|
size?: BadgeTextSize;
|
|
51
|
+
/** 徽章顯示的文字內容。 */
|
|
44
52
|
text: string;
|
|
53
|
+
/** 文字徽章的視覺變體。 */
|
|
45
54
|
variant: BadgeTextVariant;
|
|
46
55
|
};
|
|
47
56
|
type BadgeDotWithTextProps = {
|
|
@@ -57,11 +66,17 @@ type BadgeDotWithTextProps = {
|
|
|
57
66
|
variant: BadgeDotVariant;
|
|
58
67
|
};
|
|
59
68
|
type BadgeDotProps = {
|
|
69
|
+
/** 徽章附著的子元素,圓點會顯示在子元素右上角。 */
|
|
60
70
|
children?: ReactNode;
|
|
71
|
+
/** 此變體下不適用。 */
|
|
61
72
|
count?: never;
|
|
73
|
+
/** 此變體下不適用。 */
|
|
62
74
|
overflowCount?: never;
|
|
75
|
+
/** 此變體下不適用。 */
|
|
63
76
|
size?: never;
|
|
77
|
+
/** 此變體下不適用。 */
|
|
64
78
|
text?: never;
|
|
79
|
+
/** 圓點徽章的視覺變體。 */
|
|
65
80
|
variant: BadgeDotVariant;
|
|
66
81
|
};
|
|
67
82
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const BreadcrumbDropdown: import("react").ForwardRefExoticComponent<Omit<import("../Dropdown").DropdownProps, "children"> & {
|
|
1
|
+
declare const BreadcrumbDropdown: import("react").ForwardRefExoticComponent<Omit<import("../Dropdown").DropdownProps, "children" | "onScroll"> & {
|
|
2
2
|
className?: string;
|
|
3
3
|
current?: boolean;
|
|
4
4
|
href?: never;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const BreadcrumbOverflowMenuDropdown: import("react").ForwardRefExoticComponent<Omit<import("../Dropdown").DropdownProps, "children"> & {
|
|
1
|
+
declare const BreadcrumbOverflowMenuDropdown: import("react").ForwardRefExoticComponent<Omit<import("../Dropdown").DropdownProps, "children" | "onScroll"> & {
|
|
2
2
|
className?: string;
|
|
3
3
|
current?: boolean;
|
|
4
4
|
href?: never;
|