@jobber/components 8.14.1 → 8.15.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/Autocomplete-es.js +1 -1
- package/dist/BottomSheet-cjs.js +109 -77
- package/dist/BottomSheet-es.js +103 -75
- package/dist/Card/index.cjs +1 -2
- package/dist/Card/index.mjs +1 -2
- package/dist/DataDump/index.cjs +1 -2
- package/dist/DataDump/index.mjs +1 -2
- package/dist/InputNumberExperimental-cjs.js +3 -4
- package/dist/InputNumberExperimental-es.js +2 -3
- package/dist/Menu/index.cjs +1 -2
- package/dist/Menu/index.mjs +1 -2
- package/dist/Menu-cjs.js +11 -56
- package/dist/Menu-es.js +4 -49
- package/dist/MenuSubmenuTrigger-cjs.js +160 -345
- package/dist/MenuSubmenuTrigger-es.js +4 -186
- package/dist/Modal/index.mjs +1 -1
- package/dist/NumberFieldInput-cjs.js +3 -4
- package/dist/NumberFieldInput-es.js +2 -3
- package/dist/Page/index.cjs +1 -2
- package/dist/Page/index.mjs +1 -2
- package/dist/{DrawerRoot-cjs.js → ScrollAreaViewport-cjs.js} +1042 -3
- package/dist/{DrawerRoot-es.js → ScrollAreaViewport-es.js} +1035 -5
- package/dist/floating-ui.react-es.js +1 -1
- package/dist/index.cjs +1 -2
- package/dist/index.mjs +1 -2
- package/dist/primitives/BottomSheet/BottomSheet.d.ts +15 -16
- package/dist/primitives/BottomSheet/BottomSheet.types.d.ts +27 -0
- package/dist/primitives/BottomSheet/BottomSheet.utils.d.ts +6 -0
- package/dist/primitives/BottomSheet/index.cjs +7 -2
- package/dist/primitives/BottomSheet/index.d.ts +1 -0
- package/dist/primitives/BottomSheet/index.mjs +7 -2
- package/dist/primitives/InputNumberExperimental/index.cjs +1 -2
- package/dist/primitives/InputNumberExperimental/index.mjs +1 -2
- package/dist/primitives/index.cjs +7 -8
- package/dist/primitives/index.mjs +7 -8
- package/dist/styles.css +62 -1
- package/dist/unstyledPrimitives/index.cjs +665 -297
- package/dist/unstyledPrimitives/index.d.ts +1 -0
- package/dist/unstyledPrimitives/index.mjs +375 -8
- package/dist/useRenderElement-es.js +1 -1
- package/dist/useValueChanged-cjs.js +251 -1
- package/dist/useValueChanged-es.js +248 -2
- package/package.json +2 -2
- package/dist/useBaseUiId-cjs.js +0 -275
- package/dist/useBaseUiId-es.js +0 -251
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var useRenderElement = require('./useRenderElement-cjs.js');
|
|
4
3
|
var React = require('react');
|
|
4
|
+
var floatingUi_utils_dom = require('./floating-ui.utils.dom-cjs.js');
|
|
5
|
+
var useRenderElement = require('./useRenderElement-cjs.js');
|
|
5
6
|
var ReactDOM = require('react-dom');
|
|
6
7
|
|
|
7
8
|
function _interopNamespaceDefault(e) {
|
|
@@ -93,6 +94,20 @@ function assertNotCalled() {
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
let set;
|
|
98
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
99
|
+
set = new Set();
|
|
100
|
+
}
|
|
101
|
+
function error(...messages) {
|
|
102
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
103
|
+
const messageKey = messages.join(' ');
|
|
104
|
+
if (!set.has(messageKey)) {
|
|
105
|
+
set.add(messageKey);
|
|
106
|
+
console.error(`Base UI: ${messageKey}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
96
111
|
// https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
|
|
97
112
|
const SafeReact = {
|
|
98
113
|
...React__namespace
|
|
@@ -101,6 +116,228 @@ const SafeReact = {
|
|
|
101
116
|
const noop = () => {};
|
|
102
117
|
const useIsoLayoutEffect = typeof document !== 'undefined' ? React__namespace.useLayoutEffect : noop;
|
|
103
118
|
|
|
119
|
+
const CompositeRootContext = /*#__PURE__*/React__namespace.createContext(undefined);
|
|
120
|
+
if (process.env.NODE_ENV !== "production") CompositeRootContext.displayName = "CompositeRootContext";
|
|
121
|
+
function useCompositeRootContext(optional = false) {
|
|
122
|
+
const context = React__namespace.useContext(CompositeRootContext);
|
|
123
|
+
if (context === undefined && !optional) {
|
|
124
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>.' : useRenderElement.formatErrorMessage(16));
|
|
125
|
+
}
|
|
126
|
+
return context;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function useFocusableWhenDisabled(parameters) {
|
|
130
|
+
const {
|
|
131
|
+
focusableWhenDisabled,
|
|
132
|
+
disabled,
|
|
133
|
+
composite = false,
|
|
134
|
+
tabIndex: tabIndexProp = 0,
|
|
135
|
+
isNativeButton
|
|
136
|
+
} = parameters;
|
|
137
|
+
const isFocusableComposite = composite && focusableWhenDisabled !== false;
|
|
138
|
+
const isNonFocusableComposite = composite && focusableWhenDisabled === false;
|
|
139
|
+
|
|
140
|
+
// we can't explicitly assign `undefined` to any of these props because it
|
|
141
|
+
// would otherwise prevent subsequently merged props from setting them
|
|
142
|
+
const props = React__namespace.useMemo(() => {
|
|
143
|
+
const additionalProps = {
|
|
144
|
+
// allow Tabbing away from focusableWhenDisabled elements
|
|
145
|
+
onKeyDown(event) {
|
|
146
|
+
if (disabled && focusableWhenDisabled && event.key !== 'Tab') {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
if (!composite) {
|
|
152
|
+
additionalProps.tabIndex = tabIndexProp;
|
|
153
|
+
if (!isNativeButton && disabled) {
|
|
154
|
+
additionalProps.tabIndex = focusableWhenDisabled ? tabIndexProp : -1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (isNativeButton && (focusableWhenDisabled || isFocusableComposite) || !isNativeButton && disabled) {
|
|
158
|
+
additionalProps['aria-disabled'] = disabled;
|
|
159
|
+
}
|
|
160
|
+
if (isNativeButton && (!focusableWhenDisabled || isNonFocusableComposite)) {
|
|
161
|
+
additionalProps.disabled = disabled;
|
|
162
|
+
}
|
|
163
|
+
return additionalProps;
|
|
164
|
+
}, [composite, disabled, focusableWhenDisabled, isFocusableComposite, isNonFocusableComposite, isNativeButton, tabIndexProp]);
|
|
165
|
+
return {
|
|
166
|
+
props
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function useButton(parameters = {}) {
|
|
171
|
+
const {
|
|
172
|
+
disabled = false,
|
|
173
|
+
focusableWhenDisabled,
|
|
174
|
+
tabIndex = 0,
|
|
175
|
+
native: isNativeButton = true,
|
|
176
|
+
composite: compositeProp
|
|
177
|
+
} = parameters;
|
|
178
|
+
const elementRef = React__namespace.useRef(null);
|
|
179
|
+
const compositeRootContext = useCompositeRootContext(true);
|
|
180
|
+
const isCompositeItem = compositeProp ?? compositeRootContext !== undefined;
|
|
181
|
+
const {
|
|
182
|
+
props: focusableWhenDisabledProps
|
|
183
|
+
} = useFocusableWhenDisabled({
|
|
184
|
+
focusableWhenDisabled,
|
|
185
|
+
disabled,
|
|
186
|
+
composite: isCompositeItem,
|
|
187
|
+
tabIndex,
|
|
188
|
+
isNativeButton
|
|
189
|
+
});
|
|
190
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
191
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
192
|
+
React__namespace.useEffect(() => {
|
|
193
|
+
if (!elementRef.current) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const isButtonTag = isButtonElement(elementRef.current);
|
|
197
|
+
if (isNativeButton) {
|
|
198
|
+
if (!isButtonTag) {
|
|
199
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
200
|
+
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`.';
|
|
201
|
+
error(`${message}${ownerStackMessage}`);
|
|
202
|
+
}
|
|
203
|
+
} else if (isButtonTag) {
|
|
204
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
205
|
+
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`.';
|
|
206
|
+
error(`${message}${ownerStackMessage}`);
|
|
207
|
+
}
|
|
208
|
+
}, [isNativeButton]);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// handles a disabled composite button rendering another button, e.g.
|
|
212
|
+
// <Toolbar.Button disabled render={<Menu.Trigger />} />
|
|
213
|
+
// the `disabled` prop needs to pass through 2 `useButton`s then finally
|
|
214
|
+
// delete the `disabled` attribute from DOM
|
|
215
|
+
const updateDisabled = React__namespace.useCallback(() => {
|
|
216
|
+
const element = elementRef.current;
|
|
217
|
+
if (!isButtonElement(element)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (isCompositeItem && disabled && focusableWhenDisabledProps.disabled === undefined && element.disabled) {
|
|
221
|
+
element.disabled = false;
|
|
222
|
+
}
|
|
223
|
+
}, [disabled, focusableWhenDisabledProps.disabled, isCompositeItem]);
|
|
224
|
+
useIsoLayoutEffect(updateDisabled, [updateDisabled]);
|
|
225
|
+
const getButtonProps = React__namespace.useCallback((externalProps = {}) => {
|
|
226
|
+
const {
|
|
227
|
+
onClick: externalOnClick,
|
|
228
|
+
onMouseDown: externalOnMouseDown,
|
|
229
|
+
onKeyUp: externalOnKeyUp,
|
|
230
|
+
onKeyDown: externalOnKeyDown,
|
|
231
|
+
onPointerDown: externalOnPointerDown,
|
|
232
|
+
...otherExternalProps
|
|
233
|
+
} = externalProps;
|
|
234
|
+
const type = isNativeButton ? 'button' : undefined;
|
|
235
|
+
return useRenderElement.mergeProps({
|
|
236
|
+
type,
|
|
237
|
+
onClick(event) {
|
|
238
|
+
if (disabled) {
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
externalOnClick?.(event);
|
|
243
|
+
},
|
|
244
|
+
onMouseDown(event) {
|
|
245
|
+
if (!disabled) {
|
|
246
|
+
externalOnMouseDown?.(event);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
onKeyDown(event) {
|
|
250
|
+
if (disabled) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
useRenderElement.makeEventPreventable(event);
|
|
254
|
+
externalOnKeyDown?.(event);
|
|
255
|
+
if (event.baseUIHandlerPrevented) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const isCurrentTarget = event.target === event.currentTarget;
|
|
259
|
+
const currentTarget = event.currentTarget;
|
|
260
|
+
const isButton = isButtonElement(currentTarget);
|
|
261
|
+
const isLink = !isNativeButton && isValidLinkElement(currentTarget);
|
|
262
|
+
const shouldClick = isCurrentTarget && (isNativeButton ? isButton : !isLink);
|
|
263
|
+
const isEnterKey = event.key === 'Enter';
|
|
264
|
+
const isSpaceKey = event.key === ' ';
|
|
265
|
+
const role = currentTarget.getAttribute('role');
|
|
266
|
+
const isTextNavigationRole = role?.startsWith('menuitem') || role === 'option' || role === 'gridcell';
|
|
267
|
+
if (isCurrentTarget && isCompositeItem && isSpaceKey) {
|
|
268
|
+
if (event.defaultPrevented && isTextNavigationRole) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
event.preventDefault();
|
|
272
|
+
if (isLink || isNativeButton && isButton) {
|
|
273
|
+
currentTarget.click();
|
|
274
|
+
event.preventBaseUIHandler();
|
|
275
|
+
} else if (shouldClick) {
|
|
276
|
+
externalOnClick?.(event);
|
|
277
|
+
event.preventBaseUIHandler();
|
|
278
|
+
}
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Keyboard accessibility for native and non-native elements.
|
|
283
|
+
if (shouldClick) {
|
|
284
|
+
if (!isNativeButton && (isSpaceKey || isEnterKey)) {
|
|
285
|
+
event.preventDefault();
|
|
286
|
+
}
|
|
287
|
+
if (!isNativeButton && isEnterKey) {
|
|
288
|
+
externalOnClick?.(event);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
onKeyUp(event) {
|
|
293
|
+
if (disabled) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed
|
|
298
|
+
// https://codesandbox.io/p/sandbox/button-keyup-preventdefault-dn7f0
|
|
299
|
+
useRenderElement.makeEventPreventable(event);
|
|
300
|
+
externalOnKeyUp?.(event);
|
|
301
|
+
if (event.target === event.currentTarget && isNativeButton && isCompositeItem && isButtonElement(event.currentTarget) && event.key === ' ') {
|
|
302
|
+
event.preventDefault();
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (event.baseUIHandlerPrevented) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Keyboard accessibility for non interactive elements
|
|
310
|
+
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === ' ') {
|
|
311
|
+
externalOnClick?.(event);
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
onPointerDown(event) {
|
|
315
|
+
if (disabled) {
|
|
316
|
+
event.preventDefault();
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
externalOnPointerDown?.(event);
|
|
320
|
+
}
|
|
321
|
+
}, !isNativeButton ? {
|
|
322
|
+
role: 'button'
|
|
323
|
+
} : undefined, focusableWhenDisabledProps, otherExternalProps);
|
|
324
|
+
}, [disabled, focusableWhenDisabledProps, isCompositeItem, isNativeButton]);
|
|
325
|
+
const buttonRef = useStableCallback(element => {
|
|
326
|
+
elementRef.current = element;
|
|
327
|
+
updateDisabled();
|
|
328
|
+
});
|
|
329
|
+
return {
|
|
330
|
+
getButtonProps,
|
|
331
|
+
buttonRef
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function isButtonElement(elem) {
|
|
335
|
+
return floatingUi_utils_dom.isHTMLElement(elem) && elem.tagName === 'BUTTON';
|
|
336
|
+
}
|
|
337
|
+
function isValidLinkElement(elem) {
|
|
338
|
+
return Boolean(elem?.tagName === 'A' && elem?.href);
|
|
339
|
+
}
|
|
340
|
+
|
|
104
341
|
const none = 'none';
|
|
105
342
|
const triggerPress = 'trigger-press';
|
|
106
343
|
const triggerHover = 'trigger-hover';
|
|
@@ -216,6 +453,15 @@ function useId(idOverride, prefix) {
|
|
|
216
453
|
return useGlobalId(idOverride, prefix);
|
|
217
454
|
}
|
|
218
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Wraps `useId` and prefixes generated `id`s with `base-ui-`
|
|
458
|
+
* @param {string | undefined} idOverride overrides the generated id when provided
|
|
459
|
+
* @returns {string | undefined}
|
|
460
|
+
*/
|
|
461
|
+
function useBaseUiId(idOverride) {
|
|
462
|
+
return useId(idOverride, 'base-ui');
|
|
463
|
+
}
|
|
464
|
+
|
|
219
465
|
const EMPTY$2 = [];
|
|
220
466
|
|
|
221
467
|
/**
|
|
@@ -768,6 +1014,7 @@ exports.closeWatcher = closeWatcher;
|
|
|
768
1014
|
exports.createChangeEventDetails = createChangeEventDetails;
|
|
769
1015
|
exports.createGenericEventDetails = createGenericEventDetails;
|
|
770
1016
|
exports.decrementPress = decrementPress;
|
|
1017
|
+
exports.error = error;
|
|
771
1018
|
exports.escapeKey = escapeKey;
|
|
772
1019
|
exports.focusOut = focusOut;
|
|
773
1020
|
exports.imperativeAction = imperativeAction;
|
|
@@ -806,6 +1053,9 @@ exports.triggerHover = triggerHover;
|
|
|
806
1053
|
exports.triggerPress = triggerPress;
|
|
807
1054
|
exports.useAnimationFrame = useAnimationFrame;
|
|
808
1055
|
exports.useAnimationsFinished = useAnimationsFinished;
|
|
1056
|
+
exports.useBaseUiId = useBaseUiId;
|
|
1057
|
+
exports.useButton = useButton;
|
|
1058
|
+
exports.useCompositeRootContext = useCompositeRootContext;
|
|
809
1059
|
exports.useControlled = useControlled;
|
|
810
1060
|
exports.useId = useId;
|
|
811
1061
|
exports.useIsoLayoutEffect = useIsoLayoutEffect;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { b as useRefWithInit, E as EMPTY_OBJECT } from './useRenderElement-es.js';
|
|
2
1
|
import * as React from 'react';
|
|
2
|
+
import { a as isHTMLElement } from './floating-ui.utils.dom-es.js';
|
|
3
|
+
import { a as useRefWithInit, f as formatErrorMessage, m as mergeProps, c as makeEventPreventable, E as EMPTY_OBJECT } from './useRenderElement-es.js';
|
|
3
4
|
import * as ReactDOM from 'react-dom';
|
|
4
5
|
|
|
5
6
|
let TransitionStatusDataAttributes = /*#__PURE__*/function (TransitionStatusDataAttributes) {
|
|
@@ -71,6 +72,20 @@ function assertNotCalled() {
|
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
let set;
|
|
76
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
77
|
+
set = new Set();
|
|
78
|
+
}
|
|
79
|
+
function error(...messages) {
|
|
80
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
81
|
+
const messageKey = messages.join(' ');
|
|
82
|
+
if (!set.has(messageKey)) {
|
|
83
|
+
set.add(messageKey);
|
|
84
|
+
console.error(`Base UI: ${messageKey}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
// https://github.com/mui/material-ui/issues/41190#issuecomment-2040873379
|
|
75
90
|
const SafeReact = {
|
|
76
91
|
...React
|
|
@@ -79,6 +94,228 @@ const SafeReact = {
|
|
|
79
94
|
const noop = () => {};
|
|
80
95
|
const useIsoLayoutEffect = typeof document !== 'undefined' ? React.useLayoutEffect : noop;
|
|
81
96
|
|
|
97
|
+
const CompositeRootContext = /*#__PURE__*/React.createContext(undefined);
|
|
98
|
+
if (process.env.NODE_ENV !== "production") CompositeRootContext.displayName = "CompositeRootContext";
|
|
99
|
+
function useCompositeRootContext(optional = false) {
|
|
100
|
+
const context = React.useContext(CompositeRootContext);
|
|
101
|
+
if (context === undefined && !optional) {
|
|
102
|
+
throw new Error(process.env.NODE_ENV !== "production" ? 'Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>.' : formatErrorMessage(16));
|
|
103
|
+
}
|
|
104
|
+
return context;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function useFocusableWhenDisabled(parameters) {
|
|
108
|
+
const {
|
|
109
|
+
focusableWhenDisabled,
|
|
110
|
+
disabled,
|
|
111
|
+
composite = false,
|
|
112
|
+
tabIndex: tabIndexProp = 0,
|
|
113
|
+
isNativeButton
|
|
114
|
+
} = parameters;
|
|
115
|
+
const isFocusableComposite = composite && focusableWhenDisabled !== false;
|
|
116
|
+
const isNonFocusableComposite = composite && focusableWhenDisabled === false;
|
|
117
|
+
|
|
118
|
+
// we can't explicitly assign `undefined` to any of these props because it
|
|
119
|
+
// would otherwise prevent subsequently merged props from setting them
|
|
120
|
+
const props = React.useMemo(() => {
|
|
121
|
+
const additionalProps = {
|
|
122
|
+
// allow Tabbing away from focusableWhenDisabled elements
|
|
123
|
+
onKeyDown(event) {
|
|
124
|
+
if (disabled && focusableWhenDisabled && event.key !== 'Tab') {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
if (!composite) {
|
|
130
|
+
additionalProps.tabIndex = tabIndexProp;
|
|
131
|
+
if (!isNativeButton && disabled) {
|
|
132
|
+
additionalProps.tabIndex = focusableWhenDisabled ? tabIndexProp : -1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (isNativeButton && (focusableWhenDisabled || isFocusableComposite) || !isNativeButton && disabled) {
|
|
136
|
+
additionalProps['aria-disabled'] = disabled;
|
|
137
|
+
}
|
|
138
|
+
if (isNativeButton && (!focusableWhenDisabled || isNonFocusableComposite)) {
|
|
139
|
+
additionalProps.disabled = disabled;
|
|
140
|
+
}
|
|
141
|
+
return additionalProps;
|
|
142
|
+
}, [composite, disabled, focusableWhenDisabled, isFocusableComposite, isNonFocusableComposite, isNativeButton, tabIndexProp]);
|
|
143
|
+
return {
|
|
144
|
+
props
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function useButton(parameters = {}) {
|
|
149
|
+
const {
|
|
150
|
+
disabled = false,
|
|
151
|
+
focusableWhenDisabled,
|
|
152
|
+
tabIndex = 0,
|
|
153
|
+
native: isNativeButton = true,
|
|
154
|
+
composite: compositeProp
|
|
155
|
+
} = parameters;
|
|
156
|
+
const elementRef = React.useRef(null);
|
|
157
|
+
const compositeRootContext = useCompositeRootContext(true);
|
|
158
|
+
const isCompositeItem = compositeProp ?? compositeRootContext !== undefined;
|
|
159
|
+
const {
|
|
160
|
+
props: focusableWhenDisabledProps
|
|
161
|
+
} = useFocusableWhenDisabled({
|
|
162
|
+
focusableWhenDisabled,
|
|
163
|
+
disabled,
|
|
164
|
+
composite: isCompositeItem,
|
|
165
|
+
tabIndex,
|
|
166
|
+
isNativeButton
|
|
167
|
+
});
|
|
168
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
169
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
170
|
+
React.useEffect(() => {
|
|
171
|
+
if (!elementRef.current) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const isButtonTag = isButtonElement(elementRef.current);
|
|
175
|
+
if (isNativeButton) {
|
|
176
|
+
if (!isButtonTag) {
|
|
177
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
178
|
+
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`.';
|
|
179
|
+
error(`${message}${ownerStackMessage}`);
|
|
180
|
+
}
|
|
181
|
+
} else if (isButtonTag) {
|
|
182
|
+
const ownerStackMessage = SafeReact.captureOwnerStack?.() || '';
|
|
183
|
+
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`.';
|
|
184
|
+
error(`${message}${ownerStackMessage}`);
|
|
185
|
+
}
|
|
186
|
+
}, [isNativeButton]);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// handles a disabled composite button rendering another button, e.g.
|
|
190
|
+
// <Toolbar.Button disabled render={<Menu.Trigger />} />
|
|
191
|
+
// the `disabled` prop needs to pass through 2 `useButton`s then finally
|
|
192
|
+
// delete the `disabled` attribute from DOM
|
|
193
|
+
const updateDisabled = React.useCallback(() => {
|
|
194
|
+
const element = elementRef.current;
|
|
195
|
+
if (!isButtonElement(element)) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (isCompositeItem && disabled && focusableWhenDisabledProps.disabled === undefined && element.disabled) {
|
|
199
|
+
element.disabled = false;
|
|
200
|
+
}
|
|
201
|
+
}, [disabled, focusableWhenDisabledProps.disabled, isCompositeItem]);
|
|
202
|
+
useIsoLayoutEffect(updateDisabled, [updateDisabled]);
|
|
203
|
+
const getButtonProps = React.useCallback((externalProps = {}) => {
|
|
204
|
+
const {
|
|
205
|
+
onClick: externalOnClick,
|
|
206
|
+
onMouseDown: externalOnMouseDown,
|
|
207
|
+
onKeyUp: externalOnKeyUp,
|
|
208
|
+
onKeyDown: externalOnKeyDown,
|
|
209
|
+
onPointerDown: externalOnPointerDown,
|
|
210
|
+
...otherExternalProps
|
|
211
|
+
} = externalProps;
|
|
212
|
+
const type = isNativeButton ? 'button' : undefined;
|
|
213
|
+
return mergeProps({
|
|
214
|
+
type,
|
|
215
|
+
onClick(event) {
|
|
216
|
+
if (disabled) {
|
|
217
|
+
event.preventDefault();
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
externalOnClick?.(event);
|
|
221
|
+
},
|
|
222
|
+
onMouseDown(event) {
|
|
223
|
+
if (!disabled) {
|
|
224
|
+
externalOnMouseDown?.(event);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
onKeyDown(event) {
|
|
228
|
+
if (disabled) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
makeEventPreventable(event);
|
|
232
|
+
externalOnKeyDown?.(event);
|
|
233
|
+
if (event.baseUIHandlerPrevented) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const isCurrentTarget = event.target === event.currentTarget;
|
|
237
|
+
const currentTarget = event.currentTarget;
|
|
238
|
+
const isButton = isButtonElement(currentTarget);
|
|
239
|
+
const isLink = !isNativeButton && isValidLinkElement(currentTarget);
|
|
240
|
+
const shouldClick = isCurrentTarget && (isNativeButton ? isButton : !isLink);
|
|
241
|
+
const isEnterKey = event.key === 'Enter';
|
|
242
|
+
const isSpaceKey = event.key === ' ';
|
|
243
|
+
const role = currentTarget.getAttribute('role');
|
|
244
|
+
const isTextNavigationRole = role?.startsWith('menuitem') || role === 'option' || role === 'gridcell';
|
|
245
|
+
if (isCurrentTarget && isCompositeItem && isSpaceKey) {
|
|
246
|
+
if (event.defaultPrevented && isTextNavigationRole) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
if (isLink || isNativeButton && isButton) {
|
|
251
|
+
currentTarget.click();
|
|
252
|
+
event.preventBaseUIHandler();
|
|
253
|
+
} else if (shouldClick) {
|
|
254
|
+
externalOnClick?.(event);
|
|
255
|
+
event.preventBaseUIHandler();
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Keyboard accessibility for native and non-native elements.
|
|
261
|
+
if (shouldClick) {
|
|
262
|
+
if (!isNativeButton && (isSpaceKey || isEnterKey)) {
|
|
263
|
+
event.preventDefault();
|
|
264
|
+
}
|
|
265
|
+
if (!isNativeButton && isEnterKey) {
|
|
266
|
+
externalOnClick?.(event);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
onKeyUp(event) {
|
|
271
|
+
if (disabled) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed
|
|
276
|
+
// https://codesandbox.io/p/sandbox/button-keyup-preventdefault-dn7f0
|
|
277
|
+
makeEventPreventable(event);
|
|
278
|
+
externalOnKeyUp?.(event);
|
|
279
|
+
if (event.target === event.currentTarget && isNativeButton && isCompositeItem && isButtonElement(event.currentTarget) && event.key === ' ') {
|
|
280
|
+
event.preventDefault();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (event.baseUIHandlerPrevented) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Keyboard accessibility for non interactive elements
|
|
288
|
+
if (event.target === event.currentTarget && !isNativeButton && !isCompositeItem && event.key === ' ') {
|
|
289
|
+
externalOnClick?.(event);
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
onPointerDown(event) {
|
|
293
|
+
if (disabled) {
|
|
294
|
+
event.preventDefault();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
externalOnPointerDown?.(event);
|
|
298
|
+
}
|
|
299
|
+
}, !isNativeButton ? {
|
|
300
|
+
role: 'button'
|
|
301
|
+
} : undefined, focusableWhenDisabledProps, otherExternalProps);
|
|
302
|
+
}, [disabled, focusableWhenDisabledProps, isCompositeItem, isNativeButton]);
|
|
303
|
+
const buttonRef = useStableCallback(element => {
|
|
304
|
+
elementRef.current = element;
|
|
305
|
+
updateDisabled();
|
|
306
|
+
});
|
|
307
|
+
return {
|
|
308
|
+
getButtonProps,
|
|
309
|
+
buttonRef
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function isButtonElement(elem) {
|
|
313
|
+
return isHTMLElement(elem) && elem.tagName === 'BUTTON';
|
|
314
|
+
}
|
|
315
|
+
function isValidLinkElement(elem) {
|
|
316
|
+
return Boolean(elem?.tagName === 'A' && elem?.href);
|
|
317
|
+
}
|
|
318
|
+
|
|
82
319
|
const none = 'none';
|
|
83
320
|
const triggerPress = 'trigger-press';
|
|
84
321
|
const triggerHover = 'trigger-hover';
|
|
@@ -194,6 +431,15 @@ function useId(idOverride, prefix) {
|
|
|
194
431
|
return useGlobalId(idOverride, prefix);
|
|
195
432
|
}
|
|
196
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Wraps `useId` and prefixes generated `id`s with `base-ui-`
|
|
436
|
+
* @param {string | undefined} idOverride overrides the generated id when provided
|
|
437
|
+
* @returns {string | undefined}
|
|
438
|
+
*/
|
|
439
|
+
function useBaseUiId(idOverride) {
|
|
440
|
+
return useId(idOverride, 'base-ui');
|
|
441
|
+
}
|
|
442
|
+
|
|
197
443
|
const EMPTY$2 = [];
|
|
198
444
|
|
|
199
445
|
/**
|
|
@@ -733,4 +979,4 @@ function useValueChanged(value, onChange) {
|
|
|
733
979
|
}, [value]);
|
|
734
980
|
}
|
|
735
981
|
|
|
736
|
-
export {
|
|
982
|
+
export { isWebKit as $, stopEvent as A, keyboard as B, closePress as C, isMouseLikePointerType as D, useId as E, triggerFocus as F, isMac as G, isSafari as H, triggerPress as I, escapeKey as J, triggerHover as K, listNavigation as L, focusOut as M, isVirtualClick as N, isVirtualPointerEvent as O, itemPress as P, outsidePress as Q, useAnimationsFinished as R, siblingOpen as S, Timeout as T, imperativeAction as U, useCompositeRootContext as V, cancelOpen as W, TransitionStatusDataAttributes as X, isJSDOM as Y, useAnimationFrame as Z, resolveRef as _, useStableCallback as a, isClickLikeEvent as a0, isReactEvent as a1, AnimationFrame as a2, isAndroid as a3, closeWatcher as a4, swipe as a5, inputPress as a6, isFirefox as a7, clearPress as a8, SafeReact as a9, error as aa, chipRemovePress as ab, scrub as ac, useTimeout as b, useTransitionStatus as c, useIsoLayoutEffect as d, useOpenChangeComplete as e, useOnMount as f, clamp as g, useControlled as h, useValueAsRef as i, isIOS as j, createChangeEventDetails as k, visuallyHidden as l, inputChange as m, none as n, inputClear as o, inputBlur as p, inputPaste as q, createGenericEventDetails as r, ownerDocument as s, transitionStatusMapping as t, useBaseUiId as u, visuallyHiddenInput as v, incrementPress as w, decrementPress as x, useButton as y, useValueChanged as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.15.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -546,5 +546,5 @@
|
|
|
546
546
|
"> 1%",
|
|
547
547
|
"IE 10"
|
|
548
548
|
],
|
|
549
|
-
"gitHead": "
|
|
549
|
+
"gitHead": "5de9b8345618fdfbfcbef4b288fb67d302242104"
|
|
550
550
|
}
|