@capra/core 1.11.1 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +523 -130
- package/dist/index.d.cts +147 -21
- package/dist/index.d.mts +147 -21
- package/dist/index.mjs +527 -135
- package/dist/style.css +550 -236
- package/docs/core-autocompletefield--usage.md +1 -1
- package/docs/core-menu--usage.md +1 -1
- package/docs/core-selectfield--design.md +66 -0
- package/docs/core-selectfield--usage.md +145 -0
- package/docs/core-tabnav--design.md +2 -0
- package/docs/core-tabnav--usage.md +21 -3
- package/docs/history-changelogs-capra-core--docs.md +26 -0
- package/docs/index.md +2 -0
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -346,11 +346,50 @@ HelperText.displayName = "HelperText";
|
|
|
346
346
|
//#endregion
|
|
347
347
|
//#region src/components/input-helpers/fieldLayout.module.css
|
|
348
348
|
var fieldLayout_module_default = {
|
|
349
|
-
"field": "capra-fieldLayout-module-
|
|
350
|
-
"fieldContent": "capra-fieldLayout-module-
|
|
351
|
-
"labelRow": "capra-fieldLayout-module-
|
|
349
|
+
"field": "capra-fieldLayout-module-0mM4jW-field",
|
|
350
|
+
"fieldContent": "capra-fieldLayout-module-0mM4jW-fieldContent",
|
|
351
|
+
"labelRow": "capra-fieldLayout-module-0mM4jW-labelRow"
|
|
352
352
|
};
|
|
353
353
|
//#endregion
|
|
354
|
+
//#region src/components/input-helpers/useAnchorWidth.ts
|
|
355
|
+
/**
|
|
356
|
+
* Element that visually bounds the field (select trigger or text input shell). The popover matches
|
|
357
|
+
* its width and left edge, which differs from the field root in horizontal layouts where the label
|
|
358
|
+
* sits beside the control.
|
|
359
|
+
*/
|
|
360
|
+
function getShellElement(anchor) {
|
|
361
|
+
return anchor.querySelector("[data-capra-anchor-width-target]") ?? anchor.querySelector("[data-capra-text-input]") ?? anchor;
|
|
362
|
+
}
|
|
363
|
+
/** Element React Aria anchors the popover to: the select trigger or the combobox input. */
|
|
364
|
+
function getTriggerElement(anchor) {
|
|
365
|
+
return anchor.querySelector("[data-capra-anchor-width-target]") ?? anchor.querySelector("input") ?? anchor;
|
|
366
|
+
}
|
|
367
|
+
function useAnchorWidth(additionalDependencies = []) {
|
|
368
|
+
const anchorRef = react.useRef(null);
|
|
369
|
+
const [width, setWidth] = react.useState(null);
|
|
370
|
+
const [offset, setOffset] = react.useState(0);
|
|
371
|
+
react.useEffect(() => {
|
|
372
|
+
const anchor = anchorRef.current;
|
|
373
|
+
if (!anchor) return;
|
|
374
|
+
const measure = () => {
|
|
375
|
+
const shell = getShellElement(anchor);
|
|
376
|
+
const trigger = getTriggerElement(anchor);
|
|
377
|
+
setWidth(shell.offsetWidth + "px");
|
|
378
|
+
setOffset(shell.getBoundingClientRect().left - trigger.getBoundingClientRect().left);
|
|
379
|
+
};
|
|
380
|
+
const observer = new ResizeObserver(measure);
|
|
381
|
+
observer.observe(anchor);
|
|
382
|
+
const shell = getShellElement(anchor);
|
|
383
|
+
if (shell !== anchor) observer.observe(shell);
|
|
384
|
+
return () => observer.disconnect();
|
|
385
|
+
}, additionalDependencies);
|
|
386
|
+
return [
|
|
387
|
+
anchorRef,
|
|
388
|
+
width,
|
|
389
|
+
offset
|
|
390
|
+
];
|
|
391
|
+
}
|
|
392
|
+
//#endregion
|
|
354
393
|
//#region src/components/Autocomplete/AutocompleteField.module.css
|
|
355
394
|
var AutocompleteField_module_default = {
|
|
356
395
|
"item": "capra-AutocompleteField-module-MVvKYa-item",
|
|
@@ -409,41 +448,6 @@ function AutocompleteFieldWithoutRef(props, ref) {
|
|
|
409
448
|
style: { width: shouldAutoSizeDropdown ? width : void 0 }
|
|
410
449
|
}, /* @__PURE__ */ react.default.createElement(react_aria_components.ListBox, { className: AutocompleteField_module_default.listbox }, children)));
|
|
411
450
|
}
|
|
412
|
-
function useResizeObserver({ ref, onResize, additionalDependencies = [] }) {
|
|
413
|
-
react.default.useEffect(() => {
|
|
414
|
-
if (!ref.current) return;
|
|
415
|
-
const observer = new ResizeObserver((entries) => {
|
|
416
|
-
onResize(entries[0]);
|
|
417
|
-
});
|
|
418
|
-
observer.observe(ref.current);
|
|
419
|
-
return () => observer.disconnect();
|
|
420
|
-
}, [
|
|
421
|
-
ref,
|
|
422
|
-
onResize,
|
|
423
|
-
...additionalDependencies
|
|
424
|
-
]);
|
|
425
|
-
}
|
|
426
|
-
function useAnchorWidth(additionalDependencies = []) {
|
|
427
|
-
const anchorRef = react.default.useRef(null);
|
|
428
|
-
const [width, setWidth] = (0, react.useState)(null);
|
|
429
|
-
const [offset, setOffset] = (0, react.useState)(0);
|
|
430
|
-
useResizeObserver({
|
|
431
|
-
ref: anchorRef,
|
|
432
|
-
onResize: (0, react.useCallback)(() => {
|
|
433
|
-
if (anchorRef.current) {
|
|
434
|
-
setWidth(anchorRef.current.offsetWidth + "px");
|
|
435
|
-
const input = anchorRef.current.querySelector("input");
|
|
436
|
-
if (input) setOffset(anchorRef.current.offsetLeft - input.offsetLeft);
|
|
437
|
-
}
|
|
438
|
-
}, [anchorRef]),
|
|
439
|
-
additionalDependencies
|
|
440
|
-
});
|
|
441
|
-
return [
|
|
442
|
-
anchorRef,
|
|
443
|
-
width,
|
|
444
|
-
offset
|
|
445
|
-
];
|
|
446
|
-
}
|
|
447
451
|
/**
|
|
448
452
|
* AutocompleteField combines a text field with a suggestions list. Consumers can supply static `AutocompleteField.Item` children or an `items` collection with an optional default item renderer. The field allows custom values that are not in the list.
|
|
449
453
|
*/
|
|
@@ -834,7 +838,7 @@ function RadioTileWithoutRef({ children, checked, disabled, description, icon, F
|
|
|
834
838
|
const RadioTile = fixedForwardRef(RadioTileWithoutRef);
|
|
835
839
|
//#endregion
|
|
836
840
|
//#region src/components/Switch/Switch.module.css
|
|
837
|
-
var Switch_module_default = { "switch": "capra-Switch-module-
|
|
841
|
+
var Switch_module_default = { "switch": "capra-Switch-module-j8Yc-q-switch" };
|
|
838
842
|
//#endregion
|
|
839
843
|
//#region src/components/Switch/Switch.tsx
|
|
840
844
|
const Switch = react.forwardRef((props, ref) => {
|
|
@@ -2313,6 +2317,430 @@ const DatePickerFieldWithRef = react.forwardRef(DatePickerFieldInner);
|
|
|
2313
2317
|
DatePickerFieldWithRef.displayName = "DatePickerField";
|
|
2314
2318
|
const DatePickerField = DatePickerFieldWithRef;
|
|
2315
2319
|
//#endregion
|
|
2320
|
+
//#region src/components/SelectField/SelectField.module.css
|
|
2321
|
+
var SelectField_module_default = {
|
|
2322
|
+
"chevron": "capra-SelectField-module-1X4diq-chevron",
|
|
2323
|
+
"dropdownPanel": "capra-SelectField-module-1X4diq-dropdownPanel",
|
|
2324
|
+
"emptyState": "capra-SelectField-module-1X4diq-emptyState",
|
|
2325
|
+
"errorIndicator": "capra-SelectField-module-1X4diq-errorIndicator",
|
|
2326
|
+
"header": "capra-SelectField-module-1X4diq-header",
|
|
2327
|
+
"item": "capra-SelectField-module-1X4diq-item",
|
|
2328
|
+
"itemCheck": "capra-SelectField-module-1X4diq-itemCheck",
|
|
2329
|
+
"itemContent": "capra-SelectField-module-1X4diq-itemContent",
|
|
2330
|
+
"leadingSlot": "capra-SelectField-module-1X4diq-leadingSlot",
|
|
2331
|
+
"listbox": "capra-SelectField-module-1X4diq-listbox",
|
|
2332
|
+
"multipleOpenButton": "capra-SelectField-module-1X4diq-multipleOpenButton",
|
|
2333
|
+
"multipleTrigger": "capra-SelectField-module-1X4diq-multipleTrigger",
|
|
2334
|
+
"search": "capra-SelectField-module-1X4diq-search",
|
|
2335
|
+
"section": "capra-SelectField-module-1X4diq-section",
|
|
2336
|
+
"singleTrigger": "capra-SelectField-module-1X4diq-singleTrigger",
|
|
2337
|
+
"tag": "capra-SelectField-module-1X4diq-tag",
|
|
2338
|
+
"tagGroup": "capra-SelectField-module-1X4diq-tagGroup",
|
|
2339
|
+
"tagIcon": "capra-SelectField-module-1X4diq-tagIcon",
|
|
2340
|
+
"tagLabel": "capra-SelectField-module-1X4diq-tagLabel",
|
|
2341
|
+
"tagList": "capra-SelectField-module-1X4diq-tagList",
|
|
2342
|
+
"tagRemove": "capra-SelectField-module-1X4diq-tagRemove",
|
|
2343
|
+
"trailingSlot": "capra-SelectField-module-1X4diq-trailingSlot",
|
|
2344
|
+
"triggerShell": "capra-SelectField-module-1X4diq-triggerShell",
|
|
2345
|
+
"value": "capra-SelectField-module-1X4diq-value",
|
|
2346
|
+
"valueIcon": "capra-SelectField-module-1X4diq-valueIcon",
|
|
2347
|
+
"valueText": "capra-SelectField-module-1X4diq-valueText",
|
|
2348
|
+
"warningIndicator": "capra-SelectField-module-1X4diq-warningIndicator"
|
|
2349
|
+
};
|
|
2350
|
+
//#endregion
|
|
2351
|
+
//#region src/components/SelectField/SelectField.tsx
|
|
2352
|
+
/** When true, SelectField.Item indents by default (inside SelectField.Section that contains SelectField.Header). */
|
|
2353
|
+
const SelectFieldSectionIndentContext = react.createContext(false);
|
|
2354
|
+
function normalizeIterable(value) {
|
|
2355
|
+
return value === void 0 ? void 0 : Array.from(value);
|
|
2356
|
+
}
|
|
2357
|
+
function getItemLabelFromNode(node) {
|
|
2358
|
+
if (typeof node === "string") return node;
|
|
2359
|
+
if (typeof node === "number") return String(node);
|
|
2360
|
+
if (react.isValidElement(node)) {
|
|
2361
|
+
if (typeof node.props.textValue === "string") return node.props.textValue;
|
|
2362
|
+
return getItemLabelFromNode(node.props.children);
|
|
2363
|
+
}
|
|
2364
|
+
return "";
|
|
2365
|
+
}
|
|
2366
|
+
function removeKeysFromSelection(selection, keys) {
|
|
2367
|
+
return (selection ?? []).filter((selectedKey) => !keys.has(selectedKey));
|
|
2368
|
+
}
|
|
2369
|
+
function getItemIcon(item) {
|
|
2370
|
+
if (item && typeof item === "object" && "icon" in item) {
|
|
2371
|
+
const icon = item.icon;
|
|
2372
|
+
return icon && typeof icon === "object" && "__brand" in icon ? icon : void 0;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
function isDefaultSection(item) {
|
|
2376
|
+
const children = item.children;
|
|
2377
|
+
return children != null && typeof children !== "string" && typeof children[Symbol.iterator] === "function";
|
|
2378
|
+
}
|
|
2379
|
+
function SelectFieldIndicators(props) {
|
|
2380
|
+
const { appearance } = props;
|
|
2381
|
+
return /* @__PURE__ */ react.createElement(react.Fragment, null, appearance === "warning" ? /* @__PURE__ */ react.createElement("span", {
|
|
2382
|
+
className: SelectField_module_default.warningIndicator,
|
|
2383
|
+
"aria-hidden": true
|
|
2384
|
+
}, /* @__PURE__ */ react.createElement(_capra_icons.WarningOutlined, { size: "sm" })) : null, appearance === "danger" ? /* @__PURE__ */ react.createElement("span", {
|
|
2385
|
+
className: SelectField_module_default.errorIndicator,
|
|
2386
|
+
"aria-hidden": true
|
|
2387
|
+
}, /* @__PURE__ */ react.createElement(_capra_icons.Exclamation, { size: "sm" })) : null, /* @__PURE__ */ react.createElement("span", {
|
|
2388
|
+
className: SelectField_module_default.chevron,
|
|
2389
|
+
"aria-hidden": true
|
|
2390
|
+
}, /* @__PURE__ */ react.createElement(_capra_icons.ChevronDown, { size: "sm" })));
|
|
2391
|
+
}
|
|
2392
|
+
function SelectFieldTriggerButton(props) {
|
|
2393
|
+
const { appearance, buttonRef, children, className, ...rest } = props;
|
|
2394
|
+
const localRef = react.useRef(null);
|
|
2395
|
+
const ref = buttonRef ?? localRef;
|
|
2396
|
+
const [mergedProps, mergedRef] = (0, react_aria_components.useContextProps)({
|
|
2397
|
+
...rest,
|
|
2398
|
+
className
|
|
2399
|
+
}, ref, react_aria_components.ButtonContext);
|
|
2400
|
+
const { buttonProps, isPressed } = (0, react_aria.useButton)(mergedProps, mergedRef);
|
|
2401
|
+
const { focusProps, isFocused, isFocusVisible } = (0, react_aria.useFocusRing)(mergedProps);
|
|
2402
|
+
return /* @__PURE__ */ react.createElement("button", {
|
|
2403
|
+
...(0, react_aria.mergeProps)(buttonProps, focusProps),
|
|
2404
|
+
ref: mergedRef,
|
|
2405
|
+
className,
|
|
2406
|
+
"aria-invalid": appearance === "danger" ? true : void 0,
|
|
2407
|
+
"data-pressed": isPressed || void 0,
|
|
2408
|
+
"data-focused": isFocused || void 0,
|
|
2409
|
+
"data-focus-visible": isFocusVisible || void 0,
|
|
2410
|
+
"data-disabled": mergedProps.isDisabled || void 0
|
|
2411
|
+
}, children);
|
|
2412
|
+
}
|
|
2413
|
+
function SelectFieldTrigger(props) {
|
|
2414
|
+
const { appearance, disabled, leadingSlot, placeholder, required, selectedItemsLabel, size, triggerRef } = props;
|
|
2415
|
+
const state = react.useContext(react_aria_components.SelectStateContext);
|
|
2416
|
+
const openButtonRef = react.useRef(null);
|
|
2417
|
+
if (!state) return null;
|
|
2418
|
+
if (!(state.selectionManager.selectionMode === "multiple")) return /* @__PURE__ */ react.createElement(SelectFieldTriggerButton, {
|
|
2419
|
+
appearance,
|
|
2420
|
+
className: clsx(SelectField_module_default.triggerShell, SelectField_module_default.singleTrigger),
|
|
2421
|
+
"data-capra-anchor-width-target": "",
|
|
2422
|
+
"data-size": size,
|
|
2423
|
+
"data-disabled": disabled || void 0,
|
|
2424
|
+
"aria-required": required || void 0,
|
|
2425
|
+
isDisabled: disabled
|
|
2426
|
+
}, leadingSlot ? /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.leadingSlot }, leadingSlot) : null, /* @__PURE__ */ react.createElement(react_aria_components.SelectValue, { className: SelectField_module_default.value }, ({ isPlaceholder, selectedText, selectedItems }) => {
|
|
2427
|
+
const ValueIcon = getItemIcon(selectedItems[0]);
|
|
2428
|
+
return /* @__PURE__ */ react.createElement(react.Fragment, null, ValueIcon ? /* @__PURE__ */ react.createElement("span", {
|
|
2429
|
+
className: SelectField_module_default.valueIcon,
|
|
2430
|
+
"aria-hidden": true
|
|
2431
|
+
}, /* @__PURE__ */ react.createElement(ValueIcon, { size: "sm" })) : null, /* @__PURE__ */ react.createElement("span", {
|
|
2432
|
+
className: SelectField_module_default.valueText,
|
|
2433
|
+
"data-placeholder": isPlaceholder || !selectedText || void 0
|
|
2434
|
+
}, selectedText || placeholder));
|
|
2435
|
+
}), /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.trailingSlot }, /* @__PURE__ */ react.createElement(SelectFieldIndicators, { appearance })));
|
|
2436
|
+
const hasSelection = !state.selectionManager.isEmpty;
|
|
2437
|
+
const handleEmptyTriggerPress = (event) => {
|
|
2438
|
+
if (disabled || hasSelection || state.isOpen) return;
|
|
2439
|
+
if (event.target.closest("button")) return;
|
|
2440
|
+
openButtonRef.current?.focus();
|
|
2441
|
+
state.open();
|
|
2442
|
+
};
|
|
2443
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.Group, {
|
|
2444
|
+
ref: triggerRef,
|
|
2445
|
+
className: clsx(SelectField_module_default.triggerShell, SelectField_module_default.multipleTrigger),
|
|
2446
|
+
"data-capra-anchor-width-target": "",
|
|
2447
|
+
"data-size": size,
|
|
2448
|
+
"data-disabled": disabled || void 0,
|
|
2449
|
+
"data-empty": hasSelection ? void 0 : "",
|
|
2450
|
+
onClick: handleEmptyTriggerPress
|
|
2451
|
+
}, leadingSlot ? /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.leadingSlot }, leadingSlot) : null, /* @__PURE__ */ react.createElement(react_aria_components.ButtonContext.Provider, { value: null }, /* @__PURE__ */ react.createElement(react_aria_components.SelectValue, { className: SelectField_module_default.value }, ({ state: selectState }) => {
|
|
2452
|
+
const tagItems = selectState.selectedItems.filter((item) => item != null).map((item) => ({
|
|
2453
|
+
id: item.key,
|
|
2454
|
+
label: item.textValue || getItemLabelFromNode(item.rendered) || String(item.key),
|
|
2455
|
+
icon: getItemIcon(item.value)
|
|
2456
|
+
}));
|
|
2457
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.TagGroup, {
|
|
2458
|
+
"aria-label": selectedItemsLabel,
|
|
2459
|
+
className: SelectField_module_default.tagGroup,
|
|
2460
|
+
onRemove: disabled ? void 0 : (keys) => {
|
|
2461
|
+
const value = selectState.value;
|
|
2462
|
+
if (Array.isArray(value)) selectState.setValue(removeKeysFromSelection(value, keys));
|
|
2463
|
+
}
|
|
2464
|
+
}, /* @__PURE__ */ react.createElement(react_aria_components.TagList, {
|
|
2465
|
+
className: SelectField_module_default.tagList,
|
|
2466
|
+
items: tagItems,
|
|
2467
|
+
renderEmptyState: () => /* @__PURE__ */ react.createElement("span", {
|
|
2468
|
+
className: SelectField_module_default.valueText,
|
|
2469
|
+
"data-placeholder": placeholder ? true : void 0
|
|
2470
|
+
}, placeholder)
|
|
2471
|
+
}, (item) => /* @__PURE__ */ react.createElement(react_aria_components.Tag, {
|
|
2472
|
+
id: item.id,
|
|
2473
|
+
textValue: item.label,
|
|
2474
|
+
className: SelectField_module_default.tag,
|
|
2475
|
+
"data-size": size === "sm" ? "sm" : "md"
|
|
2476
|
+
}, ({ allowsRemoving }) => /* @__PURE__ */ react.createElement(react.Fragment, null, item.icon ? /* @__PURE__ */ react.createElement("span", {
|
|
2477
|
+
className: SelectField_module_default.tagIcon,
|
|
2478
|
+
"aria-hidden": true
|
|
2479
|
+
}, /* @__PURE__ */ react.createElement(item.icon, { size: "xs" })) : null, /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.tagLabel }, item.label), allowsRemoving ? /* @__PURE__ */ react.createElement(react_aria_components.Button, {
|
|
2480
|
+
slot: "remove",
|
|
2481
|
+
className: SelectField_module_default.tagRemove,
|
|
2482
|
+
"aria-label": "Delete",
|
|
2483
|
+
excludeFromTabOrder: true
|
|
2484
|
+
}, /* @__PURE__ */ react.createElement(_capra_icons.CloseOutlined, { size: "xs" })) : null))));
|
|
2485
|
+
})), /* @__PURE__ */ react.createElement(SelectFieldTriggerButton, {
|
|
2486
|
+
appearance,
|
|
2487
|
+
buttonRef: openButtonRef,
|
|
2488
|
+
className: SelectField_module_default.multipleOpenButton,
|
|
2489
|
+
isDisabled: disabled,
|
|
2490
|
+
"aria-required": required || void 0
|
|
2491
|
+
}, /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.trailingSlot }, /* @__PURE__ */ react.createElement(SelectFieldIndicators, { appearance }))));
|
|
2492
|
+
}
|
|
2493
|
+
function SelectFieldItem(props) {
|
|
2494
|
+
const { id, textValue, isDisabled, indent: indentProp, value, children } = props;
|
|
2495
|
+
const indentFromSectionHeader = react.useContext(SelectFieldSectionIndentContext);
|
|
2496
|
+
const indent = indentProp !== void 0 ? indentProp : indentFromSectionHeader;
|
|
2497
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.ListBoxItem, {
|
|
2498
|
+
id,
|
|
2499
|
+
value,
|
|
2500
|
+
textValue: textValue || getItemLabelFromNode(children),
|
|
2501
|
+
isDisabled,
|
|
2502
|
+
className: SelectField_module_default.item,
|
|
2503
|
+
"data-indent": indent || void 0
|
|
2504
|
+
}, ({ isSelected, selectionMode }) => /* @__PURE__ */ react.createElement("div", { className: SelectField_module_default.itemContent }, selectionMode === "multiple" ? /* @__PURE__ */ react.createElement("span", {
|
|
2505
|
+
className: SelectField_module_default.itemCheck,
|
|
2506
|
+
"data-selected": isSelected || void 0,
|
|
2507
|
+
"aria-hidden": true
|
|
2508
|
+
}, isSelected ? /* @__PURE__ */ react.createElement(_capra_icons.CheckOutlined, { size: "sm" }) : null) : null, typeof children === "string" ? /* @__PURE__ */ react.createElement(Text, { slot: "label" }, children) : children));
|
|
2509
|
+
}
|
|
2510
|
+
function SelectFieldHeader(props) {
|
|
2511
|
+
const { id, label = "Header", FORCE__className: classNameOverride, children } = props;
|
|
2512
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.Header, {
|
|
2513
|
+
id,
|
|
2514
|
+
className: clsx(SelectField_module_default.header, classNameOverride)
|
|
2515
|
+
}, children ?? label);
|
|
2516
|
+
}
|
|
2517
|
+
SelectFieldHeader.displayName = "SelectField.Header";
|
|
2518
|
+
function isSelectFieldHeaderElement(child) {
|
|
2519
|
+
return react.isValidElement(child) && child.type === SelectFieldHeader;
|
|
2520
|
+
}
|
|
2521
|
+
function SelectFieldSection(props) {
|
|
2522
|
+
const { children, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, FORCE__className: classNameOverride, className, ...rest } = props;
|
|
2523
|
+
const autoHeaderId = react.useId();
|
|
2524
|
+
const childArray = react.Children.toArray(children);
|
|
2525
|
+
let headerIndex = -1;
|
|
2526
|
+
for (let i = 0; i < childArray.length; i++) if (isSelectFieldHeaderElement(childArray[i])) {
|
|
2527
|
+
headerIndex = i;
|
|
2528
|
+
break;
|
|
2529
|
+
}
|
|
2530
|
+
const hasHeader = headerIndex >= 0;
|
|
2531
|
+
if (process.env.NODE_ENV !== "production") {
|
|
2532
|
+
if (!hasHeader && !ariaLabel?.trim() && !ariaLabelledBy?.trim()) console.error("SelectField.Section: provide aria-label or aria-labelledby when the section has no direct SelectField.Header child.");
|
|
2533
|
+
}
|
|
2534
|
+
const labelledBy = hasHeader ? ariaLabelledBy ?? autoHeaderId : ariaLabelledBy;
|
|
2535
|
+
const effectiveAriaLabel = hasHeader ? void 0 : ariaLabel;
|
|
2536
|
+
const resolvedChildren = hasHeader && headerIndex >= 0 ? childArray.map((child, i) => {
|
|
2537
|
+
if (i === headerIndex && isSelectFieldHeaderElement(child)) return react.cloneElement(child, { id: child.props.id ?? autoHeaderId });
|
|
2538
|
+
return child;
|
|
2539
|
+
}) : children;
|
|
2540
|
+
return /* @__PURE__ */ react.createElement(SelectFieldSectionIndentContext.Provider, { value: hasHeader }, /* @__PURE__ */ react.createElement(react_aria_components.ListBoxSection, {
|
|
2541
|
+
"aria-label": effectiveAriaLabel,
|
|
2542
|
+
"aria-labelledby": labelledBy,
|
|
2543
|
+
className: clsx(SelectField_module_default.section, className, classNameOverride),
|
|
2544
|
+
...rest
|
|
2545
|
+
}, resolvedChildren));
|
|
2546
|
+
}
|
|
2547
|
+
SelectFieldSection.displayName = "SelectField.Section";
|
|
2548
|
+
function defaultSelectFieldItemRenderer(item) {
|
|
2549
|
+
if (isDefaultSection(item)) {
|
|
2550
|
+
const { id, label, "aria-label": ariaLabel, children } = item;
|
|
2551
|
+
return /* @__PURE__ */ react.createElement(SelectFieldSection, {
|
|
2552
|
+
key: String(id),
|
|
2553
|
+
"aria-label": label ? void 0 : ariaLabel
|
|
2554
|
+
}, label ? /* @__PURE__ */ react.createElement(SelectFieldHeader, { label }) : null, /* @__PURE__ */ react.createElement(react_aria_components.Collection, { items: children }, (child) => defaultSelectFieldItemRenderer(child)));
|
|
2555
|
+
}
|
|
2556
|
+
const Icon = item.icon;
|
|
2557
|
+
return /* @__PURE__ */ react.createElement(SelectFieldItem, {
|
|
2558
|
+
id: item.id,
|
|
2559
|
+
textValue: item.label
|
|
2560
|
+
}, Icon ? /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(Icon, { size: "sm" }), /* @__PURE__ */ react.createElement(Text, { slot: "label" }, item.label)) : item.label);
|
|
2561
|
+
}
|
|
2562
|
+
function SelectFieldLabel(props) {
|
|
2563
|
+
const { children, required } = props;
|
|
2564
|
+
const { elementType: _elementType, ...labelContextWithoutElementType } = (0, react_aria_components.useSlottedContext)(react_aria_components.LabelContext) ?? {};
|
|
2565
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.LabelContext.Provider, { value: labelContextWithoutElementType }, /* @__PURE__ */ react.createElement(Label, { required }, children));
|
|
2566
|
+
}
|
|
2567
|
+
function AutocompleteTextInput(props) {
|
|
2568
|
+
const { placeholder, shouldFocus, size } = props;
|
|
2569
|
+
const ref = react.useRef(null);
|
|
2570
|
+
const [mergedProps, mergedRef] = (0, react_aria_components.useContextProps)({
|
|
2571
|
+
"aria-label": props["aria-label"],
|
|
2572
|
+
placeholder,
|
|
2573
|
+
type: "search"
|
|
2574
|
+
}, ref, react_aria_components.FieldInputContext);
|
|
2575
|
+
const { onChange, value, ...inputProps } = mergedProps;
|
|
2576
|
+
const inputRef = mergedRef;
|
|
2577
|
+
react.useLayoutEffect(() => {
|
|
2578
|
+
if (!shouldFocus) return;
|
|
2579
|
+
const input = inputRef.current;
|
|
2580
|
+
if (!input) return;
|
|
2581
|
+
requestAnimationFrame(() => {
|
|
2582
|
+
try {
|
|
2583
|
+
input.focus({ preventScroll: true });
|
|
2584
|
+
} catch {}
|
|
2585
|
+
});
|
|
2586
|
+
}, [inputRef, shouldFocus]);
|
|
2587
|
+
return /* @__PURE__ */ react.createElement(TextInput, {
|
|
2588
|
+
...inputProps,
|
|
2589
|
+
ref: inputRef,
|
|
2590
|
+
size,
|
|
2591
|
+
value: typeof value === "string" ? value : "",
|
|
2592
|
+
onChange: (event) => {
|
|
2593
|
+
onChange?.(event.target.value);
|
|
2594
|
+
}
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
function SelectFieldInner(props, ref) {
|
|
2598
|
+
const { appearance = "default", autoFocus, canSearch, defaultOpen, disabled, disabledKeys, helperText, id, isOpen, items, children, label, layout, leadingSlot, name, onOpenChange, placeholder, required, searchPlaceholder, selectionMode = "single", shouldAutoSizeDropdown = true, size = "md", FORCE__className: classNameOverride, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy } = props;
|
|
2599
|
+
const [searchValue, setSearchValue] = react.useState("");
|
|
2600
|
+
const [popoverWidth, setPopoverWidth] = react.useState();
|
|
2601
|
+
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(Boolean(defaultOpen));
|
|
2602
|
+
const isPopoverOpen = isOpen ?? uncontrolledOpen;
|
|
2603
|
+
const { contains } = (0, react_aria_components.useFilter)({ sensitivity: "base" });
|
|
2604
|
+
const [anchorRef, width, offset] = useAnchorWidth([
|
|
2605
|
+
canSearch,
|
|
2606
|
+
selectionMode,
|
|
2607
|
+
size
|
|
2608
|
+
]);
|
|
2609
|
+
const multipleTriggerRef = react.useRef(null);
|
|
2610
|
+
const selectedItemsLabel = label ? `Selected ${label}` : ariaLabel ?? "Selected items";
|
|
2611
|
+
react.useImperativeHandle(ref, () => anchorRef.current, [anchorRef]);
|
|
2612
|
+
react.useLayoutEffect(() => {
|
|
2613
|
+
const trigger = multipleTriggerRef.current ?? anchorRef.current;
|
|
2614
|
+
if (selectionMode !== "multiple" || !isPopoverOpen || popoverWidth || !trigger) return;
|
|
2615
|
+
setPopoverWidth(`${trigger.offsetWidth}px`);
|
|
2616
|
+
}, [
|
|
2617
|
+
isPopoverOpen,
|
|
2618
|
+
popoverWidth,
|
|
2619
|
+
selectionMode,
|
|
2620
|
+
width,
|
|
2621
|
+
anchorRef
|
|
2622
|
+
]);
|
|
2623
|
+
const itemList = react.useMemo(() => items ? Array.from(items) : void 0, [items]);
|
|
2624
|
+
const resolvedChildren = children ?? (itemList ? defaultSelectFieldItemRenderer : void 0);
|
|
2625
|
+
const handleOpenChange = react.useCallback((nextOpen) => {
|
|
2626
|
+
if (isOpen === void 0) setUncontrolledOpen(nextOpen);
|
|
2627
|
+
if (selectionMode === "multiple" && !nextOpen) setPopoverWidth(void 0);
|
|
2628
|
+
if (!nextOpen) setSearchValue("");
|
|
2629
|
+
onOpenChange?.(nextOpen);
|
|
2630
|
+
}, [
|
|
2631
|
+
isOpen,
|
|
2632
|
+
onOpenChange,
|
|
2633
|
+
selectionMode
|
|
2634
|
+
]);
|
|
2635
|
+
const dropdownWidth = selectionMode === "multiple" ? popoverWidth ?? width ?? void 0 : width ?? void 0;
|
|
2636
|
+
const listBoxSearchProps = canSearch ? {
|
|
2637
|
+
autoFocus: false,
|
|
2638
|
+
renderEmptyState: () => /* @__PURE__ */ react.createElement("span", { className: SelectField_module_default.emptyState }, "No results")
|
|
2639
|
+
} : {};
|
|
2640
|
+
const listBox = /* @__PURE__ */ react.createElement(react_aria_components.ListBox, {
|
|
2641
|
+
...listBoxSearchProps,
|
|
2642
|
+
className: SelectField_module_default.listbox,
|
|
2643
|
+
"data-selection-mode": selectionMode,
|
|
2644
|
+
items: itemList
|
|
2645
|
+
}, resolvedChildren);
|
|
2646
|
+
const popoverContent = canSearch ? /* @__PURE__ */ react.createElement(react_aria_components.Autocomplete, {
|
|
2647
|
+
filter: contains,
|
|
2648
|
+
inputValue: searchValue,
|
|
2649
|
+
onInputChange: setSearchValue
|
|
2650
|
+
}, /* @__PURE__ */ react.createElement("div", { className: SelectField_module_default.search }, /* @__PURE__ */ react.createElement(AutocompleteTextInput, {
|
|
2651
|
+
"aria-label": searchPlaceholder || "Search",
|
|
2652
|
+
placeholder: searchPlaceholder || "Search",
|
|
2653
|
+
shouldFocus: isPopoverOpen,
|
|
2654
|
+
size
|
|
2655
|
+
})), listBox) : listBox;
|
|
2656
|
+
const selectContent = /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement("div", { className: fieldLayout_module_default.labelRow }, /* @__PURE__ */ react.createElement(SelectFieldLabel, { required }, label)), /* @__PURE__ */ react.createElement("div", { className: fieldLayout_module_default.fieldContent }, /* @__PURE__ */ react.createElement(SelectFieldTrigger, {
|
|
2657
|
+
appearance,
|
|
2658
|
+
disabled,
|
|
2659
|
+
leadingSlot,
|
|
2660
|
+
placeholder,
|
|
2661
|
+
required,
|
|
2662
|
+
selectedItemsLabel,
|
|
2663
|
+
size,
|
|
2664
|
+
triggerRef: selectionMode === "multiple" ? multipleTriggerRef : void 0
|
|
2665
|
+
}), /* @__PURE__ */ react.createElement(HelperText, {
|
|
2666
|
+
appearance,
|
|
2667
|
+
disabled
|
|
2668
|
+
}, helperText)), /* @__PURE__ */ react.createElement(react_aria_components.Popover, {
|
|
2669
|
+
className: SelectField_module_default.dropdownPanel,
|
|
2670
|
+
offset: 2,
|
|
2671
|
+
crossOffset: offset,
|
|
2672
|
+
triggerRef: selectionMode === "multiple" ? multipleTriggerRef : void 0,
|
|
2673
|
+
style: { width: shouldAutoSizeDropdown ? dropdownWidth : void 0 }
|
|
2674
|
+
}, popoverContent));
|
|
2675
|
+
if (props.selectionMode === "multiple") {
|
|
2676
|
+
const handleChange = (nextValue) => {
|
|
2677
|
+
props.onChange?.(new Set(nextValue));
|
|
2678
|
+
};
|
|
2679
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.Select, {
|
|
2680
|
+
id,
|
|
2681
|
+
ref: anchorRef,
|
|
2682
|
+
name,
|
|
2683
|
+
className: clsx(fieldLayout_module_default.field, classNameOverride),
|
|
2684
|
+
"data-capra-field-root": "",
|
|
2685
|
+
"data-layout": layout,
|
|
2686
|
+
isDisabled: disabled,
|
|
2687
|
+
isRequired: required,
|
|
2688
|
+
isInvalid: appearance === "danger",
|
|
2689
|
+
validationBehavior: "aria",
|
|
2690
|
+
placeholder,
|
|
2691
|
+
selectionMode: "multiple",
|
|
2692
|
+
disabledKeys,
|
|
2693
|
+
value: normalizeIterable(props.value),
|
|
2694
|
+
defaultValue: normalizeIterable(props.defaultValue),
|
|
2695
|
+
onChange: handleChange,
|
|
2696
|
+
isOpen,
|
|
2697
|
+
defaultOpen,
|
|
2698
|
+
onOpenChange: handleOpenChange,
|
|
2699
|
+
autoFocus,
|
|
2700
|
+
"aria-label": ariaLabel,
|
|
2701
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2702
|
+
"aria-describedby": ariaDescribedBy
|
|
2703
|
+
}, selectContent);
|
|
2704
|
+
}
|
|
2705
|
+
const handleChange = (nextValue) => {
|
|
2706
|
+
props.onChange?.(nextValue ?? null);
|
|
2707
|
+
};
|
|
2708
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.Select, {
|
|
2709
|
+
id,
|
|
2710
|
+
ref: anchorRef,
|
|
2711
|
+
name,
|
|
2712
|
+
className: clsx(fieldLayout_module_default.field, classNameOverride),
|
|
2713
|
+
"data-capra-field-root": "",
|
|
2714
|
+
"data-layout": layout,
|
|
2715
|
+
isDisabled: disabled,
|
|
2716
|
+
isRequired: required,
|
|
2717
|
+
isInvalid: appearance === "danger",
|
|
2718
|
+
validationBehavior: "aria",
|
|
2719
|
+
placeholder,
|
|
2720
|
+
selectionMode: "single",
|
|
2721
|
+
disabledKeys,
|
|
2722
|
+
value: props.value,
|
|
2723
|
+
defaultValue: props.defaultValue,
|
|
2724
|
+
onChange: handleChange,
|
|
2725
|
+
isOpen,
|
|
2726
|
+
defaultOpen,
|
|
2727
|
+
onOpenChange: handleOpenChange,
|
|
2728
|
+
autoFocus,
|
|
2729
|
+
"aria-label": ariaLabel,
|
|
2730
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2731
|
+
"aria-describedby": ariaDescribedBy
|
|
2732
|
+
}, selectContent);
|
|
2733
|
+
}
|
|
2734
|
+
const SelectFieldRoot = react.forwardRef(SelectFieldInner);
|
|
2735
|
+
/**
|
|
2736
|
+
* Composed select field with Capra label/helper text layout, single and multiple selection, and an optional popover search input.
|
|
2737
|
+
*/
|
|
2738
|
+
const SelectField = Object.assign(SelectFieldRoot, {
|
|
2739
|
+
Item: SelectFieldItem,
|
|
2740
|
+
Header: SelectFieldHeader,
|
|
2741
|
+
Section: SelectFieldSection
|
|
2742
|
+
});
|
|
2743
|
+
//#endregion
|
|
2316
2744
|
//#region src/components/DateRangePickerField/DateRangePickerField.module.css
|
|
2317
2745
|
var DateRangePickerField_module_default = {
|
|
2318
2746
|
"cell": "capra-DateRangePickerField-module-QpPhpG-cell",
|
|
@@ -4120,20 +4548,21 @@ const Toast = {
|
|
|
4120
4548
|
//#endregion
|
|
4121
4549
|
//#region src/components/Menu/Menu.module.css
|
|
4122
4550
|
var Menu_module_default = {
|
|
4123
|
-
"divider": "capra-Menu-module-
|
|
4124
|
-
"header": "capra-Menu-module-
|
|
4125
|
-
"list": "capra-Menu-module-
|
|
4126
|
-
"menu": "capra-Menu-module-
|
|
4127
|
-
"menuItem": "capra-Menu-module-
|
|
4128
|
-
"menuItemDescription": "capra-Menu-module-
|
|
4129
|
-
"menuItemLabel": "capra-Menu-module-
|
|
4130
|
-
"menuItemLeadingGutter": "capra-Menu-module-
|
|
4131
|
-
"menuItemListItemShell": "capra-Menu-module-
|
|
4132
|
-
"menuItemShortcut": "capra-Menu-module-
|
|
4133
|
-
"menuItemTrailingGroup": "capra-Menu-module-
|
|
4134
|
-
"menuItemTrailingGutter": "capra-Menu-module-
|
|
4135
|
-
"menuTriggerSlot": "capra-Menu-module-
|
|
4136
|
-
"section": "capra-Menu-module-
|
|
4551
|
+
"divider": "capra-Menu-module-HIhAFW-divider",
|
|
4552
|
+
"header": "capra-Menu-module-HIhAFW-header",
|
|
4553
|
+
"list": "capra-Menu-module-HIhAFW-list",
|
|
4554
|
+
"menu": "capra-Menu-module-HIhAFW-menu",
|
|
4555
|
+
"menuItem": "capra-Menu-module-HIhAFW-menuItem",
|
|
4556
|
+
"menuItemDescription": "capra-Menu-module-HIhAFW-menuItemDescription",
|
|
4557
|
+
"menuItemLabel": "capra-Menu-module-HIhAFW-menuItemLabel",
|
|
4558
|
+
"menuItemLeadingGutter": "capra-Menu-module-HIhAFW-menuItemLeadingGutter",
|
|
4559
|
+
"menuItemListItemShell": "capra-Menu-module-HIhAFW-menuItemListItemShell",
|
|
4560
|
+
"menuItemShortcut": "capra-Menu-module-HIhAFW-menuItemShortcut",
|
|
4561
|
+
"menuItemTrailingGroup": "capra-Menu-module-HIhAFW-menuItemTrailingGroup",
|
|
4562
|
+
"menuItemTrailingGutter": "capra-Menu-module-HIhAFW-menuItemTrailingGutter",
|
|
4563
|
+
"menuTriggerSlot": "capra-Menu-module-HIhAFW-menuTriggerSlot",
|
|
4564
|
+
"section": "capra-Menu-module-HIhAFW-section",
|
|
4565
|
+
"slot": "capra-Menu-module-HIhAFW-slot"
|
|
4137
4566
|
};
|
|
4138
4567
|
//#endregion
|
|
4139
4568
|
//#region src/components/Menu/Menu.tsx
|
|
@@ -4223,7 +4652,7 @@ const MenuItem = ({ as: Component, label, description, ariaLabel, href, disabled
|
|
|
4223
4652
|
const labelContent = children ?? label;
|
|
4224
4653
|
const showDescription = description != null && description !== "";
|
|
4225
4654
|
const textValue = ariaLabel || (typeof label === "string" ? label : void 0) || (typeof children === "string" ? children : void 0) || "";
|
|
4226
|
-
const listItemContent = /* @__PURE__ */ react.createElement(react.Fragment, null, (indent || icon) && /* @__PURE__ */ react.createElement(ListItem.Leading, { FORCE__className: icon ? Menu_module_default.menuItemLeadingGutter : void 0 }, icon
|
|
4655
|
+
const listItemContent = /* @__PURE__ */ react.createElement(react.Fragment, null, (indent || icon) && /* @__PURE__ */ react.createElement(ListItem.Leading, { FORCE__className: icon ? Menu_module_default.menuItemLeadingGutter : void 0 }, icon), /* @__PURE__ */ react.createElement(ListItem.Content, null, /* @__PURE__ */ react.createElement(ListItem.Label, null, /* @__PURE__ */ react.createElement("span", { className: Menu_module_default.menuItemLabel }, labelContent)), showDescription ? /* @__PURE__ */ react.createElement(ListItem.Description, null, /* @__PURE__ */ react.createElement("span", { className: Menu_module_default.menuItemDescription }, description)) : null), (shortcut || parent) && /* @__PURE__ */ react.createElement(ListItem.Trailing, { FORCE__className: Menu_module_default.menuItemTrailingGutter }, /* @__PURE__ */ react.createElement("span", { className: Menu_module_default.menuItemTrailingGroup }, [shortcut ? /* @__PURE__ */ react.createElement("span", {
|
|
4227
4656
|
key: "shortcut",
|
|
4228
4657
|
className: Menu_module_default.menuItemShortcut
|
|
4229
4658
|
}, shortcut) : null, parent ? /* @__PURE__ */ react.createElement(_capra_icons.ChevronRight, {
|
|
@@ -4251,7 +4680,8 @@ const MenuItem = ({ as: Component, label, description, ariaLabel, href, disabled
|
|
|
4251
4680
|
"data-has-description": showDescription || void 0,
|
|
4252
4681
|
render,
|
|
4253
4682
|
onClick,
|
|
4254
|
-
onPress
|
|
4683
|
+
onPress,
|
|
4684
|
+
...rest
|
|
4255
4685
|
}, /* @__PURE__ */ react.createElement(ListItem, {
|
|
4256
4686
|
as: "div",
|
|
4257
4687
|
role: "presentation",
|
|
@@ -4293,7 +4723,6 @@ const MenuSubmenu = ({ label, children, itemHoverAppearance = "default", itemAct
|
|
|
4293
4723
|
}, listItemContent)), /* @__PURE__ */ react.createElement(PopoverSurface, {
|
|
4294
4724
|
placement: "rightTop",
|
|
4295
4725
|
isNonModal: true,
|
|
4296
|
-
shouldFlip: false,
|
|
4297
4726
|
offsets: [0, 0],
|
|
4298
4727
|
removeContentPadding: true
|
|
4299
4728
|
}, /* @__PURE__ */ react.createElement("div", menuSessionId != null ? { [MENU_SESSION_DATA_ATTR]: menuSessionId } : {}, /* @__PURE__ */ react.createElement(react_aria_components.Menu, {
|
|
@@ -4361,7 +4790,7 @@ function MenuPanelFocusScope({ controlledOpen, children }) {
|
|
|
4361
4790
|
restoreFocus: true
|
|
4362
4791
|
}, children));
|
|
4363
4792
|
}
|
|
4364
|
-
const Menu = ({ trigger, children, contentProps, open, onOpenChange, itemHoverAppearance = "default", itemActiveAccentBar = true, itemActiveLabelSemibold = true, panelPadding = "default", popoverOffset =
|
|
4793
|
+
const Menu = ({ trigger, children, contentProps, open, onOpenChange, itemHoverAppearance = "default", itemActiveAccentBar = true, itemActiveLabelSemibold = true, panelPadding = "default", popoverOffset = 2, trapFocus = false, FORCE__className: classNameOverride }) => {
|
|
4365
4794
|
const sessionId = react.useId();
|
|
4366
4795
|
const menuPanel = /* @__PURE__ */ react.createElement(react_aria_components.Menu, {
|
|
4367
4796
|
className: clsx(Menu_module_default.menu, classNameOverride),
|
|
@@ -4428,6 +4857,17 @@ var TabNav_module_default = {
|
|
|
4428
4857
|
const SUB_KEY_SEP = "::";
|
|
4429
4858
|
/** Delay before closing a subnav on pointer leave (hover), so users can move into the menu. */
|
|
4430
4859
|
const HOVER_CLOSE_DELAY_MS = 150;
|
|
4860
|
+
function getRoutedLinkProps(source) {
|
|
4861
|
+
return {
|
|
4862
|
+
href: source.href,
|
|
4863
|
+
hrefLang: source.hrefLang,
|
|
4864
|
+
target: source.target,
|
|
4865
|
+
rel: source.rel,
|
|
4866
|
+
download: source.download,
|
|
4867
|
+
referrerPolicy: source.referrerPolicy,
|
|
4868
|
+
routerOptions: source.routerOptions
|
|
4869
|
+
};
|
|
4870
|
+
}
|
|
4431
4871
|
function optionalAriaLabelProps(source) {
|
|
4432
4872
|
const v = source["aria-label"];
|
|
4433
4873
|
return v != null && v !== "" ? { "aria-label": v } : {};
|
|
@@ -4437,7 +4877,7 @@ function optionalAriaLabelProps(source) {
|
|
|
4437
4877
|
* Tab items are links that redirect to URLs. With `subItems`, horizontal tabs open a dropdown menu; vertical tabs
|
|
4438
4878
|
* use an inline indented list (Tab Nav | Vertical in Figma).
|
|
4439
4879
|
*/
|
|
4440
|
-
const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", centered = false, tabBarExtraSlot, wrap = true, FORCE__className: classNameOverride, "aria-label": ariaLabel = "Navigation", ...props }) => {
|
|
4880
|
+
const TabNav = ({ activeKey, onTabPress, onTabClick, items, tabPlacement = "horizontal", centered = false, tabBarExtraSlot, wrap = true, FORCE__className: classNameOverride, "aria-label": ariaLabel = "Navigation", ...props }) => {
|
|
4441
4881
|
const [subMenuOpen, setSubMenuOpen] = react.useState({});
|
|
4442
4882
|
const hoverCloseTimeoutRef = react.useRef(null);
|
|
4443
4883
|
const pendingKeyboardFocusKeyRef = react.useRef(null);
|
|
@@ -4598,15 +5038,6 @@ const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", cen
|
|
|
4598
5038
|
getEnabledMenuItems,
|
|
4599
5039
|
getTriggerElement
|
|
4600
5040
|
]);
|
|
4601
|
-
const handleTabClick = (key, event) => {
|
|
4602
|
-
const item = items.find((i) => i.key === key);
|
|
4603
|
-
if (item?.disabled) {
|
|
4604
|
-
event.preventDefault();
|
|
4605
|
-
return;
|
|
4606
|
-
}
|
|
4607
|
-
if (item?.subItems?.length) return;
|
|
4608
|
-
onTabClick?.(key, event);
|
|
4609
|
-
};
|
|
4610
5041
|
const handleKeyDown = (event, key) => {
|
|
4611
5042
|
const itemIndex = items.findIndex((i) => i.key === key);
|
|
4612
5043
|
if (itemIndex === -1) return;
|
|
@@ -4743,37 +5174,24 @@ const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", cen
|
|
|
4743
5174
|
}, item.subItems.map((sub) => {
|
|
4744
5175
|
const subActive = activeMainKey === item.key && activeSubKey === sub.key;
|
|
4745
5176
|
const compoundKey = `${item.key}${SUB_KEY_SEP}${sub.key}`;
|
|
4746
|
-
|
|
5177
|
+
return /* @__PURE__ */ react.createElement("li", {
|
|
5178
|
+
key: sub.key,
|
|
5179
|
+
className: TabNav_module_default.subTabListItem
|
|
5180
|
+
}, /* @__PURE__ */ react.createElement(react_aria_components.Link, {
|
|
4747
5181
|
"data-tab-key": compoundKey,
|
|
4748
5182
|
"data-indent": true,
|
|
4749
5183
|
"data-variant": "default",
|
|
4750
5184
|
"data-active": subActive || void 0,
|
|
4751
|
-
"data-disabled": sub.disabled || void 0,
|
|
4752
5185
|
id: `tabnav-${item.key}-${sub.key}`,
|
|
4753
5186
|
className: clsx(TabNav_module_default.tab, TabNav_module_default.subTab),
|
|
4754
|
-
"aria-current": subActive ? "page" : void 0
|
|
4755
|
-
};
|
|
4756
|
-
if (sub.href && sub.disabled) return /* @__PURE__ */ react.createElement("li", {
|
|
4757
|
-
key: sub.key,
|
|
4758
|
-
className: TabNav_module_default.subTabListItem
|
|
4759
|
-
}, /* @__PURE__ */ react.createElement("a", {
|
|
4760
|
-
...subCommon,
|
|
5187
|
+
"aria-current": subActive ? "page" : void 0,
|
|
4761
5188
|
...optionalAriaLabelProps(sub),
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
"aria-hidden": "true"
|
|
4769
|
-
}), /* @__PURE__ */ react.createElement("span", { className: TabNav_module_default.tabLabel }, sub.name)));
|
|
4770
|
-
if (sub.href) return /* @__PURE__ */ react.createElement("li", {
|
|
4771
|
-
key: sub.key,
|
|
4772
|
-
className: TabNav_module_default.subTabListItem
|
|
4773
|
-
}, /* @__PURE__ */ react.createElement("a", {
|
|
4774
|
-
...subCommon,
|
|
4775
|
-
...optionalAriaLabelProps(sub),
|
|
4776
|
-
href: sub.href,
|
|
5189
|
+
...getRoutedLinkProps(sub),
|
|
5190
|
+
isDisabled: sub.disabled,
|
|
5191
|
+
onPress: () => {
|
|
5192
|
+
sub.onPress?.();
|
|
5193
|
+
onTabPress?.(compoundKey);
|
|
5194
|
+
},
|
|
4777
5195
|
onClick: (e) => {
|
|
4778
5196
|
sub.onClick?.(e);
|
|
4779
5197
|
onTabClick?.(compoundKey, e);
|
|
@@ -4783,26 +5201,6 @@ const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", cen
|
|
|
4783
5201
|
className: TabNav_module_default.indentSpacer,
|
|
4784
5202
|
"aria-hidden": "true"
|
|
4785
5203
|
}), /* @__PURE__ */ react.createElement("span", { className: TabNav_module_default.tabLabel }, sub.name)));
|
|
4786
|
-
return /* @__PURE__ */ react.createElement("li", {
|
|
4787
|
-
key: sub.key,
|
|
4788
|
-
className: TabNav_module_default.subTabListItem
|
|
4789
|
-
}, /* @__PURE__ */ react.createElement("span", {
|
|
4790
|
-
...subCommon,
|
|
4791
|
-
...optionalAriaLabelProps(sub),
|
|
4792
|
-
role: "link",
|
|
4793
|
-
"aria-disabled": sub.disabled,
|
|
4794
|
-
tabIndex: sub.disabled ? -1 : 0,
|
|
4795
|
-
onKeyDown: (e) => {
|
|
4796
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
4797
|
-
e.preventDefault();
|
|
4798
|
-
sub.onClick?.(e);
|
|
4799
|
-
onTabClick?.(compoundKey, e);
|
|
4800
|
-
} else handleKeyDown(e, item.key);
|
|
4801
|
-
}
|
|
4802
|
-
}, /* @__PURE__ */ react.createElement("span", {
|
|
4803
|
-
className: TabNav_module_default.indentSpacer,
|
|
4804
|
-
"aria-hidden": "true"
|
|
4805
|
-
}), /* @__PURE__ */ react.createElement("span", { className: TabNav_module_default.tabLabel }, sub.name)));
|
|
4806
5204
|
})));
|
|
4807
5205
|
}
|
|
4808
5206
|
if (hasSubItems) {
|
|
@@ -4826,7 +5224,7 @@ const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", cen
|
|
|
4826
5224
|
itemActiveLabelSemibold: false,
|
|
4827
5225
|
panelPadding: "none",
|
|
4828
5226
|
popoverOffset: 1,
|
|
4829
|
-
open: subMenuOpen[item.key],
|
|
5227
|
+
open: Boolean(subMenuOpen[item.key]),
|
|
4830
5228
|
onOpenChange: (open) => {
|
|
4831
5229
|
if (open) {
|
|
4832
5230
|
openSubMenu(item.key);
|
|
@@ -4862,36 +5260,30 @@ const TabNav = ({ activeKey, onTabClick, items, tabPlacement = "horizontal", cen
|
|
|
4862
5260
|
ariaLabel: sub["aria-label"],
|
|
4863
5261
|
href: sub.href,
|
|
4864
5262
|
disabled: sub.disabled,
|
|
5263
|
+
routerOptions: sub.routerOptions,
|
|
4865
5264
|
active: activeSubKey === sub.key,
|
|
5265
|
+
onPress: () => {
|
|
5266
|
+
sub.onPress?.();
|
|
5267
|
+
onTabPress?.(`${item.key}${SUB_KEY_SEP}${sub.key}`);
|
|
5268
|
+
closeMenu();
|
|
5269
|
+
},
|
|
4866
5270
|
onClick: (e) => {
|
|
4867
5271
|
sub.onClick?.(e);
|
|
4868
|
-
|
|
5272
|
+
onTabClick?.(`${item.key}${SUB_KEY_SEP}${sub.key}`, e);
|
|
4869
5273
|
}
|
|
4870
5274
|
});
|
|
4871
5275
|
}));
|
|
4872
5276
|
}
|
|
4873
|
-
|
|
5277
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.Link, {
|
|
4874
5278
|
key: item.key,
|
|
4875
5279
|
...commonTabProps,
|
|
4876
|
-
|
|
5280
|
+
...getRoutedLinkProps(item),
|
|
5281
|
+
isDisabled: item.disabled,
|
|
4877
5282
|
"aria-current": ariaCurrentPage ? "page" : void 0,
|
|
4878
|
-
|
|
5283
|
+
onPress: () => onTabPress?.(item.key),
|
|
5284
|
+
onClick: (e) => onTabClick?.(item.key, e),
|
|
4879
5285
|
onKeyDown: (e) => handleKeyDown(e, item.key)
|
|
4880
5286
|
}, renderTabContent(item));
|
|
4881
|
-
return /* @__PURE__ */ react.createElement("span", {
|
|
4882
|
-
key: item.key,
|
|
4883
|
-
...commonTabProps,
|
|
4884
|
-
role: "link",
|
|
4885
|
-
"aria-disabled": item.disabled,
|
|
4886
|
-
"aria-current": ariaCurrentPage ? "page" : void 0,
|
|
4887
|
-
tabIndex: item.disabled ? -1 : computedTabIndex ?? 0,
|
|
4888
|
-
onKeyDown: (e) => {
|
|
4889
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
4890
|
-
e.preventDefault();
|
|
4891
|
-
handleTabClick(item.key, e);
|
|
4892
|
-
} else handleKeyDown(e, item.key);
|
|
4893
|
-
}
|
|
4894
|
-
}, renderTabContent(item));
|
|
4895
5287
|
})), tabBarExtraSlot && /* @__PURE__ */ react.createElement("div", { className: TabNav_module_default.extraContent }, tabBarExtraSlot)));
|
|
4896
5288
|
};
|
|
4897
5289
|
TabNav.displayName = "TabNav";
|
|
@@ -5270,6 +5662,7 @@ Object.defineProperty(exports, "RouterProvider", {
|
|
|
5270
5662
|
});
|
|
5271
5663
|
exports.SKELETON_SIZE = SKELETON_SIZE;
|
|
5272
5664
|
exports.SKELETON_SIZE_TOKENS = SKELETON_SIZE_TOKENS;
|
|
5665
|
+
exports.SelectField = SelectField;
|
|
5273
5666
|
exports.Skeleton = Skeleton;
|
|
5274
5667
|
exports.SkeletonGroup = SkeletonGroup;
|
|
5275
5668
|
exports.Spinner = Spinner;
|