@jobber/components 7.15.3-progress-b-cc1652c.1 → 7.15.4
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/README.md +1 -1
- package/dist/Card/index.cjs +3 -6
- package/dist/Card/index.mjs +3 -6
- package/dist/DataDump/index.cjs +3 -6
- package/dist/DataDump/index.mjs +3 -6
- package/dist/DrawerRoot-es.js +2 -2
- package/dist/InputNumberExperimental-cjs.js +4 -3
- package/dist/InputNumberExperimental-es.js +4 -3
- package/dist/Menu/index.cjs +3 -6
- package/dist/Menu/index.mjs +3 -6
- package/dist/Menu-cjs.js +1 -3
- package/dist/Menu-es.js +1 -3
- package/dist/MenuSubmenuTrigger-cjs.js +16 -16
- package/dist/MenuSubmenuTrigger-es.js +3 -3
- package/dist/NumberFieldInput-cjs.js +4 -252
- package/dist/NumberFieldInput-es.js +5 -249
- package/dist/Page/index.cjs +3 -5
- package/dist/Page/index.mjs +3 -5
- package/dist/index.cjs +3 -5
- package/dist/index.mjs +3 -5
- package/dist/primitives/InputNumberExperimental/index.cjs +1 -0
- package/dist/primitives/InputNumberExperimental/index.mjs +1 -0
- package/dist/primitives/index.cjs +1 -0
- package/dist/primitives/index.mjs +1 -0
- package/dist/styles.css +9617 -9617
- package/dist/unstyledPrimitives/index.cjs +14 -13
- package/dist/unstyledPrimitives/index.mjs +4 -3
- package/dist/useBaseUiId-cjs.js +275 -0
- package/dist/useBaseUiId-es.js +251 -0
- package/dist/useRenderElement-es.js +1 -1
- package/dist/useValueChanged-es.js +2 -2
- package/package.json +4 -4
|
@@ -4,13 +4,14 @@ var DrawerRoot = require('../DrawerRoot-cjs.js');
|
|
|
4
4
|
var MenuSubmenuTrigger = require('../MenuSubmenuTrigger-cjs.js');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var useRenderElement = require('../useRenderElement-cjs.js');
|
|
7
|
-
var
|
|
7
|
+
var useBaseUiId = require('../useBaseUiId-cjs.js');
|
|
8
8
|
var useValueChanged = require('../useValueChanged-cjs.js');
|
|
9
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
10
10
|
var floatingUi_utils_dom = require('../floating-ui.utils.dom-cjs.js');
|
|
11
11
|
var ReactDOM = require('react-dom');
|
|
12
12
|
var index_esm = require('../index.esm-cjs.js');
|
|
13
13
|
var Separator = require('../Separator-cjs.js');
|
|
14
|
+
var NumberFieldInput = require('../NumberFieldInput-cjs.js');
|
|
14
15
|
require('../floating-ui.react-dom-cjs.js');
|
|
15
16
|
|
|
16
17
|
function _interopNamespaceDefault(e) {
|
|
@@ -49,7 +50,7 @@ const DialogDescription = /*#__PURE__*/React__namespace.forwardRef(function Dial
|
|
|
49
50
|
const {
|
|
50
51
|
store
|
|
51
52
|
} = DrawerRoot.useDialogRootContext();
|
|
52
|
-
const id =
|
|
53
|
+
const id = useBaseUiId.useBaseUiId(idProp);
|
|
53
54
|
store.useSyncedValueWithCleanup('descriptionElementId', id);
|
|
54
55
|
return useRenderElement.useRenderElement('p', componentProps, {
|
|
55
56
|
ref: forwardedRef,
|
|
@@ -1491,7 +1492,7 @@ const DrawerSwipeArea = /*#__PURE__*/React__namespace.forwardRef(function Drawer
|
|
|
1491
1492
|
const closedOffsetRef = React__namespace.useRef(null);
|
|
1492
1493
|
const appliedSwipeStylesRef = React__namespace.useRef(false);
|
|
1493
1494
|
const popupTransitionRef = React__namespace.useRef(null);
|
|
1494
|
-
const swipeAreaId =
|
|
1495
|
+
const swipeAreaId = useBaseUiId.useBaseUiId(componentProps.id);
|
|
1495
1496
|
const registerTrigger = DrawerRoot.useTriggerRegistration(swipeAreaId, store);
|
|
1496
1497
|
const open = store.useState('open');
|
|
1497
1498
|
const resolvedSwipeDirection = swipeDirectionProp ?? oppositeSwipeDirection[swipeDirection];
|
|
@@ -2882,7 +2883,7 @@ const MenuCheckboxItem = /*#__PURE__*/React__namespace.forwardRef(function MenuC
|
|
|
2882
2883
|
label
|
|
2883
2884
|
});
|
|
2884
2885
|
const menuPositionerContext = MenuSubmenuTrigger.useMenuPositionerContext(true);
|
|
2885
|
-
const id =
|
|
2886
|
+
const id = useBaseUiId.useBaseUiId(idProp);
|
|
2886
2887
|
const {
|
|
2887
2888
|
store
|
|
2888
2889
|
} = MenuSubmenuTrigger.useMenuRootContext();
|
|
@@ -5069,7 +5070,7 @@ const ComboboxTrigger = /*#__PURE__*/React__namespace.forwardRef(function Combob
|
|
|
5069
5070
|
const {
|
|
5070
5071
|
buttonRef,
|
|
5071
5072
|
getButtonProps
|
|
5072
|
-
} =
|
|
5073
|
+
} = useBaseUiId.useButton({
|
|
5073
5074
|
native: nativeButton,
|
|
5074
5075
|
disabled
|
|
5075
5076
|
});
|
|
@@ -5202,7 +5203,7 @@ const ComboboxInternalDismissButton = /*#__PURE__*/React__namespace.forwardRef(f
|
|
|
5202
5203
|
const {
|
|
5203
5204
|
buttonRef,
|
|
5204
5205
|
getButtonProps
|
|
5205
|
-
} =
|
|
5206
|
+
} = useBaseUiId.useButton({
|
|
5206
5207
|
native: false
|
|
5207
5208
|
});
|
|
5208
5209
|
const mergedRef = useRenderElement.useMergedRefs(forwardedRef, buttonRef);
|
|
@@ -5274,7 +5275,7 @@ const ComboboxInput = /*#__PURE__*/React__namespace.forwardRef(function Combobox
|
|
|
5274
5275
|
const listEmpty = filteredItems.length === 0;
|
|
5275
5276
|
const isInsidePopup = hasPositionerParent || inline;
|
|
5276
5277
|
const focusManagerModal = !isInsidePopup || modal;
|
|
5277
|
-
const id =
|
|
5278
|
+
const id = useBaseUiId.useBaseUiId(idProp ?? (!isInsidePopup ? rootId : undefined));
|
|
5278
5279
|
const ariaLabelledBy = resolveAriaLabelledBy(fieldLabelId, undefined);
|
|
5279
5280
|
const fieldStateForInput = hasPositionerParent ? NumberFieldInput.DEFAULT_FIELD_STATE_ATTRIBUTES : fieldState;
|
|
5280
5281
|
const [composingValue, setComposingValue] = React__namespace.useState(null);
|
|
@@ -5708,7 +5709,7 @@ const ComboboxClear = /*#__PURE__*/React__namespace.forwardRef(function Combobox
|
|
|
5708
5709
|
const {
|
|
5709
5710
|
buttonRef,
|
|
5710
5711
|
getButtonProps
|
|
5711
|
-
} =
|
|
5712
|
+
} = useBaseUiId.useButton({
|
|
5712
5713
|
native: nativeButton,
|
|
5713
5714
|
disabled
|
|
5714
5715
|
});
|
|
@@ -6292,7 +6293,7 @@ const ComboboxGroupLabel = /*#__PURE__*/React__namespace.forwardRef(function Com
|
|
|
6292
6293
|
const {
|
|
6293
6294
|
setLabelId
|
|
6294
6295
|
} = useComboboxGroupContext();
|
|
6295
|
-
const id =
|
|
6296
|
+
const id = useBaseUiId.useBaseUiId(idProp);
|
|
6296
6297
|
useValueChanged.useIsoLayoutEffect(() => {
|
|
6297
6298
|
setLabelId(id);
|
|
6298
6299
|
return () => {
|
|
@@ -6419,7 +6420,7 @@ const ComboboxItem = /*#__PURE__*/React__namespace.memo(/*#__PURE__*/React__name
|
|
|
6419
6420
|
const {
|
|
6420
6421
|
getButtonProps,
|
|
6421
6422
|
buttonRef
|
|
6422
|
-
} =
|
|
6423
|
+
} = useBaseUiId.useButton({
|
|
6423
6424
|
disabled,
|
|
6424
6425
|
focusableWhenDisabled: true,
|
|
6425
6426
|
native: nativeButton,
|
|
@@ -6556,7 +6557,7 @@ function ComboboxRoot(props) {
|
|
|
6556
6557
|
}
|
|
6557
6558
|
|
|
6558
6559
|
function useRegisteredLabelId(idProp, setLabelId) {
|
|
6559
|
-
const id =
|
|
6560
|
+
const id = useBaseUiId.useBaseUiId(idProp);
|
|
6560
6561
|
useValueChanged.useIsoLayoutEffect(() => {
|
|
6561
6562
|
setLabelId(id);
|
|
6562
6563
|
return () => {
|
|
@@ -6664,7 +6665,7 @@ const ComboboxLabel = /*#__PURE__*/React__namespace.forwardRef(function Combobox
|
|
|
6664
6665
|
}
|
|
6665
6666
|
const ownerStackMessage = useValueChanged.SafeReact.captureOwnerStack?.() || '';
|
|
6666
6667
|
const message = '<Combobox.Label> labels <Combobox.Trigger> only. ' + 'When <Combobox.Input> is the form control, use a native <label> or <Field.Label> instead.';
|
|
6667
|
-
|
|
6668
|
+
useBaseUiId.error(`${message}${ownerStackMessage}`);
|
|
6668
6669
|
}, [inputElement, inputInsidePopup]);
|
|
6669
6670
|
}
|
|
6670
6671
|
const labelProps = useLabel({
|
|
@@ -6949,7 +6950,7 @@ const ComboboxChipRemove = /*#__PURE__*/React__namespace.forwardRef(function Com
|
|
|
6949
6950
|
const {
|
|
6950
6951
|
buttonRef,
|
|
6951
6952
|
getButtonProps
|
|
6952
|
-
} =
|
|
6953
|
+
} = useBaseUiId.useButton({
|
|
6953
6954
|
native: nativeButton,
|
|
6954
6955
|
disabled: disabled || readOnly,
|
|
6955
6956
|
focusableWhenDisabled: true
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { u as useDialogRootContext, am as useDrawerProviderContext, an as DrawerBackdropCssVars, ao as DrawerPopupCssVars, ap as DrawerProviderContext, aq as CommonPopupDataAttributes, N as popupStateMapping, ar as useDialogPortalContext, as as DialogStore, l as contains, g as getTarget, at as useDrawerRootContext, al as useTriggerRegistration, au as DrawerPopupDataAttributes, av as useDrawerSnapPoints, aw as DrawerViewportContext, ax as BASE_UI_SWIPE_IGNORE_SELECTOR, ay as DRAWER_CONTENT_ATTRIBUTE, a as DrawerBackdrop, c as DrawerContent, b as DrawerPopup, D as DrawerPortal, d as DrawerRoot, V as inertValue, Z as createSelector, az as useStore, a4 as useOpenInteractionType, a9 as useDismiss, J as useInteractions, a2 as useOnFirstRender, aA as Store, ai as pressableTriggerOpenStateMapping, L as triggerOpenStateMapping, R as FloatingPortal, a7 as useScrollLock, U as InternalBackdrop, X as DROPDOWN_COLLISION_AVOIDANCE, Q as FloatingFocusManager } from '../DrawerRoot-es.js';
|
|
2
2
|
import { b as DrawerClose, a as DrawerTitle, D as DrawerTrigger, u as useMenuRootContext, p as useMenuPositionerContext, q as useContextMenuRootContext, r as useCompositeListItem, s as useMenuItem, R as REGULAR_ITEM, t as itemMapping, v as useDirection, w as MenuStore, m as MenuGroup, o as MenuGroupLabel, d as MenuItem, c as MenuLinkItem, k as MenuPopup, i as MenuPortal, j as MenuPositioner, l as MenuRadioGroup, e as MenuRadioItem, f as MenuRadioItemIndicator, h as MenuRoot, n as MenuSubmenuRoot, g as MenuSubmenuTrigger, M as MenuTrigger, x as useFloatingRootContext, y as useClick, z as useListNavigation, A as useTypeahead, B as getPseudoElementBounds, C as CompositeList, E as useAnchorPositioning, F as getDisabledMountTransitionStyles, I as IndexGuessBehavior } from '../MenuSubmenuTrigger-es.js';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { u as useRenderElement, m as mergeProps, f as formatErrorMessage, N as NOOP, E as EMPTY_OBJECT, d as EMPTY_ARRAY,
|
|
5
|
-
import { u as useBaseUiId,
|
|
6
|
-
import {
|
|
4
|
+
import { u as useRenderElement, m as mergeProps, f as formatErrorMessage, N as NOOP, E as EMPTY_OBJECT, d as EMPTY_ARRAY, b as useRefWithInit, c as useMergedRefs } from '../useRenderElement-es.js';
|
|
5
|
+
import { u as useBaseUiId, a as useButton, e as error } from '../useBaseUiId-es.js';
|
|
6
|
+
import { u as useIsoLayoutEffect, a as useStableCallback, t as transitionStatusMapping, k as createChangeEventDetails, V as imperativeAction, s as ownerDocument, g as clamp, c as useTimeout, a3 as swipe, D as useAnimationFrame, X as TransitionStatusDataAttributes, K as triggerHover, h as useControlled, P as itemPress, d as useTransitionStatus, e as useOpenChangeComplete, R as useAnimationsFinished, i as useValueAsRef, r as createGenericEventDetails, o as inputClear, m as inputChange, M as focusOut, Q as outsidePress, y as useValueChanged, n as none, a4 as inputPress, v as visuallyHiddenInput, l as visuallyHidden, z as stopEvent, L as listNavigation, B as closePress, a1 as isAndroid, a5 as isFirefox, J as escapeKey, a6 as clearPress, S as SafeReact, a7 as chipRemovePress, a8 as scrub, _ as isWebKit } from '../useValueChanged-es.js';
|
|
7
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { a as isHTMLElement, f as getComputedStyle, b as isElement, k as getWindow } from '../floating-ui.utils.dom-es.js';
|
|
9
9
|
import * as ReactDOM from 'react-dom';
|
|
10
10
|
import { y as round } from '../index.esm-es.js';
|
|
11
11
|
import { S as Separator } from '../Separator-es.js';
|
|
12
|
+
import { a as useFormContext, b as useFieldRootContext, i as useLabelableId, j as useField, f as fieldValidityMapping, u as useLabelableContext, k as DEFAULT_FIELD_STATE_ATTRIBUTES, l as useNumberFieldRootContext, m as DEFAULT_STEP, s as stateAttributesMapping$9, h as NumberFieldDecrement, c as NumberFieldGroup, e as NumberFieldIncrement, d as NumberFieldInput, N as NumberFieldRoot } from '../NumberFieldInput-es.js';
|
|
12
13
|
import '../floating-ui.react-dom-es.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
|
|
5
|
+
var useValueChanged = require('./useValueChanged-cjs.js');
|
|
6
|
+
var useRenderElement = require('./useRenderElement-cjs.js');
|
|
7
|
+
|
|
8
|
+
function _interopNamespaceDefault(e) {
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
26
|
+
|
|
27
|
+
let set;
|
|
28
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
29
|
+
set = new Set();
|
|
30
|
+
}
|
|
31
|
+
function error(...messages) {
|
|
32
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
33
|
+
const messageKey = messages.join(' ');
|
|
34
|
+
if (!set.has(messageKey)) {
|
|
35
|
+
set.add(messageKey);
|
|
36
|
+
console.error(`Base UI: ${messageKey}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const CompositeRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
42
|
+
if (process.env.NODE_ENV !== "production") CompositeRootContext.displayName = "CompositeRootContext";
|
|
43
|
+
function useCompositeRootContext(optional = false) {
|
|
44
|
+
const context = React__namespace.useContext(CompositeRootContext);
|
|
45
|
+
if (context === undefined && !optional) {
|
|
46
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>.' : useRenderElement.formatErrorMessage(16));
|
|
47
|
+
}
|
|
48
|
+
return context;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function useFocusableWhenDisabled(parameters) {
|
|
52
|
+
const {
|
|
53
|
+
focusableWhenDisabled,
|
|
54
|
+
disabled,
|
|
55
|
+
composite = false,
|
|
56
|
+
tabIndex: tabIndexProp = 0,
|
|
57
|
+
isNativeButton
|
|
58
|
+
} = parameters;
|
|
59
|
+
const isFocusableComposite = composite && focusableWhenDisabled !== false;
|
|
60
|
+
const isNonFocusableComposite = composite && focusableWhenDisabled === false;
|
|
61
|
+
|
|
62
|
+
// we can't explicitly assign `undefined` to any of these props because it
|
|
63
|
+
// would otherwise prevent subsequently merged props from setting them
|
|
64
|
+
const props = React__namespace.useMemo(() => {
|
|
65
|
+
const additionalProps = {
|
|
66
|
+
// allow Tabbing away from focusableWhenDisabled elements
|
|
67
|
+
onKeyDown(event) {
|
|
68
|
+
if (disabled && focusableWhenDisabled && event.key !== 'Tab') {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
if (!composite) {
|
|
74
|
+
additionalProps.tabIndex = tabIndexProp;
|
|
75
|
+
if (!isNativeButton && disabled) {
|
|
76
|
+
additionalProps.tabIndex = focusableWhenDisabled ? tabIndexProp : -1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (isNativeButton && (focusableWhenDisabled || isFocusableComposite) || !isNativeButton && disabled) {
|
|
80
|
+
additionalProps['aria-disabled'] = disabled;
|
|
81
|
+
}
|
|
82
|
+
if (isNativeButton && (!focusableWhenDisabled || isNonFocusableComposite)) {
|
|
83
|
+
additionalProps.disabled = disabled;
|
|
84
|
+
}
|
|
85
|
+
return additionalProps;
|
|
86
|
+
}, [composite, disabled, focusableWhenDisabled, isFocusableComposite, isNonFocusableComposite, isNativeButton, tabIndexProp]);
|
|
87
|
+
return {
|
|
88
|
+
props
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function useButton(parameters = {}) {
|
|
93
|
+
const {
|
|
94
|
+
disabled = false,
|
|
95
|
+
focusableWhenDisabled,
|
|
96
|
+
tabIndex = 0,
|
|
97
|
+
native: isNativeButton = true,
|
|
98
|
+
composite: compositeProp
|
|
99
|
+
} = parameters;
|
|
100
|
+
const elementRef = React__namespace.useRef(null);
|
|
101
|
+
const compositeRootContext = useCompositeRootContext(true);
|
|
102
|
+
const isCompositeItem = compositeProp ?? compositeRootContext !== undefined;
|
|
103
|
+
const {
|
|
104
|
+
props: focusableWhenDisabledProps
|
|
105
|
+
} = useFocusableWhenDisabled({
|
|
106
|
+
focusableWhenDisabled,
|
|
107
|
+
disabled,
|
|
108
|
+
composite: isCompositeItem,
|
|
109
|
+
tabIndex,
|
|
110
|
+
isNativeButton
|
|
111
|
+
});
|
|
112
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
113
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
114
|
+
React__namespace.useEffect(() => {
|
|
115
|
+
if (!elementRef.current) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const isButtonTag = isButtonElement(elementRef.current);
|
|
119
|
+
if (isNativeButton) {
|
|
120
|
+
if (!isButtonTag) {
|
|
121
|
+
const ownerStackMessage = useValueChanged.SafeReact.captureOwnerStack?.() || '';
|
|
122
|
+
const message = 'A component that acts as a button expected a native <button> because the ' + '`nativeButton` prop is true. Rendering a non-<button> removes native button ' + 'semantics, which can impact forms and accessibility. Use a real <button> in the ' + '`render` prop, or set `nativeButton` to `false`.';
|
|
123
|
+
error(`${message}${ownerStackMessage}`);
|
|
124
|
+
}
|
|
125
|
+
} else if (isButtonTag) {
|
|
126
|
+
const ownerStackMessage = useValueChanged.SafeReact.captureOwnerStack?.() || '';
|
|
127
|
+
const message = 'A component that acts as a button expected a non-<button> because the `nativeButton` ' + 'prop is false. Rendering a <button> keeps native behavior while Base UI applies ' + 'non-native attributes and handlers, which can add unintended extra attributes (such ' + 'as `role` or `aria-disabled`). Use a non-<button> in the `render` prop, or set ' + '`nativeButton` to `true`.';
|
|
128
|
+
error(`${message}${ownerStackMessage}`);
|
|
129
|
+
}
|
|
130
|
+
}, [isNativeButton]);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// handles a disabled composite button rendering another button, e.g.
|
|
134
|
+
// <Toolbar.Button disabled render={<Menu.Trigger />} />
|
|
135
|
+
// the `disabled` prop needs to pass through 2 `useButton`s then finally
|
|
136
|
+
// delete the `disabled` attribute from DOM
|
|
137
|
+
const updateDisabled = React__namespace.useCallback(() => {
|
|
138
|
+
const element = elementRef.current;
|
|
139
|
+
if (!isButtonElement(element)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (isCompositeItem && disabled && focusableWhenDisabledProps.disabled === undefined && element.disabled) {
|
|
143
|
+
element.disabled = false;
|
|
144
|
+
}
|
|
145
|
+
}, [disabled, focusableWhenDisabledProps.disabled, isCompositeItem]);
|
|
146
|
+
useValueChanged.useIsoLayoutEffect(updateDisabled, [updateDisabled]);
|
|
147
|
+
const getButtonProps = React__namespace.useCallback((externalProps = {}) => {
|
|
148
|
+
const {
|
|
149
|
+
onClick: externalOnClick,
|
|
150
|
+
onMouseDown: externalOnMouseDown,
|
|
151
|
+
onKeyUp: externalOnKeyUp,
|
|
152
|
+
onKeyDown: externalOnKeyDown,
|
|
153
|
+
onPointerDown: externalOnPointerDown,
|
|
154
|
+
...otherExternalProps
|
|
155
|
+
} = externalProps;
|
|
156
|
+
const type = isNativeButton ? 'button' : undefined;
|
|
157
|
+
return useRenderElement.mergeProps({
|
|
158
|
+
type,
|
|
159
|
+
onClick(event) {
|
|
160
|
+
if (disabled) {
|
|
161
|
+
event.preventDefault();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
externalOnClick?.(event);
|
|
165
|
+
},
|
|
166
|
+
onMouseDown(event) {
|
|
167
|
+
if (!disabled) {
|
|
168
|
+
externalOnMouseDown?.(event);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
onKeyDown(event) {
|
|
172
|
+
if (disabled) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
useRenderElement.makeEventPreventable(event);
|
|
176
|
+
externalOnKeyDown?.(event);
|
|
177
|
+
if (event.baseUIHandlerPrevented) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const isCurrentTarget = event.target === event.currentTarget;
|
|
181
|
+
const currentTarget = event.currentTarget;
|
|
182
|
+
const isButton = isButtonElement(currentTarget);
|
|
183
|
+
const isLink = !isNativeButton && isValidLinkElement(currentTarget);
|
|
184
|
+
const shouldClick = isCurrentTarget && (isNativeButton ? isButton : !isLink);
|
|
185
|
+
const isEnterKey = event.key === 'Enter';
|
|
186
|
+
const isSpaceKey = event.key === ' ';
|
|
187
|
+
const role = currentTarget.getAttribute('role');
|
|
188
|
+
const isTextNavigationRole = role?.startsWith('menuitem') || role === 'option' || role === 'gridcell';
|
|
189
|
+
if (isCurrentTarget && isCompositeItem && isSpaceKey) {
|
|
190
|
+
if (event.defaultPrevented && isTextNavigationRole) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
event.preventDefault();
|
|
194
|
+
if (isLink || isNativeButton && isButton) {
|
|
195
|
+
currentTarget.click();
|
|
196
|
+
event.preventBaseUIHandler();
|
|
197
|
+
} else if (shouldClick) {
|
|
198
|
+
externalOnClick?.(event);
|
|
199
|
+
event.preventBaseUIHandler();
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Keyboard accessibility for native and non-native elements.
|
|
205
|
+
if (shouldClick) {
|
|
206
|
+
if (!isNativeButton && (isSpaceKey || isEnterKey)) {
|
|
207
|
+
event.preventDefault();
|
|
208
|
+
}
|
|
209
|
+
if (!isNativeButton && isEnterKey) {
|
|
210
|
+
externalOnClick?.(event);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
onKeyUp(event) {
|
|
215
|
+
if (disabled) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed
|
|
220
|
+
// https://codesandbox.io/p/sandbox/button-keyup-preventdefault-dn7f0
|
|
221
|
+
useRenderElement.makeEventPreventable(event);
|
|
222
|
+
externalOnKeyUp?.(event);
|
|
223
|
+
if (event.target === event.currentTarget && isNativeButton && isCompositeItem && isButtonElement(event.currentTarget) && event.key === ' ') {
|
|
224
|
+
event.preventDefault();
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (event.baseUIHandlerPrevented) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Keyboard accessibility for non interactive elements
|
|
232
|
+
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === ' ') {
|
|
233
|
+
externalOnClick?.(event);
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
onPointerDown(event) {
|
|
237
|
+
if (disabled) {
|
|
238
|
+
event.preventDefault();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
externalOnPointerDown?.(event);
|
|
242
|
+
}
|
|
243
|
+
}, !isNativeButton ? {
|
|
244
|
+
role: 'button'
|
|
245
|
+
} : undefined, focusableWhenDisabledProps, otherExternalProps);
|
|
246
|
+
}, [disabled, focusableWhenDisabledProps, isCompositeItem, isNativeButton]);
|
|
247
|
+
const buttonRef = useValueChanged.useStableCallback(element => {
|
|
248
|
+
elementRef.current = element;
|
|
249
|
+
updateDisabled();
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
getButtonProps,
|
|
253
|
+
buttonRef
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function isButtonElement(elem) {
|
|
257
|
+
return floatingUi_utils_dom.isHTMLElement(elem) && elem.tagName === 'BUTTON';
|
|
258
|
+
}
|
|
259
|
+
function isValidLinkElement(elem) {
|
|
260
|
+
return Boolean(elem?.tagName === 'A' && elem?.href);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Wraps `useId` and prefixes generated `id`s with `base-ui-`
|
|
265
|
+
* @param {string | undefined} idOverride overrides the generated id when provided
|
|
266
|
+
* @returns {string | undefined}
|
|
267
|
+
*/
|
|
268
|
+
function useBaseUiId(idOverride) {
|
|
269
|
+
return useValueChanged.useId(idOverride, 'base-ui');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
exports.error = error;
|
|
273
|
+
exports.useBaseUiId = useBaseUiId;
|
|
274
|
+
exports.useButton = useButton;
|
|
275
|
+
exports.useCompositeRootContext = useCompositeRootContext;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { a as isHTMLElement } from './floating-ui.utils.dom-es.js';
|
|
3
|
+
import { S as SafeReact, u as useIsoLayoutEffect, a as useStableCallback, b as useId } from './useValueChanged-es.js';
|
|
4
|
+
import { f as formatErrorMessage, m as mergeProps, a as makeEventPreventable } from './useRenderElement-es.js';
|
|
5
|
+
|
|
6
|
+
let set;
|
|
7
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
8
|
+
set = new Set();
|
|
9
|
+
}
|
|
10
|
+
function error(...messages) {
|
|
11
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
12
|
+
const messageKey = messages.join(' ');
|
|
13
|
+
if (!set.has(messageKey)) {
|
|
14
|
+
set.add(messageKey);
|
|
15
|
+
console.error(`Base UI: ${messageKey}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const CompositeRootContext = /*#__PURE__*/React.createContext(undefined);
|
|
21
|
+
if (process.env.NODE_ENV !== "production") CompositeRootContext.displayName = "CompositeRootContext";
|
|
22
|
+
function useCompositeRootContext(optional = false) {
|
|
23
|
+
const context = React.useContext(CompositeRootContext);
|
|
24
|
+
if (context === undefined && !optional) {
|
|
25
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>.' : formatErrorMessage(16));
|
|
26
|
+
}
|
|
27
|
+
return context;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function useFocusableWhenDisabled(parameters) {
|
|
31
|
+
const {
|
|
32
|
+
focusableWhenDisabled,
|
|
33
|
+
disabled,
|
|
34
|
+
composite = false,
|
|
35
|
+
tabIndex: tabIndexProp = 0,
|
|
36
|
+
isNativeButton
|
|
37
|
+
} = parameters;
|
|
38
|
+
const isFocusableComposite = composite && focusableWhenDisabled !== false;
|
|
39
|
+
const isNonFocusableComposite = composite && focusableWhenDisabled === false;
|
|
40
|
+
|
|
41
|
+
// we can't explicitly assign `undefined` to any of these props because it
|
|
42
|
+
// would otherwise prevent subsequently merged props from setting them
|
|
43
|
+
const props = React.useMemo(() => {
|
|
44
|
+
const additionalProps = {
|
|
45
|
+
// allow Tabbing away from focusableWhenDisabled elements
|
|
46
|
+
onKeyDown(event) {
|
|
47
|
+
if (disabled && focusableWhenDisabled && event.key !== 'Tab') {
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
if (!composite) {
|
|
53
|
+
additionalProps.tabIndex = tabIndexProp;
|
|
54
|
+
if (!isNativeButton && disabled) {
|
|
55
|
+
additionalProps.tabIndex = focusableWhenDisabled ? tabIndexProp : -1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (isNativeButton && (focusableWhenDisabled || isFocusableComposite) || !isNativeButton && disabled) {
|
|
59
|
+
additionalProps['aria-disabled'] = disabled;
|
|
60
|
+
}
|
|
61
|
+
if (isNativeButton && (!focusableWhenDisabled || isNonFocusableComposite)) {
|
|
62
|
+
additionalProps.disabled = disabled;
|
|
63
|
+
}
|
|
64
|
+
return additionalProps;
|
|
65
|
+
}, [composite, disabled, focusableWhenDisabled, isFocusableComposite, isNonFocusableComposite, isNativeButton, tabIndexProp]);
|
|
66
|
+
return {
|
|
67
|
+
props
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function useButton(parameters = {}) {
|
|
72
|
+
const {
|
|
73
|
+
disabled = false,
|
|
74
|
+
focusableWhenDisabled,
|
|
75
|
+
tabIndex = 0,
|
|
76
|
+
native: isNativeButton = true,
|
|
77
|
+
composite: compositeProp
|
|
78
|
+
} = parameters;
|
|
79
|
+
const elementRef = React.useRef(null);
|
|
80
|
+
const compositeRootContext = useCompositeRootContext(true);
|
|
81
|
+
const isCompositeItem = compositeProp ?? compositeRootContext !== undefined;
|
|
82
|
+
const {
|
|
83
|
+
props: focusableWhenDisabledProps
|
|
84
|
+
} = useFocusableWhenDisabled({
|
|
85
|
+
focusableWhenDisabled,
|
|
86
|
+
disabled,
|
|
87
|
+
composite: isCompositeItem,
|
|
88
|
+
tabIndex,
|
|
89
|
+
isNativeButton
|
|
90
|
+
});
|
|
91
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
92
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
93
|
+
React.useEffect(() => {
|
|
94
|
+
if (!elementRef.current) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const isButtonTag = isButtonElement(elementRef.current);
|
|
98
|
+
if (isNativeButton) {
|
|
99
|
+
if (!isButtonTag) {
|
|
100
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
101
|
+
const message = 'A component that acts as a button expected a native <button> because the ' + '`nativeButton` prop is true. Rendering a non-<button> removes native button ' + 'semantics, which can impact forms and accessibility. Use a real <button> in the ' + '`render` prop, or set `nativeButton` to `false`.';
|
|
102
|
+
error(`${message}${ownerStackMessage}`);
|
|
103
|
+
}
|
|
104
|
+
} else if (isButtonTag) {
|
|
105
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
106
|
+
const message = 'A component that acts as a button expected a non-<button> because the `nativeButton` ' + 'prop is false. Rendering a <button> keeps native behavior while Base UI applies ' + 'non-native attributes and handlers, which can add unintended extra attributes (such ' + 'as `role` or `aria-disabled`). Use a non-<button> in the `render` prop, or set ' + '`nativeButton` to `true`.';
|
|
107
|
+
error(`${message}${ownerStackMessage}`);
|
|
108
|
+
}
|
|
109
|
+
}, [isNativeButton]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// handles a disabled composite button rendering another button, e.g.
|
|
113
|
+
// <Toolbar.Button disabled render={<Menu.Trigger />} />
|
|
114
|
+
// the `disabled` prop needs to pass through 2 `useButton`s then finally
|
|
115
|
+
// delete the `disabled` attribute from DOM
|
|
116
|
+
const updateDisabled = React.useCallback(() => {
|
|
117
|
+
const element = elementRef.current;
|
|
118
|
+
if (!isButtonElement(element)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (isCompositeItem && disabled && focusableWhenDisabledProps.disabled === undefined && element.disabled) {
|
|
122
|
+
element.disabled = false;
|
|
123
|
+
}
|
|
124
|
+
}, [disabled, focusableWhenDisabledProps.disabled, isCompositeItem]);
|
|
125
|
+
useIsoLayoutEffect(updateDisabled, [updateDisabled]);
|
|
126
|
+
const getButtonProps = React.useCallback((externalProps = {}) => {
|
|
127
|
+
const {
|
|
128
|
+
onClick: externalOnClick,
|
|
129
|
+
onMouseDown: externalOnMouseDown,
|
|
130
|
+
onKeyUp: externalOnKeyUp,
|
|
131
|
+
onKeyDown: externalOnKeyDown,
|
|
132
|
+
onPointerDown: externalOnPointerDown,
|
|
133
|
+
...otherExternalProps
|
|
134
|
+
} = externalProps;
|
|
135
|
+
const type = isNativeButton ? 'button' : undefined;
|
|
136
|
+
return mergeProps({
|
|
137
|
+
type,
|
|
138
|
+
onClick(event) {
|
|
139
|
+
if (disabled) {
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
externalOnClick?.(event);
|
|
144
|
+
},
|
|
145
|
+
onMouseDown(event) {
|
|
146
|
+
if (!disabled) {
|
|
147
|
+
externalOnMouseDown?.(event);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
onKeyDown(event) {
|
|
151
|
+
if (disabled) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
makeEventPreventable(event);
|
|
155
|
+
externalOnKeyDown?.(event);
|
|
156
|
+
if (event.baseUIHandlerPrevented) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const isCurrentTarget = event.target === event.currentTarget;
|
|
160
|
+
const currentTarget = event.currentTarget;
|
|
161
|
+
const isButton = isButtonElement(currentTarget);
|
|
162
|
+
const isLink = !isNativeButton && isValidLinkElement(currentTarget);
|
|
163
|
+
const shouldClick = isCurrentTarget && (isNativeButton ? isButton : !isLink);
|
|
164
|
+
const isEnterKey = event.key === 'Enter';
|
|
165
|
+
const isSpaceKey = event.key === ' ';
|
|
166
|
+
const role = currentTarget.getAttribute('role');
|
|
167
|
+
const isTextNavigationRole = role?.startsWith('menuitem') || role === 'option' || role === 'gridcell';
|
|
168
|
+
if (isCurrentTarget && isCompositeItem && isSpaceKey) {
|
|
169
|
+
if (event.defaultPrevented && isTextNavigationRole) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
if (isLink || isNativeButton && isButton) {
|
|
174
|
+
currentTarget.click();
|
|
175
|
+
event.preventBaseUIHandler();
|
|
176
|
+
} else if (shouldClick) {
|
|
177
|
+
externalOnClick?.(event);
|
|
178
|
+
event.preventBaseUIHandler();
|
|
179
|
+
}
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Keyboard accessibility for native and non-native elements.
|
|
184
|
+
if (shouldClick) {
|
|
185
|
+
if (!isNativeButton && (isSpaceKey || isEnterKey)) {
|
|
186
|
+
event.preventDefault();
|
|
187
|
+
}
|
|
188
|
+
if (!isNativeButton && isEnterKey) {
|
|
189
|
+
externalOnClick?.(event);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
onKeyUp(event) {
|
|
194
|
+
if (disabled) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed
|
|
199
|
+
// https://codesandbox.io/p/sandbox/button-keyup-preventdefault-dn7f0
|
|
200
|
+
makeEventPreventable(event);
|
|
201
|
+
externalOnKeyUp?.(event);
|
|
202
|
+
if (event.target === event.currentTarget && isNativeButton && isCompositeItem && isButtonElement(event.currentTarget) && event.key === ' ') {
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (event.baseUIHandlerPrevented) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Keyboard accessibility for non interactive elements
|
|
211
|
+
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === ' ') {
|
|
212
|
+
externalOnClick?.(event);
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
onPointerDown(event) {
|
|
216
|
+
if (disabled) {
|
|
217
|
+
event.preventDefault();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
externalOnPointerDown?.(event);
|
|
221
|
+
}
|
|
222
|
+
}, !isNativeButton ? {
|
|
223
|
+
role: 'button'
|
|
224
|
+
} : undefined, focusableWhenDisabledProps, otherExternalProps);
|
|
225
|
+
}, [disabled, focusableWhenDisabledProps, isCompositeItem, isNativeButton]);
|
|
226
|
+
const buttonRef = useStableCallback(element => {
|
|
227
|
+
elementRef.current = element;
|
|
228
|
+
updateDisabled();
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
getButtonProps,
|
|
232
|
+
buttonRef
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function isButtonElement(elem) {
|
|
236
|
+
return isHTMLElement(elem) && elem.tagName === 'BUTTON';
|
|
237
|
+
}
|
|
238
|
+
function isValidLinkElement(elem) {
|
|
239
|
+
return Boolean(elem?.tagName === 'A' && elem?.href);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Wraps `useId` and prefixes generated `id`s with `base-ui-`
|
|
244
|
+
* @param {string | undefined} idOverride overrides the generated id when provided
|
|
245
|
+
* @returns {string | undefined}
|
|
246
|
+
*/
|
|
247
|
+
function useBaseUiId(idOverride) {
|
|
248
|
+
return useId(idOverride, 'base-ui');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export { useButton as a, useCompositeRootContext as b, error as e, useBaseUiId as u };
|
|
@@ -566,4 +566,4 @@ function renderTag(Tag, props) {
|
|
|
566
566
|
return /*#__PURE__*/React.createElement(Tag, props);
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
-
export { EMPTY_OBJECT as E, NOOP as N,
|
|
569
|
+
export { EMPTY_OBJECT as E, NOOP as N, makeEventPreventable as a, useRefWithInit as b, useMergedRefs as c, EMPTY_ARRAY as d, formatErrorMessage as f, isReactVersionAtLeast as i, mergeProps as m, useRenderElement as u };
|