@lumx/react 4.9.0-alpha.1 → 4.9.0-alpha.3
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/_internal/{C9YCH96e.js → Dpulze-1.js} +3 -3
- package/_internal/Dpulze-1.js.map +1 -0
- package/index.d.ts +164 -25
- package/index.js +485 -223
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/utils/index.js +1 -1
- package/_internal/C9YCH96e.js.map +0 -1
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Kind as Kind$1, Size as Size$1, ColorPalette as ColorPalette$1, Emphasis as Emphasis$1, ColorVariant, VISUALLY_HIDDEN, Theme as Theme$1, AspectRatio as AspectRatio$1, DOCUMENT, IS_BROWSER as IS_BROWSER$1, WINDOW, DIALOG_TRANSITION_DURATION, Orientation as Orientation$1, Alignment, NOTIFICATION_TRANSITION_DURATION } from '@lumx/core/js/constants';
|
|
1
|
+
import { Kind as Kind$1, Size as Size$1, ColorPalette as ColorPalette$1, Emphasis as Emphasis$1, ColorVariant, VISUALLY_HIDDEN, Theme as Theme$1, AspectRatio as AspectRatio$1, DOCUMENT, IS_BROWSER as IS_BROWSER$1, WINDOW, DIALOG_TRANSITION_DURATION, Orientation as Orientation$1, Alignment as Alignment$1, NOTIFICATION_TRANSITION_DURATION } from '@lumx/core/js/constants';
|
|
2
2
|
export * from '@lumx/core/js/constants';
|
|
3
3
|
export * from '@lumx/core/js/types';
|
|
4
4
|
import * as React from 'react';
|
|
@@ -9,7 +9,7 @@ import ReactDOM__default from 'react-dom';
|
|
|
9
9
|
import { classNames, onEscapePressed, onEnterPressed as onEnterPressed$1, detectHorizontalSwipe } from '@lumx/core/js/utils';
|
|
10
10
|
import last from 'lodash/last.js';
|
|
11
11
|
import pull from 'lodash/pull.js';
|
|
12
|
-
import { u as useDisabledStateContext, P as Portal, C as ClickAwayProvider } from './_internal/
|
|
12
|
+
import { u as useDisabledStateContext, P as Portal, C as ClickAwayProvider } from './_internal/Dpulze-1.js';
|
|
13
13
|
import isEmpty from 'lodash/isEmpty.js';
|
|
14
14
|
import get from 'lodash/get.js';
|
|
15
15
|
import { getDisabledState } from '@lumx/core/js/utils/disabledState';
|
|
@@ -892,6 +892,8 @@ const TOOLTIP_LONG_PRESS_DELAY = {
|
|
|
892
892
|
/**
|
|
893
893
|
* Alignments.
|
|
894
894
|
*/
|
|
895
|
+
const Alignment = {
|
|
896
|
+
left: 'left'};
|
|
895
897
|
const Theme = {
|
|
896
898
|
light: 'light',
|
|
897
899
|
dark: 'dark'
|
|
@@ -946,7 +948,10 @@ const AspectRatio = {
|
|
|
946
948
|
/** Ratio 3:2 */
|
|
947
949
|
horizontal: 'horizontal',
|
|
948
950
|
/** Ratio 1:1 */
|
|
949
|
-
square: 'square'
|
|
951
|
+
square: 'square',
|
|
952
|
+
/** Ratio constrained by the parent. */
|
|
953
|
+
free: 'free'
|
|
954
|
+
};
|
|
950
955
|
/**
|
|
951
956
|
* Semantic info about the purpose of the component
|
|
952
957
|
*/
|
|
@@ -1637,6 +1642,7 @@ const IconButton = forwardRef((props, ref) => {
|
|
|
1637
1642
|
tooltipProps,
|
|
1638
1643
|
hideTooltip,
|
|
1639
1644
|
label,
|
|
1645
|
+
theme = defaultTheme,
|
|
1640
1646
|
...forwardedProps
|
|
1641
1647
|
} = props;
|
|
1642
1648
|
const {
|
|
@@ -1654,7 +1660,7 @@ const IconButton = forwardRef((props, ref) => {
|
|
|
1654
1660
|
...tooltipProps,
|
|
1655
1661
|
children: IconButton$1({
|
|
1656
1662
|
ref,
|
|
1657
|
-
theme
|
|
1663
|
+
theme,
|
|
1658
1664
|
...disabledStateProps,
|
|
1659
1665
|
...restOfOtherProps,
|
|
1660
1666
|
handleClick: onClick,
|
|
@@ -3207,7 +3213,7 @@ function setupListbox(handle, signal, notify) {
|
|
|
3207
3213
|
*
|
|
3208
3214
|
* @see https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
3209
3215
|
*
|
|
3210
|
-
* @param callbacks Callbacks
|
|
3216
|
+
* @param callbacks Callbacks invoked on combobox events (e.g. option selection).
|
|
3211
3217
|
* @param options Options for configuring the shared combobox behavior.
|
|
3212
3218
|
* @param onTriggerAttach Optional callback invoked when the trigger is registered and the signal is ready.
|
|
3213
3219
|
* Used by mode-specific wrappers (setupComboboxInput/Button) to automatically
|
|
@@ -3238,6 +3244,9 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3238
3244
|
/** Last notified isEmpty state, to avoid redundant `emptyChange` notifications. */
|
|
3239
3245
|
let lastIsEmpty = true;
|
|
3240
3246
|
|
|
3247
|
+
/** Last notified input value, to re-fire `emptyChange` when the user keeps typing while empty. */
|
|
3248
|
+
let lastInputValue = '';
|
|
3249
|
+
|
|
3241
3250
|
/** Event subscribers managed by the handle. */
|
|
3242
3251
|
const subscribers = {
|
|
3243
3252
|
open: new Set(),
|
|
@@ -3253,7 +3262,9 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3253
3262
|
}
|
|
3254
3263
|
|
|
3255
3264
|
/**
|
|
3256
|
-
* Notify all registered sections and fire `emptyChange` if the visible option count changed
|
|
3265
|
+
* Notify all registered sections and fire `emptyChange` if the visible option count changed
|
|
3266
|
+
* or if the input value changed while the list is empty (so `emptyMessage` callbacks get
|
|
3267
|
+
* the updated query string).
|
|
3257
3268
|
* Called whenever the set of visible options may have changed (option register/unregister, filter change).
|
|
3258
3269
|
*/
|
|
3259
3270
|
function notifyVisibilityChange() {
|
|
@@ -3265,9 +3276,10 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3265
3276
|
if (!reg.lastFiltered) visibleCount += 1;
|
|
3266
3277
|
}
|
|
3267
3278
|
const isEmpty = visibleCount === 0;
|
|
3268
|
-
|
|
3279
|
+
const inputValue = trigger?.value ?? '';
|
|
3280
|
+
if (isEmpty !== lastIsEmpty || isEmpty && inputValue !== lastInputValue) {
|
|
3269
3281
|
lastIsEmpty = isEmpty;
|
|
3270
|
-
|
|
3282
|
+
lastInputValue = inputValue;
|
|
3271
3283
|
notify('emptyChange', {
|
|
3272
3284
|
isEmpty,
|
|
3273
3285
|
inputValue
|
|
@@ -3286,6 +3298,22 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3286
3298
|
/** Timer for debounced loading announcement. */
|
|
3287
3299
|
let loadingTimer;
|
|
3288
3300
|
|
|
3301
|
+
/** Whether a loading announcement has been sent since the last open. */
|
|
3302
|
+
let announcementSent = false;
|
|
3303
|
+
|
|
3304
|
+
/** Start or restart the debounced loading announcement timer if conditions are met. */
|
|
3305
|
+
function startLoadingAnnouncementTimer() {
|
|
3306
|
+
clearTimeout(loadingTimer);
|
|
3307
|
+
if (skeletonCount > 0 && isOpenState) {
|
|
3308
|
+
loadingTimer = setTimeout(() => {
|
|
3309
|
+
if (skeletonCount > 0 && isOpenState) {
|
|
3310
|
+
announcementSent = true;
|
|
3311
|
+
notify('loadingAnnouncement', true);
|
|
3312
|
+
}
|
|
3313
|
+
}, LOADING_ANNOUNCEMENT_DELAY);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3289
3317
|
/**
|
|
3290
3318
|
* Called when the skeleton count transitions between 0 and >0 (or vice versa).
|
|
3291
3319
|
* Fires `loadingChange` immediately and manages the debounced `loadingAnnouncement`.
|
|
@@ -3293,15 +3321,14 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3293
3321
|
function onSkeletonCountChange() {
|
|
3294
3322
|
const isLoading = skeletonCount > 0;
|
|
3295
3323
|
notify('loadingChange', isLoading);
|
|
3296
|
-
clearTimeout(loadingTimer);
|
|
3297
3324
|
if (isLoading) {
|
|
3298
|
-
|
|
3299
|
-
if (skeletonCount > 0) {
|
|
3300
|
-
notify('loadingAnnouncement', true);
|
|
3301
|
-
}
|
|
3302
|
-
}, LOADING_ANNOUNCEMENT_DELAY);
|
|
3325
|
+
startLoadingAnnouncementTimer();
|
|
3303
3326
|
} else {
|
|
3304
|
-
|
|
3327
|
+
clearTimeout(loadingTimer);
|
|
3328
|
+
if (announcementSent) {
|
|
3329
|
+
announcementSent = false;
|
|
3330
|
+
notify('loadingAnnouncement', false);
|
|
3331
|
+
}
|
|
3305
3332
|
}
|
|
3306
3333
|
}
|
|
3307
3334
|
|
|
@@ -3343,17 +3370,19 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3343
3370
|
case 'Enter':
|
|
3344
3371
|
if (handle.isOpen && nav?.hasActiveItem && nav.activeItem) {
|
|
3345
3372
|
if (!isOptionDisabled(nav.activeItem)) {
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
// Option cell: select the option.
|
|
3351
|
-
handle.select(nav.activeItem);
|
|
3352
|
-
}
|
|
3373
|
+
// Click the active item. For option cells, the delegated click handler
|
|
3374
|
+
// on the listbox will call handle.select() and handle closing.
|
|
3375
|
+
// For action cells and link options, the native click fires too.
|
|
3376
|
+
nav.activeItem.click();
|
|
3353
3377
|
}
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3378
|
+
// Close for single-select. For option cells the delegated handler
|
|
3379
|
+
// already closed, but setIsOpen(false) is idempotent. For action cells
|
|
3380
|
+
// and disabled options, the delegated handler did NOT close, so this is needed.
|
|
3381
|
+
if (!handle.isMultiSelect) {
|
|
3382
|
+
handle.setIsOpen(false);
|
|
3383
|
+
}
|
|
3384
|
+
} else if (!handle.isMultiSelect) {
|
|
3385
|
+
// No active item — toggle open/close.
|
|
3357
3386
|
handle.setIsOpen(!handle.isOpen);
|
|
3358
3387
|
}
|
|
3359
3388
|
flag = true;
|
|
@@ -3406,10 +3435,12 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3406
3435
|
flag = true;
|
|
3407
3436
|
break;
|
|
3408
3437
|
case 'Tab':
|
|
3409
|
-
//
|
|
3438
|
+
// Click the active option (if any) and close. Let Tab propagate.
|
|
3410
3439
|
if (nav?.hasActiveItem && nav.activeItem && !isOptionDisabled(nav.activeItem)) {
|
|
3411
|
-
|
|
3440
|
+
nav.activeItem.click();
|
|
3412
3441
|
}
|
|
3442
|
+
// The delegated click handler closes for single-select, but for multi-select
|
|
3443
|
+
// or when no item is active, we still need to explicitly close.
|
|
3413
3444
|
handle.setIsOpen(false);
|
|
3414
3445
|
break;
|
|
3415
3446
|
case 'PageUp':
|
|
@@ -3484,16 +3515,38 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3484
3515
|
isOpenState = isOpen;
|
|
3485
3516
|
if (!isOpen) {
|
|
3486
3517
|
focusNav?.clear();
|
|
3518
|
+
// Reset announcement state so it retriggers on next open
|
|
3519
|
+
clearTimeout(loadingTimer);
|
|
3520
|
+
if (announcementSent) {
|
|
3521
|
+
announcementSent = false;
|
|
3522
|
+
notify('loadingAnnouncement', false);
|
|
3523
|
+
}
|
|
3524
|
+
} else if (skeletonCount > 0) {
|
|
3525
|
+
// Opening while already loading — start the announcement timer
|
|
3526
|
+
startLoadingAnnouncementTimer();
|
|
3487
3527
|
}
|
|
3488
3528
|
|
|
3489
3529
|
// Update aria-expanded on trigger
|
|
3490
3530
|
trigger?.setAttribute('aria-expanded', String(isOpen));
|
|
3491
3531
|
notify('open', isOpen);
|
|
3532
|
+
|
|
3533
|
+
// When opening, always notify the current empty state so that
|
|
3534
|
+
// subscribers (ComboboxState) get the correct initial value.
|
|
3535
|
+
// Without this, a list that starts empty never fires `emptyChange`
|
|
3536
|
+
// because `lastIsEmpty` is initialized to `true` and `notifyVisibilityChange`
|
|
3537
|
+
// only fires on *changes*.
|
|
3538
|
+
if (isOpen) {
|
|
3539
|
+
const inputValue = trigger?.value ?? '';
|
|
3540
|
+
notify('emptyChange', {
|
|
3541
|
+
isEmpty: lastIsEmpty,
|
|
3542
|
+
inputValue
|
|
3543
|
+
});
|
|
3544
|
+
}
|
|
3492
3545
|
},
|
|
3493
3546
|
select(option) {
|
|
3494
3547
|
callbacks.onSelect({
|
|
3495
3548
|
value: option ? getOptionValue(option) : ''
|
|
3496
|
-
});
|
|
3549
|
+
}, handle);
|
|
3497
3550
|
},
|
|
3498
3551
|
registerOption(element, callback) {
|
|
3499
3552
|
const filterLower = filterValue.toLowerCase();
|
|
@@ -3605,10 +3658,12 @@ function setupCombobox(callbacks, options, onTriggerAttach) {
|
|
|
3605
3658
|
listbox = null;
|
|
3606
3659
|
filterValue = '';
|
|
3607
3660
|
lastIsEmpty = true;
|
|
3661
|
+
lastInputValue = '';
|
|
3608
3662
|
optionRegistrations.clear();
|
|
3609
3663
|
sectionRegistrations.clear();
|
|
3610
3664
|
skeletonCount = 0;
|
|
3611
3665
|
clearTimeout(loadingTimer);
|
|
3666
|
+
announcementSent = false;
|
|
3612
3667
|
// Clear all subscribers
|
|
3613
3668
|
for (const set of Object.values(subscribers)) {
|
|
3614
3669
|
set.clear();
|
|
@@ -3775,13 +3830,8 @@ function setupComboboxButton(button, callbacks) {
|
|
|
3775
3830
|
case ' ':
|
|
3776
3831
|
// Space acts like Enter in button mode.
|
|
3777
3832
|
if (combobox.isOpen && nav?.hasActiveItem && nav.activeItem) {
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
nav.activeItem.click();
|
|
3781
|
-
} else {
|
|
3782
|
-
combobox.select(nav.activeItem);
|
|
3783
|
-
combobox.setIsOpen(false);
|
|
3784
|
-
}
|
|
3833
|
+
// Click the active item — delegated handler handles select + close.
|
|
3834
|
+
nav.activeItem.click();
|
|
3785
3835
|
} else {
|
|
3786
3836
|
combobox.setIsOpen(true);
|
|
3787
3837
|
}
|
|
@@ -6563,44 +6613,58 @@ const ComboboxButton = Object.assign(forwardRefPolymorphic((props, ref) => {
|
|
|
6563
6613
|
* Handles: Home/End (text cursor), ArrowLeft/Right (clear active descendant),
|
|
6564
6614
|
* filtering (on input and on open), and focus behavior.
|
|
6565
6615
|
*
|
|
6566
|
-
* @param input
|
|
6567
|
-
* @param callbacks
|
|
6568
|
-
* @param options Options for configuring the input-mode controller.
|
|
6616
|
+
* @param input The input element to use as the combobox trigger.
|
|
6617
|
+
* @param options Options and callbacks for configuring the input-mode controller.
|
|
6569
6618
|
* @returns A ComboboxHandle for interacting with the combobox.
|
|
6570
6619
|
*/
|
|
6571
|
-
function setupComboboxInput(input,
|
|
6620
|
+
function setupComboboxInput(input, options) {
|
|
6572
6621
|
const {
|
|
6573
|
-
autoFilter = true
|
|
6622
|
+
autoFilter = true,
|
|
6623
|
+
onSelect: optionOnSelect
|
|
6574
6624
|
} = options;
|
|
6575
|
-
|
|
6625
|
+
|
|
6626
|
+
/**
|
|
6627
|
+
* True when the current input value came from user typing (real InputEvent).
|
|
6628
|
+
* False when the value was set programmatically (select, clear, etc.).
|
|
6629
|
+
* Used to decide whether to re-apply the filter when the combobox opens.
|
|
6630
|
+
*/
|
|
6631
|
+
let userHasTyped = false;
|
|
6632
|
+
|
|
6633
|
+
/**
|
|
6634
|
+
* Wraps the consumer's onSelect to perform input-mode side effects after selection:
|
|
6635
|
+
* clears the active descendant, resets the filter, and re-opens the popup.
|
|
6636
|
+
*/
|
|
6637
|
+
const onSelect = (option, combobox) => {
|
|
6638
|
+
optionOnSelect(option, combobox);
|
|
6639
|
+
|
|
6640
|
+
// Clear the active item. In multi-select, keep visual focus so the
|
|
6641
|
+
// user can continue navigating after selection.
|
|
6642
|
+
if (!combobox.isMultiSelect) {
|
|
6643
|
+
combobox.focusNav?.clear();
|
|
6644
|
+
}
|
|
6645
|
+
userHasTyped = false;
|
|
6646
|
+
combobox.setIsOpen(true);
|
|
6647
|
+
if (autoFilter) {
|
|
6648
|
+
combobox.setFilter('');
|
|
6649
|
+
}
|
|
6650
|
+
};
|
|
6651
|
+
const handle = setupCombobox({
|
|
6652
|
+
onSelect
|
|
6653
|
+
}, {
|
|
6576
6654
|
wrapNavigation: true
|
|
6577
6655
|
}, (combobox, signal) => {
|
|
6578
|
-
/**
|
|
6579
|
-
* True when the current input value came from user typing (real InputEvent).
|
|
6580
|
-
* False when the value was set programmatically (select, clear, etc.).
|
|
6581
|
-
* Used to decide whether to re-apply the filter when the combobox opens.
|
|
6582
|
-
*/
|
|
6583
|
-
let userHasTyped = false;
|
|
6584
6656
|
signal.addEventListener('abort', () => {
|
|
6585
6657
|
userHasTyped = false;
|
|
6586
6658
|
});
|
|
6587
6659
|
|
|
6588
|
-
// Filter on user typing
|
|
6589
|
-
// Real user input fires an `InputEvent` (with `inputType`), while
|
|
6590
|
-
// programmatic changes (selection bridge, clear, etc.) dispatch a
|
|
6591
|
-
// plain `Event('input')` — we use this to distinguish the two.
|
|
6660
|
+
// Filter on real user typing (InputEvent with `inputType`).
|
|
6592
6661
|
input.addEventListener('input', event => {
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
// visual focus so the user can continue navigating after selection.
|
|
6597
|
-
if (isUserTyping || !combobox.isMultiSelect) {
|
|
6598
|
-
combobox.focusNav?.clear();
|
|
6599
|
-
}
|
|
6600
|
-
userHasTyped = isUserTyping;
|
|
6662
|
+
if (!(event instanceof InputEvent)) return;
|
|
6663
|
+
combobox.focusNav?.clear();
|
|
6664
|
+
userHasTyped = true;
|
|
6601
6665
|
combobox.setIsOpen(true);
|
|
6602
6666
|
if (autoFilter) {
|
|
6603
|
-
combobox.setFilter(
|
|
6667
|
+
combobox.setFilter(input.value);
|
|
6604
6668
|
}
|
|
6605
6669
|
}, {
|
|
6606
6670
|
signal
|
|
@@ -6694,6 +6758,7 @@ const ComboboxInput$1 = (props, {
|
|
|
6694
6758
|
textFieldRef,
|
|
6695
6759
|
toggleButtonProps,
|
|
6696
6760
|
handleToggle,
|
|
6761
|
+
theme,
|
|
6697
6762
|
...forwardedProps
|
|
6698
6763
|
} = props;
|
|
6699
6764
|
return /*#__PURE__*/jsx(TextField, {
|
|
@@ -6706,8 +6771,10 @@ const ComboboxInput$1 = (props, {
|
|
|
6706
6771
|
inputRef: inputRef,
|
|
6707
6772
|
textFieldRef: textFieldRef,
|
|
6708
6773
|
autoComplete: "off",
|
|
6774
|
+
theme: theme,
|
|
6709
6775
|
afterElement: toggleButtonProps ? /*#__PURE__*/jsx(IconButton, {
|
|
6710
6776
|
...toggleButtonProps,
|
|
6777
|
+
theme: theme,
|
|
6711
6778
|
emphasis: "low",
|
|
6712
6779
|
size: "s",
|
|
6713
6780
|
icon: isOpen ? mdiChevronUp : mdiChevronDown,
|
|
@@ -7229,32 +7296,6 @@ TextField.displayName = COMPONENT_NAME$1d;
|
|
|
7229
7296
|
TextField.className = CLASSNAME$1c;
|
|
7230
7297
|
TextField.defaultProps = DEFAULT_PROPS$Z;
|
|
7231
7298
|
|
|
7232
|
-
/**
|
|
7233
|
-
* Set an input's value using the native HTMLInputElement.prototype.value setter,
|
|
7234
|
-
* bypassing React's controlled input value tracker, then dispatch an `input` event
|
|
7235
|
-
* so React's onChange fires.
|
|
7236
|
-
*
|
|
7237
|
-
* React wraps the `value` property setter on controlled inputs to track the "last
|
|
7238
|
-
* known value." If you set `input.value` through React's wrapper with the same value
|
|
7239
|
-
* React last rendered, the subsequent `input` event is suppressed. Using the native
|
|
7240
|
-
* setter bypasses this tracker, ensuring React detects a value change and fires onChange.
|
|
7241
|
-
*/
|
|
7242
|
-
function setNativeInputValue(input, value) {
|
|
7243
|
-
const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set;
|
|
7244
|
-
if (nativeSetter) {
|
|
7245
|
-
nativeSetter.call(input, value);
|
|
7246
|
-
} else {
|
|
7247
|
-
// Fallback: set directly (may not trigger React onChange on controlled inputs)
|
|
7248
|
-
// eslint-disable-next-line no-param-reassign
|
|
7249
|
-
input.value = value;
|
|
7250
|
-
}
|
|
7251
|
-
|
|
7252
|
-
// Dispatch input event so React's onChange fires
|
|
7253
|
-
input.dispatchEvent(new Event('input', {
|
|
7254
|
-
bubbles: true
|
|
7255
|
-
}));
|
|
7256
|
-
}
|
|
7257
|
-
|
|
7258
7299
|
/**
|
|
7259
7300
|
* Props for Combobox.Input component.
|
|
7260
7301
|
* Note: role, aria-autocomplete, aria-controls, aria-expanded are set internally and cannot be overridden.
|
|
@@ -7285,9 +7326,11 @@ const ComboboxInput = forwardRef((props, ref) => {
|
|
|
7285
7326
|
const internalInputRef = useRef(null);
|
|
7286
7327
|
const mergedInputRef = useMergeRefs(externalInputRef, internalInputRef);
|
|
7287
7328
|
|
|
7288
|
-
// Keep
|
|
7329
|
+
// Keep callbacks in refs to avoid re-creating the handle on every render
|
|
7289
7330
|
const onSelectRef = useRef(onSelect);
|
|
7290
7331
|
onSelectRef.current = onSelect;
|
|
7332
|
+
const onChangeRef = useRef(otherProps.onChange);
|
|
7333
|
+
onChangeRef.current = otherProps.onChange;
|
|
7291
7334
|
|
|
7292
7335
|
// Create the combobox handle with input-mode controller on mount
|
|
7293
7336
|
useEffect(() => {
|
|
@@ -7295,11 +7338,10 @@ const ComboboxInput = forwardRef((props, ref) => {
|
|
|
7295
7338
|
if (!input) return undefined;
|
|
7296
7339
|
const handle = setupComboboxInput(input, {
|
|
7297
7340
|
onSelect(option) {
|
|
7298
|
-
//
|
|
7299
|
-
|
|
7341
|
+
// Update controlled value through React's normal onChange flow.
|
|
7342
|
+
onChangeRef.current?.(option.value);
|
|
7300
7343
|
onSelectRef.current?.(option);
|
|
7301
|
-
}
|
|
7302
|
-
}, {
|
|
7344
|
+
},
|
|
7303
7345
|
autoFilter
|
|
7304
7346
|
});
|
|
7305
7347
|
setHandle(handle);
|
|
@@ -7737,6 +7779,7 @@ const ComboboxOption$1 = (props, {
|
|
|
7737
7779
|
isGrid,
|
|
7738
7780
|
isSelected,
|
|
7739
7781
|
handleClick,
|
|
7782
|
+
actionProps,
|
|
7740
7783
|
ref,
|
|
7741
7784
|
tooltipProps,
|
|
7742
7785
|
value,
|
|
@@ -7749,7 +7792,8 @@ const ComboboxOption$1 = (props, {
|
|
|
7749
7792
|
itemRole = isGrid ? 'row' : 'none';
|
|
7750
7793
|
}
|
|
7751
7794
|
const actionElement = ListItemAction$1({
|
|
7752
|
-
as: '
|
|
7795
|
+
as: 'button',
|
|
7796
|
+
...actionProps,
|
|
7753
7797
|
id,
|
|
7754
7798
|
className: element$H('trigger'),
|
|
7755
7799
|
handleClick,
|
|
@@ -7832,6 +7876,7 @@ const ComboboxOption = forwardRef((props, ref) => {
|
|
|
7832
7876
|
before,
|
|
7833
7877
|
after,
|
|
7834
7878
|
tooltipProps,
|
|
7879
|
+
actionProps,
|
|
7835
7880
|
onClick,
|
|
7836
7881
|
...forwardedProps
|
|
7837
7882
|
} = props;
|
|
@@ -7865,6 +7910,7 @@ const ComboboxOption = forwardRef((props, ref) => {
|
|
|
7865
7910
|
return ComboboxOption$1({
|
|
7866
7911
|
...forwardedProps,
|
|
7867
7912
|
ref: mergedRef,
|
|
7913
|
+
actionProps,
|
|
7868
7914
|
hidden: isFiltered,
|
|
7869
7915
|
value,
|
|
7870
7916
|
description,
|
|
@@ -8011,14 +8057,16 @@ const ComboboxOptionMoreInfo$1 = (props, {
|
|
|
8011
8057
|
popoverId,
|
|
8012
8058
|
ref,
|
|
8013
8059
|
onMouseEnter,
|
|
8014
|
-
onMouseLeave
|
|
8060
|
+
onMouseLeave,
|
|
8061
|
+
buttonProps
|
|
8015
8062
|
} = props;
|
|
8016
8063
|
return /*#__PURE__*/jsxs(Fragment, {
|
|
8017
8064
|
children: [/*#__PURE__*/jsx(IconButton, {
|
|
8018
8065
|
ref: ref,
|
|
8019
|
-
className: block$R([className]),
|
|
8020
8066
|
icon: mdiInformationOutline,
|
|
8021
8067
|
size: "s",
|
|
8068
|
+
...buttonProps,
|
|
8069
|
+
className: block$R([className, buttonProps?.className]),
|
|
8022
8070
|
emphasis: "low",
|
|
8023
8071
|
onMouseEnter: onMouseEnter,
|
|
8024
8072
|
onMouseLeave: onMouseLeave
|
|
@@ -8036,6 +8084,7 @@ const ComboboxOptionMoreInfo$1 = (props, {
|
|
|
8036
8084
|
closeOnEscape: true,
|
|
8037
8085
|
closeOnClickAway: true,
|
|
8038
8086
|
placement: "bottom-end",
|
|
8087
|
+
hasArrow: true,
|
|
8039
8088
|
children: children
|
|
8040
8089
|
})]
|
|
8041
8090
|
});
|
|
@@ -8720,6 +8769,7 @@ const ComboboxOptionMoreInfo = props => {
|
|
|
8720
8769
|
const {
|
|
8721
8770
|
children,
|
|
8722
8771
|
onToggle,
|
|
8772
|
+
buttonProps,
|
|
8723
8773
|
...forwardedProps
|
|
8724
8774
|
} = props;
|
|
8725
8775
|
const ref = useRef(null);
|
|
@@ -8750,6 +8800,7 @@ const ComboboxOptionMoreInfo = props => {
|
|
|
8750
8800
|
isOpen,
|
|
8751
8801
|
popoverId,
|
|
8752
8802
|
children,
|
|
8803
|
+
buttonProps,
|
|
8753
8804
|
onMouseEnter: () => setIsHovered(true),
|
|
8754
8805
|
onMouseLeave: () => setIsHovered(false)
|
|
8755
8806
|
}, {
|
|
@@ -8835,9 +8886,10 @@ const ComboboxOptionSkeleton$1 = props => {
|
|
|
8835
8886
|
children,
|
|
8836
8887
|
className,
|
|
8837
8888
|
ref,
|
|
8889
|
+
count = 1,
|
|
8838
8890
|
...forwardedProps
|
|
8839
8891
|
} = props;
|
|
8840
|
-
|
|
8892
|
+
const itemProps = {
|
|
8841
8893
|
ref,
|
|
8842
8894
|
size: 'tiny',
|
|
8843
8895
|
role: 'none',
|
|
@@ -8852,6 +8904,13 @@ const ComboboxOptionSkeleton$1 = props => {
|
|
|
8852
8904
|
theme: "light"
|
|
8853
8905
|
})]
|
|
8854
8906
|
})
|
|
8907
|
+
};
|
|
8908
|
+
return /*#__PURE__*/jsx(Fragment, {
|
|
8909
|
+
children: Array.from({
|
|
8910
|
+
length: count
|
|
8911
|
+
}, (_, i) => /*#__PURE__*/jsx(ListItem$1, {
|
|
8912
|
+
...itemProps
|
|
8913
|
+
}, i))
|
|
8855
8914
|
});
|
|
8856
8915
|
};
|
|
8857
8916
|
|
|
@@ -8880,19 +8939,13 @@ const ComboboxOptionSkeleton$1 = props => {
|
|
|
8880
8939
|
* @return React element(s).
|
|
8881
8940
|
*/
|
|
8882
8941
|
const ComboboxOptionSkeleton = props => {
|
|
8883
|
-
const {
|
|
8884
|
-
count = 1,
|
|
8885
|
-
...itemProps
|
|
8886
|
-
} = props;
|
|
8887
8942
|
const {
|
|
8888
8943
|
handle
|
|
8889
8944
|
} = useComboboxContext();
|
|
8890
8945
|
useEffect(() => handle?.registerSkeleton(), [handle]);
|
|
8891
|
-
return
|
|
8892
|
-
|
|
8893
|
-
}
|
|
8894
|
-
...itemProps
|
|
8895
|
-
}, i));
|
|
8946
|
+
return /*#__PURE__*/jsx(ComboboxOptionSkeleton$1, {
|
|
8947
|
+
...props
|
|
8948
|
+
});
|
|
8896
8949
|
};
|
|
8897
8950
|
ComboboxOptionSkeleton.displayName = COMPONENT_NAME$12;
|
|
8898
8951
|
ComboboxOptionSkeleton.className = CLASSNAME$11;
|
|
@@ -9443,11 +9496,12 @@ const ListSection$1 = props => {
|
|
|
9443
9496
|
...forwardedProps
|
|
9444
9497
|
} = props;
|
|
9445
9498
|
const labelId = `${id}-label`;
|
|
9499
|
+
const hasHeader = !!label;
|
|
9446
9500
|
return /*#__PURE__*/jsxs("li", {
|
|
9447
9501
|
ref: ref,
|
|
9448
9502
|
...forwardedProps,
|
|
9449
9503
|
className: classnames(className, block$O()),
|
|
9450
|
-
children: [
|
|
9504
|
+
children: [hasHeader && /*#__PURE__*/jsxs(Text, {
|
|
9451
9505
|
as: "p",
|
|
9452
9506
|
typography: "overline",
|
|
9453
9507
|
className: element$D('title'),
|
|
@@ -9458,7 +9512,7 @@ const ListSection$1 = props => {
|
|
|
9458
9512
|
}), /*#__PURE__*/jsx("ul", {
|
|
9459
9513
|
...itemsWrapperProps,
|
|
9460
9514
|
className: element$D('items'),
|
|
9461
|
-
"aria-labelledby":
|
|
9515
|
+
"aria-labelledby": hasHeader ? labelId : undefined,
|
|
9462
9516
|
children: children
|
|
9463
9517
|
})]
|
|
9464
9518
|
});
|
|
@@ -9619,6 +9673,7 @@ const ComboboxState$1 = (props, {
|
|
|
9619
9673
|
loadingMessage,
|
|
9620
9674
|
state
|
|
9621
9675
|
} = props;
|
|
9676
|
+
const isOpen = state?.isOpen ?? true;
|
|
9622
9677
|
const showError = !!errorMessage;
|
|
9623
9678
|
const resolvedEmptyMessage = typeof emptyMessage === 'function' ? emptyMessage(state?.inputValue || '') : emptyMessage;
|
|
9624
9679
|
// Suppress empty while loading (immediate flag prevents false "no results" before data arrives)
|
|
@@ -9632,6 +9687,12 @@ const ComboboxState$1 = (props, {
|
|
|
9632
9687
|
hAlign: 'center',
|
|
9633
9688
|
vAlign: 'center'
|
|
9634
9689
|
};
|
|
9690
|
+
|
|
9691
|
+
// Gate message content behind isOpen so that content is *inserted* into the
|
|
9692
|
+
// aria-live region when the popover opens, triggering screen reader announcements.
|
|
9693
|
+
// Without this gate, content is already present (just hidden via display:none from
|
|
9694
|
+
// the popover's closeMode="hide") and revealing it doesn't trigger announcements.
|
|
9695
|
+
const renderContent = isOpen;
|
|
9635
9696
|
return /*#__PURE__*/jsxs(GenericBlock, {
|
|
9636
9697
|
className: classnames(!show && visuallyHidden(), block$N(), padding('regular')),
|
|
9637
9698
|
orientation: "vertical",
|
|
@@ -9639,17 +9700,17 @@ const ComboboxState$1 = (props, {
|
|
|
9639
9700
|
role: "status",
|
|
9640
9701
|
"aria-live": "polite",
|
|
9641
9702
|
"aria-atomic": true,
|
|
9642
|
-
children: [showEmpty && /*#__PURE__*/jsx(Text, {
|
|
9703
|
+
children: [renderContent && showEmpty && /*#__PURE__*/jsx(Text, {
|
|
9643
9704
|
as: "p",
|
|
9644
9705
|
typography: "body1",
|
|
9645
9706
|
color: "dark-L2",
|
|
9646
9707
|
children: resolvedEmptyMessage
|
|
9647
|
-
}), showLoading && /*#__PURE__*/jsx(Text, {
|
|
9708
|
+
}), renderContent && showLoading && /*#__PURE__*/jsx(Text, {
|
|
9648
9709
|
as: "p",
|
|
9649
9710
|
typography: "body1",
|
|
9650
9711
|
color: "dark-L2",
|
|
9651
9712
|
children: loadingMessage
|
|
9652
|
-
}), !!errorMessage && /*#__PURE__*/jsxs(Fragment, {
|
|
9713
|
+
}), renderContent && !!errorMessage && /*#__PURE__*/jsxs(Fragment, {
|
|
9653
9714
|
children: [/*#__PURE__*/jsx(Text, {
|
|
9654
9715
|
as: "p",
|
|
9655
9716
|
typography: "subtitle2",
|
|
@@ -9664,6 +9725,62 @@ const ComboboxState$1 = (props, {
|
|
|
9664
9725
|
});
|
|
9665
9726
|
};
|
|
9666
9727
|
|
|
9728
|
+
/**
|
|
9729
|
+
* Delay before inserting content into the aria-live region after the popover opens (ms).
|
|
9730
|
+
*
|
|
9731
|
+
* The popover uses `closeMode="hide"` (`display:none` when closed), so the live region
|
|
9732
|
+
* container is not in the accessibility tree until the popover becomes visible.
|
|
9733
|
+
* Screen readers only detect content *changes* in live regions that are already visible.
|
|
9734
|
+
* This delay ensures the popover's `display:none` is removed and the accessibility tree
|
|
9735
|
+
* is updated before content is inserted, so screen readers reliably announce it.
|
|
9736
|
+
*/
|
|
9737
|
+
const OPEN_ANNOUNCEMENT_DELAY = 100;
|
|
9738
|
+
|
|
9739
|
+
/** Setters invoked by `subscribeComboboxState` when handle events fire. */
|
|
9740
|
+
|
|
9741
|
+
/**
|
|
9742
|
+
* Subscribe to the combobox handle events needed by `ComboboxState`.
|
|
9743
|
+
*
|
|
9744
|
+
* Manages three subscriptions:
|
|
9745
|
+
* - `loadingChange` → `setIsLoading` (+ synchronous initial read of `handle.isLoading`)
|
|
9746
|
+
* - `loadingAnnouncement` → `setShouldAnnounce`
|
|
9747
|
+
* - `open` → `setIsOpen` (deferred by {@link OPEN_ANNOUNCEMENT_DELAY}ms on open, immediate on close)
|
|
9748
|
+
*
|
|
9749
|
+
* @param handle The combobox handle to subscribe to.
|
|
9750
|
+
* @param setters Framework-specific state setters.
|
|
9751
|
+
* @returns A cleanup function that unsubscribes all events and clears timers.
|
|
9752
|
+
*/
|
|
9753
|
+
function subscribeComboboxState(handle, setters) {
|
|
9754
|
+
const {
|
|
9755
|
+
setIsLoading,
|
|
9756
|
+
setShouldAnnounce,
|
|
9757
|
+
setIsOpen
|
|
9758
|
+
} = setters;
|
|
9759
|
+
|
|
9760
|
+
// Read current loading state synchronously
|
|
9761
|
+
setIsLoading(handle.isLoading);
|
|
9762
|
+
const unsubLoadingChange = handle.subscribe('loadingChange', setIsLoading);
|
|
9763
|
+
const unsubLoadingAnnouncement = handle.subscribe('loadingAnnouncement', setShouldAnnounce);
|
|
9764
|
+
let openTimer;
|
|
9765
|
+
const unsubOpen = handle.subscribe('open', open => {
|
|
9766
|
+
clearTimeout(openTimer);
|
|
9767
|
+
if (open) {
|
|
9768
|
+
// Delay content insertion so the popover is visible in the
|
|
9769
|
+
// accessibility tree before the live region content changes.
|
|
9770
|
+
openTimer = setTimeout(() => setIsOpen(true), OPEN_ANNOUNCEMENT_DELAY);
|
|
9771
|
+
} else {
|
|
9772
|
+
// Reset immediately on close
|
|
9773
|
+
setIsOpen(false);
|
|
9774
|
+
}
|
|
9775
|
+
});
|
|
9776
|
+
return () => {
|
|
9777
|
+
unsubLoadingChange();
|
|
9778
|
+
unsubLoadingAnnouncement();
|
|
9779
|
+
unsubOpen();
|
|
9780
|
+
clearTimeout(openTimer);
|
|
9781
|
+
};
|
|
9782
|
+
}
|
|
9783
|
+
|
|
9667
9784
|
/**
|
|
9668
9785
|
* Similar to lodash `partition` function but working with multiple predicates.
|
|
9669
9786
|
*
|
|
@@ -9967,25 +10084,21 @@ const ComboboxState = props => {
|
|
|
9967
10084
|
handle
|
|
9968
10085
|
} = useComboboxContext();
|
|
9969
10086
|
const emptyState = useComboboxEvent('emptyChange', undefined);
|
|
9970
|
-
|
|
9971
|
-
// Track loading state with both initial read and event subscription
|
|
9972
|
-
// (same pattern as ComboboxList for aria-busy)
|
|
9973
10087
|
const [isLoading, setIsLoading] = useState(false);
|
|
9974
10088
|
const [shouldAnnounce, setShouldAnnounce] = useState(false);
|
|
10089
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
9975
10090
|
useEffect(() => {
|
|
9976
10091
|
if (!handle) return undefined;
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
unsub1();
|
|
9983
|
-
unsub2();
|
|
9984
|
-
};
|
|
10092
|
+
return subscribeComboboxState(handle, {
|
|
10093
|
+
setIsLoading,
|
|
10094
|
+
setShouldAnnounce,
|
|
10095
|
+
setIsOpen
|
|
10096
|
+
});
|
|
9985
10097
|
}, [handle]);
|
|
9986
10098
|
const state = {
|
|
9987
10099
|
...emptyState,
|
|
9988
|
-
isLoading
|
|
10100
|
+
isLoading,
|
|
10101
|
+
isOpen
|
|
9989
10102
|
};
|
|
9990
10103
|
|
|
9991
10104
|
// Only pass loadingMessage to core after the 500ms debounce threshold
|
|
@@ -10006,19 +10119,32 @@ ComboboxState.className = CLASSNAME$X;
|
|
|
10006
10119
|
* Combobox compound component namespace.
|
|
10007
10120
|
*/
|
|
10008
10121
|
const Combobox = {
|
|
10122
|
+
/** Provides shared combobox context (handle, listbox ID, anchor ref) to all sub-components. */
|
|
10009
10123
|
Provider: ComboboxProvider,
|
|
10124
|
+
/** Button trigger for select-only combobox mode with keyboard navigation and typeahead. */
|
|
10010
10125
|
Button: ComboboxButton,
|
|
10126
|
+
/** Text input trigger for autocomplete combobox mode with optional toggle button and filtering. */
|
|
10011
10127
|
Input: ComboboxInput,
|
|
10128
|
+
/** Listbox container that registers with the combobox handle and tracks loading state. */
|
|
10012
10129
|
List: ComboboxList,
|
|
10130
|
+
/** Selectable option item with filtering and keyboard navigation support. */
|
|
10013
10131
|
Option: ComboboxOption,
|
|
10132
|
+
/** Secondary action button within a grid-mode option row, rendered as an independent gridcell. */
|
|
10014
10133
|
OptionAction: ComboboxOptionAction,
|
|
10134
|
+
/** Info button on an option that shows a popover on hover or keyboard highlight. */
|
|
10015
10135
|
OptionMoreInfo: ComboboxOptionMoreInfo,
|
|
10136
|
+
/** Loading placeholder skeleton(s) that auto-register loading state with the combobox handle. */
|
|
10016
10137
|
OptionSkeleton: ComboboxOptionSkeleton,
|
|
10138
|
+
/** Floating popover container that auto-binds to the combobox anchor and open/close state. */
|
|
10017
10139
|
Popover: ComboboxPopover,
|
|
10140
|
+
/** Labelled group of options that auto-hides when all its child options are filtered out. */
|
|
10018
10141
|
Section: ComboboxSection,
|
|
10142
|
+
/** Displays empty, error, and loading state messages for the combobox list. */
|
|
10019
10143
|
State: ComboboxState,
|
|
10020
10144
|
/** Visual separator between option groups (alias for ListDivider). Purely decorative — invisible to screen readers. */
|
|
10021
|
-
Divider: ListDivider
|
|
10145
|
+
Divider: ListDivider,
|
|
10146
|
+
/** Hook to subscribe to combobox events. Must be used within a Combobox.Provider. */
|
|
10147
|
+
useComboboxEvent
|
|
10022
10148
|
};
|
|
10023
10149
|
|
|
10024
10150
|
/**
|
|
@@ -11523,7 +11649,7 @@ const CLASSNAME$P = 'lumx-expansion-panel';
|
|
|
11523
11649
|
const {
|
|
11524
11650
|
block: block$G,
|
|
11525
11651
|
element: element$x
|
|
11526
|
-
} =
|
|
11652
|
+
} = bem(CLASSNAME$P);
|
|
11527
11653
|
|
|
11528
11654
|
/**
|
|
11529
11655
|
* Component default props.
|
|
@@ -11531,9 +11657,6 @@ const {
|
|
|
11531
11657
|
const DEFAULT_PROPS$L = {
|
|
11532
11658
|
closeMode: 'unmount'
|
|
11533
11659
|
};
|
|
11534
|
-
const isDragHandle = isComponent(DragHandle);
|
|
11535
|
-
const isHeader = isComponent('header');
|
|
11536
|
-
const isFooter = isComponent('footer');
|
|
11537
11660
|
|
|
11538
11661
|
/**
|
|
11539
11662
|
* ExpansionPanel component.
|
|
@@ -11542,48 +11665,45 @@ const isFooter = isComponent('footer');
|
|
|
11542
11665
|
* @param ref Component ref.
|
|
11543
11666
|
* @return React element.
|
|
11544
11667
|
*/
|
|
11545
|
-
const ExpansionPanel =
|
|
11546
|
-
const defaultTheme = useTheme() || Theme$1.light;
|
|
11668
|
+
const ExpansionPanel$1 = props => {
|
|
11547
11669
|
const {
|
|
11548
11670
|
className,
|
|
11549
|
-
closeMode = DEFAULT_PROPS$L.closeMode,
|
|
11550
11671
|
children: anyChildren,
|
|
11551
11672
|
hasBackground,
|
|
11673
|
+
ref,
|
|
11552
11674
|
hasHeaderDivider,
|
|
11553
11675
|
isOpen,
|
|
11554
11676
|
label,
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
theme
|
|
11677
|
+
handleClose,
|
|
11678
|
+
handleOpen,
|
|
11679
|
+
handleToggleOpen,
|
|
11680
|
+
theme,
|
|
11559
11681
|
toggleButtonProps,
|
|
11682
|
+
headerProps,
|
|
11683
|
+
headerContent,
|
|
11684
|
+
dragHandle,
|
|
11685
|
+
wrapperRef,
|
|
11686
|
+
content,
|
|
11687
|
+
isChildrenVisible,
|
|
11688
|
+
IconButton,
|
|
11689
|
+
footer,
|
|
11690
|
+
closeMode,
|
|
11560
11691
|
...forwardedProps
|
|
11561
11692
|
} = props;
|
|
11562
|
-
const children = Children.toArray(anyChildren);
|
|
11563
|
-
|
|
11564
|
-
// Partition children by types.
|
|
11565
|
-
const [[dragHandle], [header], [footer], content] = partitionMulti(children, [isDragHandle, isHeader, isFooter]);
|
|
11566
|
-
|
|
11567
|
-
// Either take the header in children or create one with the label.
|
|
11568
|
-
const headerProps = /*#__PURE__*/React__default.isValidElement(header) ? header.props : {};
|
|
11569
|
-
const headerContent = !isEmpty(headerProps.children) ? headerProps.children : /*#__PURE__*/jsx("span", {
|
|
11570
|
-
className: element$x('label'),
|
|
11571
|
-
children: label
|
|
11572
|
-
});
|
|
11573
11693
|
const toggleOpen = event => {
|
|
11574
11694
|
const shouldOpen = !isOpen;
|
|
11575
|
-
if (
|
|
11576
|
-
|
|
11695
|
+
if (handleOpen && shouldOpen) {
|
|
11696
|
+
handleOpen(event);
|
|
11577
11697
|
}
|
|
11578
|
-
if (
|
|
11579
|
-
|
|
11698
|
+
if (handleClose && !shouldOpen) {
|
|
11699
|
+
handleClose(event);
|
|
11580
11700
|
}
|
|
11581
|
-
if (
|
|
11582
|
-
|
|
11701
|
+
if (handleToggleOpen) {
|
|
11702
|
+
handleToggleOpen(shouldOpen, event);
|
|
11583
11703
|
}
|
|
11584
11704
|
};
|
|
11585
|
-
const color = theme === Theme
|
|
11586
|
-
const rootClassName =
|
|
11705
|
+
const color = theme === Theme.dark ? ColorPalette.light : ColorPalette.dark;
|
|
11706
|
+
const rootClassName = classnames(className, block$G({
|
|
11587
11707
|
'has-background': hasBackground,
|
|
11588
11708
|
'has-header': Boolean(!isEmpty(headerProps.children)),
|
|
11589
11709
|
'has-header-divider': hasHeaderDivider,
|
|
@@ -11592,35 +11712,6 @@ const ExpansionPanel = forwardRef((props, ref) => {
|
|
|
11592
11712
|
'is-open': isOpen,
|
|
11593
11713
|
[`theme-${theme}`]: Boolean(theme)
|
|
11594
11714
|
}));
|
|
11595
|
-
const wrapperRef = useRef(null);
|
|
11596
|
-
|
|
11597
|
-
// Children stay visible while the open/close transition is running
|
|
11598
|
-
const [isChildrenVisible, setChildrenVisible] = React__default.useState(isOpen);
|
|
11599
|
-
const isOpenRef = React__default.useRef(isOpen);
|
|
11600
|
-
React__default.useEffect(() => {
|
|
11601
|
-
if (isOpen || closeMode === 'hide') {
|
|
11602
|
-
setChildrenVisible(true);
|
|
11603
|
-
} else if (!IS_BROWSER$1) {
|
|
11604
|
-
// Outside a browser we can't wait for the transition
|
|
11605
|
-
setChildrenVisible(false);
|
|
11606
|
-
}
|
|
11607
|
-
isOpenRef.current = isOpen;
|
|
11608
|
-
}, [closeMode, isOpen]);
|
|
11609
|
-
|
|
11610
|
-
// Change children's visibility on the transition end
|
|
11611
|
-
React__default.useEffect(() => {
|
|
11612
|
-
const {
|
|
11613
|
-
current: wrapper
|
|
11614
|
-
} = wrapperRef;
|
|
11615
|
-
if (!IS_BROWSER$1 || !wrapper) {
|
|
11616
|
-
return undefined;
|
|
11617
|
-
}
|
|
11618
|
-
const onTransitionEnd = () => {
|
|
11619
|
-
setChildrenVisible(isOpenRef.current || closeMode === 'hide');
|
|
11620
|
-
};
|
|
11621
|
-
wrapper.addEventListener('transitionend', onTransitionEnd);
|
|
11622
|
-
return () => wrapper.removeEventListener('transitionend', onTransitionEnd);
|
|
11623
|
-
}, [closeMode]);
|
|
11624
11715
|
return /*#__PURE__*/jsxs("section", {
|
|
11625
11716
|
ref: ref,
|
|
11626
11717
|
...forwardedProps,
|
|
@@ -11640,7 +11731,7 @@ const ExpansionPanel = forwardRef((props, ref) => {
|
|
|
11640
11731
|
children: /*#__PURE__*/jsx(IconButton, {
|
|
11641
11732
|
...toggleButtonProps,
|
|
11642
11733
|
color: color,
|
|
11643
|
-
emphasis: Emphasis
|
|
11734
|
+
emphasis: Emphasis.low,
|
|
11644
11735
|
icon: isOpen ? mdiChevronUp : mdiChevronDown,
|
|
11645
11736
|
"aria-expanded": isOpen || 'false'
|
|
11646
11737
|
})
|
|
@@ -11660,6 +11751,92 @@ const ExpansionPanel = forwardRef((props, ref) => {
|
|
|
11660
11751
|
})
|
|
11661
11752
|
})]
|
|
11662
11753
|
});
|
|
11754
|
+
};
|
|
11755
|
+
|
|
11756
|
+
const isDragHandle = isComponent(DragHandle);
|
|
11757
|
+
const isHeader = isComponent('header');
|
|
11758
|
+
const isFooter = isComponent('footer');
|
|
11759
|
+
|
|
11760
|
+
/**
|
|
11761
|
+
* ExpansionPanel component.
|
|
11762
|
+
*
|
|
11763
|
+
* @param props Component props.
|
|
11764
|
+
* @param ref Component ref.
|
|
11765
|
+
* @return React element.
|
|
11766
|
+
*/
|
|
11767
|
+
const ExpansionPanel = forwardRef((props, ref) => {
|
|
11768
|
+
const defaultTheme = useTheme() || Theme$1.light;
|
|
11769
|
+
const {
|
|
11770
|
+
closeMode = DEFAULT_PROPS$L.closeMode,
|
|
11771
|
+
children: anyChildren,
|
|
11772
|
+
isOpen,
|
|
11773
|
+
label,
|
|
11774
|
+
onClose,
|
|
11775
|
+
onOpen,
|
|
11776
|
+
onToggleOpen,
|
|
11777
|
+
theme = defaultTheme,
|
|
11778
|
+
...forwardedProps
|
|
11779
|
+
} = props;
|
|
11780
|
+
const children = Children.toArray(anyChildren);
|
|
11781
|
+
|
|
11782
|
+
// Partition children by types.
|
|
11783
|
+
const [[dragHandle], [header], [footer], content] = partitionMulti(children, [isDragHandle, isHeader, isFooter]);
|
|
11784
|
+
|
|
11785
|
+
// Either take the header in children or create one with the label.
|
|
11786
|
+
const headerProps = /*#__PURE__*/React__default.isValidElement(header) ? header.props : {};
|
|
11787
|
+
const headerContent = !isEmpty(headerProps.children) ? headerProps.children : /*#__PURE__*/jsx("span", {
|
|
11788
|
+
className: element$x('label'),
|
|
11789
|
+
children: label
|
|
11790
|
+
});
|
|
11791
|
+
const wrapperRef = useRef(null);
|
|
11792
|
+
|
|
11793
|
+
// Children stay visible while the open/close transition is running
|
|
11794
|
+
const [isChildrenVisible, setChildrenVisible] = React__default.useState(isOpen);
|
|
11795
|
+
const isOpenRef = React__default.useRef(isOpen);
|
|
11796
|
+
React__default.useEffect(() => {
|
|
11797
|
+
if (isOpen || closeMode === 'hide') {
|
|
11798
|
+
setChildrenVisible(true);
|
|
11799
|
+
} else if (!IS_BROWSER$1) {
|
|
11800
|
+
// Outside a browser we can't wait for the transition
|
|
11801
|
+
setChildrenVisible(false);
|
|
11802
|
+
}
|
|
11803
|
+
isOpenRef.current = isOpen;
|
|
11804
|
+
}, [closeMode, isOpen]);
|
|
11805
|
+
|
|
11806
|
+
// Change children's visibility on the transition end
|
|
11807
|
+
React__default.useEffect(() => {
|
|
11808
|
+
const {
|
|
11809
|
+
current: wrapper
|
|
11810
|
+
} = wrapperRef;
|
|
11811
|
+
if (!IS_BROWSER$1 || !wrapper) {
|
|
11812
|
+
return undefined;
|
|
11813
|
+
}
|
|
11814
|
+
const onTransitionEnd = () => {
|
|
11815
|
+
setChildrenVisible(isOpenRef.current || closeMode === 'hide');
|
|
11816
|
+
};
|
|
11817
|
+
wrapper.addEventListener('transitionend', onTransitionEnd);
|
|
11818
|
+
return () => wrapper.removeEventListener('transitionend', onTransitionEnd);
|
|
11819
|
+
}, [closeMode]);
|
|
11820
|
+
return ExpansionPanel$1({
|
|
11821
|
+
content,
|
|
11822
|
+
dragHandle,
|
|
11823
|
+
footer,
|
|
11824
|
+
headerContent,
|
|
11825
|
+
ref,
|
|
11826
|
+
headerProps,
|
|
11827
|
+
wrapperRef,
|
|
11828
|
+
IconButton,
|
|
11829
|
+
isOpen,
|
|
11830
|
+
handleClose: onClose,
|
|
11831
|
+
handleToggleOpen: onToggleOpen,
|
|
11832
|
+
handleOpen: onOpen,
|
|
11833
|
+
theme,
|
|
11834
|
+
isChildrenVisible,
|
|
11835
|
+
children,
|
|
11836
|
+
closeMode,
|
|
11837
|
+
label,
|
|
11838
|
+
...forwardedProps
|
|
11839
|
+
});
|
|
11663
11840
|
});
|
|
11664
11841
|
ExpansionPanel.displayName = COMPONENT_NAME$O;
|
|
11665
11842
|
ExpansionPanel.className = CLASSNAME$P;
|
|
@@ -12237,7 +12414,7 @@ const {
|
|
|
12237
12414
|
*/
|
|
12238
12415
|
const DEFAULT_PROPS$F = {
|
|
12239
12416
|
captionPosition: ImageBlockCaptionPosition.below,
|
|
12240
|
-
align: Alignment.left
|
|
12417
|
+
align: Alignment$1.left
|
|
12241
12418
|
};
|
|
12242
12419
|
|
|
12243
12420
|
/**
|
|
@@ -13651,7 +13828,7 @@ const CLASSNAME$B = 'lumx-mosaic';
|
|
|
13651
13828
|
const {
|
|
13652
13829
|
block: block$v,
|
|
13653
13830
|
element: element$n
|
|
13654
|
-
} =
|
|
13831
|
+
} = bem(CLASSNAME$B);
|
|
13655
13832
|
|
|
13656
13833
|
/**
|
|
13657
13834
|
* Component default props.
|
|
@@ -13665,26 +13842,27 @@ const DEFAULT_PROPS$C = {};
|
|
|
13665
13842
|
* @param ref Component ref.
|
|
13666
13843
|
* @return React element.
|
|
13667
13844
|
*/
|
|
13668
|
-
const Mosaic =
|
|
13669
|
-
const defaultTheme = useTheme() || Theme$1.light;
|
|
13845
|
+
const Mosaic$1 = props => {
|
|
13670
13846
|
const {
|
|
13671
13847
|
className,
|
|
13672
|
-
theme
|
|
13848
|
+
theme,
|
|
13673
13849
|
thumbnails,
|
|
13674
|
-
|
|
13850
|
+
handleClick,
|
|
13851
|
+
Thumbnail,
|
|
13852
|
+
ref,
|
|
13675
13853
|
...forwardedProps
|
|
13676
13854
|
} = props;
|
|
13677
|
-
const
|
|
13678
|
-
if (!
|
|
13855
|
+
const onImageClick = () => {
|
|
13856
|
+
if (!handleClick) return undefined;
|
|
13679
13857
|
return (index, onClick) => event => {
|
|
13680
13858
|
onClick?.(event);
|
|
13681
|
-
|
|
13859
|
+
handleClick?.(index);
|
|
13682
13860
|
};
|
|
13683
|
-
}
|
|
13861
|
+
};
|
|
13684
13862
|
return /*#__PURE__*/jsx("div", {
|
|
13685
13863
|
ref: ref,
|
|
13686
13864
|
...forwardedProps,
|
|
13687
|
-
className:
|
|
13865
|
+
className: classnames(className, block$v({
|
|
13688
13866
|
[`theme-${theme}`]: Boolean(theme),
|
|
13689
13867
|
'has-1-thumbnail': thumbnails?.length === 1,
|
|
13690
13868
|
'has-2-thumbnails': thumbnails?.length === 2,
|
|
@@ -13707,9 +13885,9 @@ const Mosaic = forwardRef((props, ref) => {
|
|
|
13707
13885
|
align: align || Alignment.left,
|
|
13708
13886
|
image: image,
|
|
13709
13887
|
theme: theme,
|
|
13710
|
-
aspectRatio: AspectRatio
|
|
13888
|
+
aspectRatio: AspectRatio.free,
|
|
13711
13889
|
fillHeight: true,
|
|
13712
|
-
onClick:
|
|
13890
|
+
onClick: onImageClick()?.(index, onClick) || onClick
|
|
13713
13891
|
}), thumbnails.length > 4 && index === 3 && /*#__PURE__*/jsx("div", {
|
|
13714
13892
|
className: element$n('overlay'),
|
|
13715
13893
|
children: /*#__PURE__*/jsxs("span", {
|
|
@@ -13720,6 +13898,33 @@ const Mosaic = forwardRef((props, ref) => {
|
|
|
13720
13898
|
})
|
|
13721
13899
|
})
|
|
13722
13900
|
});
|
|
13901
|
+
};
|
|
13902
|
+
|
|
13903
|
+
/**
|
|
13904
|
+
* Defines the props of the component.
|
|
13905
|
+
*/
|
|
13906
|
+
|
|
13907
|
+
/**
|
|
13908
|
+
* Mosaic component.
|
|
13909
|
+
*
|
|
13910
|
+
* @param props Component props.
|
|
13911
|
+
* @param ref Component ref.
|
|
13912
|
+
* @return React element.
|
|
13913
|
+
*/
|
|
13914
|
+
const Mosaic = forwardRef((props, ref) => {
|
|
13915
|
+
const defaultTheme = useTheme() || Theme$1.light;
|
|
13916
|
+
const {
|
|
13917
|
+
theme = defaultTheme,
|
|
13918
|
+
onImageClick,
|
|
13919
|
+
...forwardedProps
|
|
13920
|
+
} = props;
|
|
13921
|
+
return Mosaic$1({
|
|
13922
|
+
ref,
|
|
13923
|
+
theme,
|
|
13924
|
+
Thumbnail,
|
|
13925
|
+
handleClick: onImageClick,
|
|
13926
|
+
...forwardedProps
|
|
13927
|
+
});
|
|
13723
13928
|
});
|
|
13724
13929
|
Mosaic.displayName = COMPONENT_NAME$A;
|
|
13725
13930
|
Mosaic.className = CLASSNAME$B;
|
|
@@ -14519,7 +14724,6 @@ const reducer = (state, action) => {
|
|
|
14519
14724
|
if (state.activeTabIndex === action.payload) {
|
|
14520
14725
|
return state;
|
|
14521
14726
|
}
|
|
14522
|
-
// Change active tab index.
|
|
14523
14727
|
return {
|
|
14524
14728
|
...state,
|
|
14525
14729
|
activeTabIndex: action.payload
|
|
@@ -14531,7 +14735,6 @@ const reducer = (state, action) => {
|
|
|
14531
14735
|
type,
|
|
14532
14736
|
id
|
|
14533
14737
|
} = action.payload;
|
|
14534
|
-
// Append tab/tabPanel id in state.
|
|
14535
14738
|
return {
|
|
14536
14739
|
...state,
|
|
14537
14740
|
ids: {
|
|
@@ -14548,7 +14751,6 @@ const reducer = (state, action) => {
|
|
|
14548
14751
|
} = action.payload;
|
|
14549
14752
|
const index = state.ids[type].indexOf(id);
|
|
14550
14753
|
if (index === -1) return state;
|
|
14551
|
-
// Remove tab & tab panel at index.
|
|
14552
14754
|
const tabIds = [...state.ids.tab];
|
|
14553
14755
|
tabIds.splice(index, 1);
|
|
14554
14756
|
const tabPanelIds = [...state.ids.tabPanel];
|
|
@@ -14565,7 +14767,9 @@ const reducer = (state, action) => {
|
|
|
14565
14767
|
return state;
|
|
14566
14768
|
}
|
|
14567
14769
|
};
|
|
14770
|
+
|
|
14568
14771
|
const TabProviderContext = /*#__PURE__*/createContext(null);
|
|
14772
|
+
|
|
14569
14773
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
14570
14774
|
const useTabProviderContext = (type, originalId) => {
|
|
14571
14775
|
const context = useContext(TabProviderContext);
|
|
@@ -17378,7 +17582,7 @@ const Switch$1 = props => {
|
|
|
17378
17582
|
* Component default props.
|
|
17379
17583
|
*/
|
|
17380
17584
|
const DEFAULT_PROPS$c = {
|
|
17381
|
-
position: Alignment.left
|
|
17585
|
+
position: Alignment$1.left
|
|
17382
17586
|
};
|
|
17383
17587
|
|
|
17384
17588
|
/**
|
|
@@ -17937,7 +18141,7 @@ const TABS_CLASSNAME = `lumx-tabs`;
|
|
|
17937
18141
|
const {
|
|
17938
18142
|
block: block$6,
|
|
17939
18143
|
element: element$4
|
|
17940
|
-
} =
|
|
18144
|
+
} = bem(TABS_CLASSNAME);
|
|
17941
18145
|
let TabListLayout = /*#__PURE__*/function (TabListLayout) {
|
|
17942
18146
|
TabListLayout["clustered"] = "clustered";
|
|
17943
18147
|
TabListLayout["fixed"] = "fixed";
|
|
@@ -17970,26 +18174,21 @@ const DEFAULT_PROPS$6 = {
|
|
|
17970
18174
|
* @param ref Component ref.
|
|
17971
18175
|
* @return React element.
|
|
17972
18176
|
*/
|
|
17973
|
-
const TabList =
|
|
17974
|
-
const defaultTheme = useTheme() || Theme$1.light;
|
|
18177
|
+
const TabList$1 = props => {
|
|
17975
18178
|
const {
|
|
17976
18179
|
'aria-label': ariaLabel,
|
|
17977
18180
|
children,
|
|
17978
18181
|
className,
|
|
17979
18182
|
layout = DEFAULT_PROPS$6.layout,
|
|
17980
18183
|
position = DEFAULT_PROPS$6.position,
|
|
17981
|
-
theme
|
|
18184
|
+
theme,
|
|
18185
|
+
ref,
|
|
17982
18186
|
...forwardedProps
|
|
17983
18187
|
} = props;
|
|
17984
|
-
const tabListRef = React__default.useRef(null);
|
|
17985
|
-
useRovingTabIndexContainer({
|
|
17986
|
-
containerRef: tabListRef,
|
|
17987
|
-
itemSelector: '[role="tab"]'
|
|
17988
|
-
});
|
|
17989
18188
|
return /*#__PURE__*/jsx("div", {
|
|
17990
|
-
ref:
|
|
18189
|
+
ref: ref,
|
|
17991
18190
|
...forwardedProps,
|
|
17992
|
-
className:
|
|
18191
|
+
className: classnames(className, block$6({
|
|
17993
18192
|
[`layout-${layout}`]: Boolean(layout),
|
|
17994
18193
|
[`position-${position}`]: Boolean(position),
|
|
17995
18194
|
[`theme-${theme}`]: Boolean(theme)
|
|
@@ -18001,6 +18200,33 @@ const TabList = forwardRef((props, ref) => {
|
|
|
18001
18200
|
children: children
|
|
18002
18201
|
})
|
|
18003
18202
|
});
|
|
18203
|
+
};
|
|
18204
|
+
|
|
18205
|
+
/**
|
|
18206
|
+
* TabList component.
|
|
18207
|
+
*
|
|
18208
|
+
* Implements WAI-ARIA `tablist` role {@see https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-1/tabs.html#rps_label}
|
|
18209
|
+
*
|
|
18210
|
+
* @param props Component props.
|
|
18211
|
+
* @param ref Component ref.
|
|
18212
|
+
* @return React element.
|
|
18213
|
+
*/
|
|
18214
|
+
const TabList = forwardRef((props, ref) => {
|
|
18215
|
+
const defaultTheme = useTheme() || Theme$1.light;
|
|
18216
|
+
const {
|
|
18217
|
+
theme = defaultTheme,
|
|
18218
|
+
...forwardedProps
|
|
18219
|
+
} = props;
|
|
18220
|
+
const tabListRef = React__default.useRef(null);
|
|
18221
|
+
useRovingTabIndexContainer({
|
|
18222
|
+
containerRef: tabListRef,
|
|
18223
|
+
itemSelector: '[role="tab"]'
|
|
18224
|
+
});
|
|
18225
|
+
return TabList$1({
|
|
18226
|
+
theme,
|
|
18227
|
+
ref: mergeRefs(ref, tabListRef),
|
|
18228
|
+
...forwardedProps
|
|
18229
|
+
});
|
|
18004
18230
|
});
|
|
18005
18231
|
TabList.displayName = COMPONENT_NAME$5;
|
|
18006
18232
|
TabList.className = TABS_CLASSNAME;
|
|
@@ -18039,12 +18265,15 @@ const Tab$1 = props => {
|
|
|
18039
18265
|
icon,
|
|
18040
18266
|
iconProps = {},
|
|
18041
18267
|
isAnyDisabled,
|
|
18268
|
+
isDisabled,
|
|
18042
18269
|
id,
|
|
18043
18270
|
isActive,
|
|
18044
18271
|
label,
|
|
18045
18272
|
handleFocus,
|
|
18046
18273
|
handleKeyPress,
|
|
18047
18274
|
tabIndex = -1,
|
|
18275
|
+
tabIndexProp = 'tabIndex',
|
|
18276
|
+
keyPressProp = 'onKeyPress',
|
|
18048
18277
|
changeToTab,
|
|
18049
18278
|
tabPanelId,
|
|
18050
18279
|
shouldActivateOnFocus,
|
|
@@ -18083,10 +18312,10 @@ const Tab$1 = props => {
|
|
|
18083
18312
|
'is-disabled': isAnyDisabled
|
|
18084
18313
|
})),
|
|
18085
18314
|
onClick: changeToCurrentTab,
|
|
18086
|
-
|
|
18315
|
+
[keyPressProp]: onKeyPress,
|
|
18087
18316
|
onFocus: onFocus,
|
|
18088
18317
|
role: "tab",
|
|
18089
|
-
|
|
18318
|
+
[tabIndexProp]: isActive ? 0 : tabIndex,
|
|
18090
18319
|
"aria-disabled": isAnyDisabled,
|
|
18091
18320
|
"aria-selected": isActive,
|
|
18092
18321
|
"aria-controls": tabPanelId,
|
|
@@ -18157,7 +18386,7 @@ const COMPONENT_NAME$3 = 'TabPanel';
|
|
|
18157
18386
|
const CLASSNAME$4 = `lumx-tab-panel`;
|
|
18158
18387
|
const {
|
|
18159
18388
|
block: block$4
|
|
18160
|
-
} =
|
|
18389
|
+
} = bem(CLASSNAME$4);
|
|
18161
18390
|
|
|
18162
18391
|
/**
|
|
18163
18392
|
* Component default props.
|
|
@@ -18173,27 +18402,60 @@ const DEFAULT_PROPS$4 = {};
|
|
|
18173
18402
|
* @param ref Component ref.
|
|
18174
18403
|
* @return React element.
|
|
18175
18404
|
*/
|
|
18176
|
-
const TabPanel =
|
|
18405
|
+
const TabPanel$1 = props => {
|
|
18177
18406
|
const {
|
|
18178
18407
|
children,
|
|
18179
|
-
id,
|
|
18180
18408
|
className,
|
|
18181
|
-
isActive
|
|
18409
|
+
isActive,
|
|
18410
|
+
id,
|
|
18411
|
+
tabId,
|
|
18412
|
+
isLazy,
|
|
18413
|
+
tabIndexProp = 'tabIndex',
|
|
18414
|
+
ref,
|
|
18182
18415
|
...forwardedProps
|
|
18183
18416
|
} = props;
|
|
18184
|
-
const state = useTabProviderContext('tabPanel', id);
|
|
18185
|
-
const isActive = propIsActive || state?.isActive;
|
|
18186
18417
|
return /*#__PURE__*/jsx("div", {
|
|
18187
18418
|
ref: ref,
|
|
18188
18419
|
...forwardedProps,
|
|
18189
|
-
id:
|
|
18190
|
-
className:
|
|
18420
|
+
id: id,
|
|
18421
|
+
className: classnames(className, block$4({
|
|
18191
18422
|
'is-active': isActive
|
|
18192
18423
|
})),
|
|
18193
18424
|
role: "tabpanel",
|
|
18194
|
-
|
|
18195
|
-
"aria-labelledby":
|
|
18196
|
-
children: (!
|
|
18425
|
+
[tabIndexProp]: isActive ? 0 : -1,
|
|
18426
|
+
"aria-labelledby": tabId,
|
|
18427
|
+
children: (!isLazy || isActive) && children
|
|
18428
|
+
});
|
|
18429
|
+
};
|
|
18430
|
+
|
|
18431
|
+
/**
|
|
18432
|
+
* Defines the props of the component.
|
|
18433
|
+
*/
|
|
18434
|
+
|
|
18435
|
+
/**
|
|
18436
|
+
* TabPanel component.
|
|
18437
|
+
*
|
|
18438
|
+
* Implements WAI-ARIA `tabpanel` role {@see https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-1/tabs.html#rps_label}
|
|
18439
|
+
*
|
|
18440
|
+
* @param props Component props.
|
|
18441
|
+
* @param ref Component ref.
|
|
18442
|
+
* @return React element.
|
|
18443
|
+
*/
|
|
18444
|
+
const TabPanel = forwardRef((props, ref) => {
|
|
18445
|
+
const {
|
|
18446
|
+
id,
|
|
18447
|
+
isActive: propIsActive,
|
|
18448
|
+
...forwardedProps
|
|
18449
|
+
} = props;
|
|
18450
|
+
const state = useTabProviderContext('tabPanel', id);
|
|
18451
|
+
const isActive = propIsActive || state?.isActive;
|
|
18452
|
+
return TabPanel$1({
|
|
18453
|
+
ref,
|
|
18454
|
+
isActive,
|
|
18455
|
+
id: state?.tabPanelId,
|
|
18456
|
+
isLazy: state?.isLazy,
|
|
18457
|
+
tabId: state?.tabId,
|
|
18458
|
+
...forwardedProps
|
|
18197
18459
|
});
|
|
18198
18460
|
});
|
|
18199
18461
|
TabPanel.displayName = COMPONENT_NAME$3;
|