@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.
Files changed (45) hide show
  1. package/dist/Autocomplete-es.js +1 -1
  2. package/dist/BottomSheet-cjs.js +109 -77
  3. package/dist/BottomSheet-es.js +103 -75
  4. package/dist/Card/index.cjs +1 -2
  5. package/dist/Card/index.mjs +1 -2
  6. package/dist/DataDump/index.cjs +1 -2
  7. package/dist/DataDump/index.mjs +1 -2
  8. package/dist/InputNumberExperimental-cjs.js +3 -4
  9. package/dist/InputNumberExperimental-es.js +2 -3
  10. package/dist/Menu/index.cjs +1 -2
  11. package/dist/Menu/index.mjs +1 -2
  12. package/dist/Menu-cjs.js +11 -56
  13. package/dist/Menu-es.js +4 -49
  14. package/dist/MenuSubmenuTrigger-cjs.js +160 -345
  15. package/dist/MenuSubmenuTrigger-es.js +4 -186
  16. package/dist/Modal/index.mjs +1 -1
  17. package/dist/NumberFieldInput-cjs.js +3 -4
  18. package/dist/NumberFieldInput-es.js +2 -3
  19. package/dist/Page/index.cjs +1 -2
  20. package/dist/Page/index.mjs +1 -2
  21. package/dist/{DrawerRoot-cjs.js → ScrollAreaViewport-cjs.js} +1042 -3
  22. package/dist/{DrawerRoot-es.js → ScrollAreaViewport-es.js} +1035 -5
  23. package/dist/floating-ui.react-es.js +1 -1
  24. package/dist/index.cjs +1 -2
  25. package/dist/index.mjs +1 -2
  26. package/dist/primitives/BottomSheet/BottomSheet.d.ts +15 -16
  27. package/dist/primitives/BottomSheet/BottomSheet.types.d.ts +27 -0
  28. package/dist/primitives/BottomSheet/BottomSheet.utils.d.ts +6 -0
  29. package/dist/primitives/BottomSheet/index.cjs +7 -2
  30. package/dist/primitives/BottomSheet/index.d.ts +1 -0
  31. package/dist/primitives/BottomSheet/index.mjs +7 -2
  32. package/dist/primitives/InputNumberExperimental/index.cjs +1 -2
  33. package/dist/primitives/InputNumberExperimental/index.mjs +1 -2
  34. package/dist/primitives/index.cjs +7 -8
  35. package/dist/primitives/index.mjs +7 -8
  36. package/dist/styles.css +62 -1
  37. package/dist/unstyledPrimitives/index.cjs +665 -297
  38. package/dist/unstyledPrimitives/index.d.ts +1 -0
  39. package/dist/unstyledPrimitives/index.mjs +375 -8
  40. package/dist/useRenderElement-es.js +1 -1
  41. package/dist/useValueChanged-cjs.js +251 -1
  42. package/dist/useValueChanged-es.js +248 -2
  43. package/package.json +2 -2
  44. package/dist/useBaseUiId-cjs.js +0 -275
  45. 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 { isReactEvent as $, keyboard as A, closePress as B, isMouseLikePointerType as C, useAnimationFrame as D, isClickLikeEvent as E, triggerPress as F, triggerFocus as G, isMac as H, isSafari 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, SafeReact as S, Timeout as T, siblingOpen as U, imperativeAction as V, cancelOpen as W, TransitionStatusDataAttributes as X, isJSDOM as Y, resolveRef as Z, isWebKit as _, useStableCallback as a, AnimationFrame as a0, isAndroid as a1, closeWatcher as a2, swipe as a3, inputPress as a4, isFirefox as a5, clearPress as a6, chipRemovePress as a7, scrub as a8, useId as b, useTimeout as c, useTransitionStatus 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, useIsoLayoutEffect as u, visuallyHiddenInput as v, incrementPress as w, decrementPress as x, useValueChanged as y, stopEvent as z };
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.14.1",
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": "b4ef91d6d0c0e2d1eb3253577b34fbc97a00422f"
549
+ "gitHead": "5de9b8345618fdfbfcbef4b288fb67d302242104"
550
550
  }