@jobber/components 6.80.0 → 6.81.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 (40) hide show
  1. package/dist/Autocomplete/constants.d.ts +0 -1
  2. package/dist/Autocomplete/index.cjs +2 -1
  3. package/dist/Autocomplete/index.mjs +2 -1
  4. package/dist/Autocomplete-cjs.js +5 -7
  5. package/dist/Autocomplete-es.js +5 -7
  6. package/dist/Card/index.cjs +1 -1
  7. package/dist/Card/index.mjs +1 -1
  8. package/dist/Chips/InternalChipDismissible/hooks/index.cjs +1 -0
  9. package/dist/Chips/InternalChipDismissible/hooks/index.mjs +1 -0
  10. package/dist/Chips/InternalChipDismissible/index.cjs +1 -0
  11. package/dist/Chips/InternalChipDismissible/index.mjs +1 -0
  12. package/dist/Chips/index.cjs +1 -0
  13. package/dist/Chips/index.mjs +1 -0
  14. package/dist/Combobox/hooks/useComboboxAccessibility.d.ts +2 -2
  15. package/dist/ComboboxContent-cjs.js +11 -15
  16. package/dist/ComboboxContent-es.js +12 -16
  17. package/dist/DataDump/index.cjs +1 -1
  18. package/dist/DataDump/index.mjs +1 -1
  19. package/dist/Menu/index.cjs +1 -1
  20. package/dist/Menu/index.mjs +1 -1
  21. package/dist/Menu-cjs.js +10 -16
  22. package/dist/Menu-es.js +10 -16
  23. package/dist/Modal/index.mjs +1 -1
  24. package/dist/Page/index.cjs +1 -1
  25. package/dist/Page/index.mjs +1 -1
  26. package/dist/Popover/PopoverContext.d.ts +2 -2
  27. package/dist/Popover/index.cjs +1 -1
  28. package/dist/Popover/index.mjs +1 -1
  29. package/dist/Popover/usePopover.d.ts +3 -6
  30. package/dist/Popover-cjs.js +17 -17
  31. package/dist/Popover-es.js +18 -18
  32. package/dist/floating-ui.react-es.js +1 -1
  33. package/dist/index.cjs +2 -1
  34. package/dist/index.mjs +2 -1
  35. package/dist/maxHeight-cjs.js +24 -0
  36. package/dist/maxHeight-es.js +22 -0
  37. package/dist/useScrollToActive-cjs.js +5 -2
  38. package/dist/useScrollToActive-es.js +5 -2
  39. package/dist/utils/maxHeight.d.ts +23 -0
  40. package/package.json +2 -2
@@ -1,2 +1 @@
1
1
  export declare const AUTOCOMPLETE_MAX_HEIGHT = 300;
2
- export declare const AUTCOMPLETE_MIN_HEIGHT = 100;
@@ -9,11 +9,12 @@ require('../useIsMounted-cjs.js');
9
9
  require('../useSafeLayoutEffect-cjs.js');
10
10
  require('../floating-ui.react-cjs.js');
11
11
  require('react-dom');
12
+ require('../maxHeight-cjs.js');
13
+ require('@jobber/design');
12
14
  require('../Heading-cjs.js');
13
15
  require('../Typography-cjs.js');
14
16
  require('../Text-cjs.js');
15
17
  require('../Icon-cjs.js');
16
- require('@jobber/design');
17
18
  require('../useOnKeyDown-cjs.js');
18
19
  require('../InputText/index.cjs');
19
20
  require('../FormField-cjs.js');
@@ -7,11 +7,12 @@ import '../useIsMounted-es.js';
7
7
  import '../useSafeLayoutEffect-es.js';
8
8
  import '../floating-ui.react-es.js';
9
9
  import 'react-dom';
10
+ import '../maxHeight-es.js';
11
+ import '@jobber/design';
10
12
  import '../Heading-es.js';
11
13
  import '../Typography-es.js';
12
14
  import '../Text-es.js';
13
15
  import '../Icon-es.js';
14
- import '@jobber/design';
15
16
  import '../useOnKeyDown-es.js';
16
17
  import '../InputText/index.mjs';
17
18
  import '../FormField-es.js';
@@ -7,6 +7,7 @@ var classnames = require('classnames');
7
7
  var useIsMounted = require('./useIsMounted-cjs.js');
8
8
  var floatingUi_react = require('./floating-ui.react-cjs.js');
9
9
  var useSafeLayoutEffect = require('./useSafeLayoutEffect-cjs.js');
10
+ var maxHeight = require('./maxHeight-cjs.js');
10
11
  var Heading = require('./Heading-cjs.js');
11
12
  var Text = require('./Text-cjs.js');
12
13
  var Icon = require('./Icon-cjs.js');
@@ -17,7 +18,6 @@ var FormField = require('./FormField-cjs.js');
17
18
  var styles = {"autocomplete":"_7mObJiwfPh4-","options":"dL5JShAJlKM-","heading":"PWZL-94hH7k-","visible":"_2RzcnTdaPyc-","option":"y9zhi8Wr8QA-","active":"_3Xg49dtL1Q8-","separator":"LIeh390F3W8-","icon":"K2phy6IC3TY-","text":"a6-LbUm5WnY-","label":"tQNbuxcE9nU-","details":"qacStG9-XbE-","spinning":"P9cQDL4MZ-s-"};
18
19
 
19
20
  const AUTOCOMPLETE_MAX_HEIGHT = 300;
20
- const AUTCOMPLETE_MIN_HEIGHT = 100;
21
21
 
22
22
  function useRepositionMenu(attachTo, visible, cssManagedVisibility) {
23
23
  const { refs, floatingStyles, update } = floatingUi_react.useFloating(Object.assign({ placement: "bottom", middleware: [
@@ -25,13 +25,11 @@ function useRepositionMenu(attachTo, visible, cssManagedVisibility) {
25
25
  floatingUi_react.flip({ fallbackPlacements: ["top"] }),
26
26
  floatingUi_react.size({
27
27
  apply({ availableHeight, elements }) {
28
- // Limit the height for a true maximum
29
- // However if we have less space than that, then reduce it to allow scrolling
30
- const maxHeight = availableHeight > AUTOCOMPLETE_MAX_HEIGHT
31
- ? AUTOCOMPLETE_MAX_HEIGHT
32
- : Math.max(AUTCOMPLETE_MIN_HEIGHT, availableHeight);
28
+ const maxHeight$1 = maxHeight.calculateMaxHeight(availableHeight, {
29
+ maxHeight: AUTOCOMPLETE_MAX_HEIGHT,
30
+ });
33
31
  Object.assign(elements.floating.style, {
34
- maxHeight: `${maxHeight}px`,
32
+ maxHeight: `${maxHeight$1}px`,
35
33
  });
36
34
  },
37
35
  }),
@@ -3,8 +3,9 @@ import React__default, { useCallback, useEffect, useState, forwardRef, useMemo,
3
3
  import { u as useDebounce_2 } from './useDebounce-es.js';
4
4
  import classnames from 'classnames';
5
5
  import { u as useIsMounted_2 } from './useIsMounted-es.js';
6
- import { u as useFloating, o as offset, f as flip, c as size, b as autoUpdate, F as FloatingPortal } from './floating-ui.react-es.js';
6
+ import { u as useFloating, o as offset, f as flip, e as size, b as autoUpdate, F as FloatingPortal } from './floating-ui.react-es.js';
7
7
  import { u as useSafeLayoutEffect_1 } from './useSafeLayoutEffect-es.js';
8
+ import { c as calculateMaxHeight } from './maxHeight-es.js';
8
9
  import { H as Heading } from './Heading-es.js';
9
10
  import { T as Text } from './Text-es.js';
10
11
  import { I as Icon } from './Icon-es.js';
@@ -15,7 +16,6 @@ import { m as mergeRefs } from './FormField-es.js';
15
16
  var styles = {"autocomplete":"_7mObJiwfPh4-","options":"dL5JShAJlKM-","heading":"PWZL-94hH7k-","visible":"_2RzcnTdaPyc-","option":"y9zhi8Wr8QA-","active":"_3Xg49dtL1Q8-","separator":"LIeh390F3W8-","icon":"K2phy6IC3TY-","text":"a6-LbUm5WnY-","label":"tQNbuxcE9nU-","details":"qacStG9-XbE-","spinning":"P9cQDL4MZ-s-"};
16
17
 
17
18
  const AUTOCOMPLETE_MAX_HEIGHT = 300;
18
- const AUTCOMPLETE_MIN_HEIGHT = 100;
19
19
 
20
20
  function useRepositionMenu(attachTo, visible, cssManagedVisibility) {
21
21
  const { refs, floatingStyles, update } = useFloating(Object.assign({ placement: "bottom", middleware: [
@@ -23,11 +23,9 @@ function useRepositionMenu(attachTo, visible, cssManagedVisibility) {
23
23
  flip({ fallbackPlacements: ["top"] }),
24
24
  size({
25
25
  apply({ availableHeight, elements }) {
26
- // Limit the height for a true maximum
27
- // However if we have less space than that, then reduce it to allow scrolling
28
- const maxHeight = availableHeight > AUTOCOMPLETE_MAX_HEIGHT
29
- ? AUTOCOMPLETE_MAX_HEIGHT
30
- : Math.max(AUTCOMPLETE_MIN_HEIGHT, availableHeight);
26
+ const maxHeight = calculateMaxHeight(availableHeight, {
27
+ maxHeight: AUTOCOMPLETE_MAX_HEIGHT,
28
+ });
31
29
  Object.assign(elements.floating.style, {
32
30
  maxHeight: `${maxHeight}px`,
33
31
  });
@@ -12,7 +12,6 @@ require('../Icon-cjs.js');
12
12
  require('@jobber/design');
13
13
  require('../Menu-cjs.js');
14
14
  require('framer-motion');
15
- require('../useOnKeyDown-cjs.js');
16
15
  require('../useRefocusOnActivator-cjs.js');
17
16
  require('../floating-ui.react-cjs.js');
18
17
  require('react-dom');
@@ -20,6 +19,7 @@ require('../useFocusTrap-cjs.js');
20
19
  require('../useIsMounted-cjs.js');
21
20
  require('../useSafeLayoutEffect-cjs.js');
22
21
  require('../useFormFieldFocus-cjs.js');
22
+ require('../maxHeight-cjs.js');
23
23
 
24
24
 
25
25
 
@@ -10,7 +10,6 @@ import '../Icon-es.js';
10
10
  import '@jobber/design';
11
11
  import '../Menu-es.js';
12
12
  import 'framer-motion';
13
- import '../useOnKeyDown-es.js';
14
13
  import '../useRefocusOnActivator-es.js';
15
14
  import '../floating-ui.react-es.js';
16
15
  import 'react-dom';
@@ -18,3 +17,4 @@ import '../useFocusTrap-es.js';
18
17
  import '../useIsMounted-es.js';
19
18
  import '../useSafeLayoutEffect-es.js';
20
19
  import '../useFormFieldFocus-es.js';
20
+ import '../maxHeight-es.js';
@@ -19,6 +19,7 @@ require('../../../Icon-cjs.js');
19
19
  require('@jobber/design');
20
20
  require('../../../floating-ui.react-cjs.js');
21
21
  require('react-dom');
22
+ require('../../../maxHeight-cjs.js');
22
23
 
23
24
 
24
25
 
@@ -17,3 +17,4 @@ import '../../../Icon-es.js';
17
17
  import '@jobber/design';
18
18
  import '../../../floating-ui.react-es.js';
19
19
  import 'react-dom';
20
+ import '../../../maxHeight-es.js';
@@ -20,6 +20,7 @@ require('../../Icon-cjs.js');
20
20
  require('@jobber/design');
21
21
  require('../../floating-ui.react-cjs.js');
22
22
  require('react-dom');
23
+ require('../../maxHeight-cjs.js');
23
24
  require('classnames');
24
25
  require('../../useSafeLayoutEffect-cjs.js');
25
26
  require('../../Text-cjs.js');
@@ -18,6 +18,7 @@ import '../../Icon-es.js';
18
18
  import '@jobber/design';
19
19
  import '../../floating-ui.react-es.js';
20
20
  import 'react-dom';
21
+ import '../../maxHeight-es.js';
21
22
  import 'classnames';
22
23
  import '../../useSafeLayoutEffect-es.js';
23
24
  import '../../Text-es.js';
@@ -22,6 +22,7 @@ require('../Icon-cjs.js');
22
22
  require('@jobber/design');
23
23
  require('../floating-ui.react-cjs.js');
24
24
  require('react-dom');
25
+ require('../maxHeight-cjs.js');
25
26
  require('classnames');
26
27
  require('../useSafeLayoutEffect-cjs.js');
27
28
  require('../Text-cjs.js');
@@ -20,6 +20,7 @@ import '../Icon-es.js';
20
20
  import '@jobber/design';
21
21
  import '../floating-ui.react-es.js';
22
22
  import 'react-dom';
23
+ import '../maxHeight-es.js';
23
24
  import 'classnames';
24
25
  import '../useSafeLayoutEffect-es.js';
25
26
  import '../Text-es.js';
@@ -1,8 +1,8 @@
1
1
  import { UseInteractionsReturn } from "@floating-ui/react";
2
2
  import { ComboboxOption } from "../Combobox.types";
3
3
  export declare function useComboboxAccessibility(selectionCallback: (selection: ComboboxOption) => void, filteredOptions: ComboboxOption[], optionsListRef: React.RefObject<HTMLUListElement>, open: boolean, wrapperRef: React.RefObject<HTMLDivElement>): {
4
- popperRef: React.RefObject<HTMLDivElement>;
5
- popperStyles: React.CSSProperties;
4
+ floatingRef: React.RefObject<HTMLDivElement>;
5
+ floatingStyles: React.CSSProperties;
6
6
  floatingProps: ReturnType<UseInteractionsReturn["getFloatingProps"]>;
7
7
  nodeId?: string;
8
8
  parentNodeId: string | null;
@@ -3,7 +3,6 @@
3
3
  var React = require('react');
4
4
  var classnames = require('classnames');
5
5
  var floatingUi_react = require('./floating-ui.react-cjs.js');
6
- var ReactDOM = require('react-dom');
7
6
  var ComboboxContentSearch = require('./ComboboxContentSearch-cjs.js');
8
7
  var ComboboxContentList = require('./ComboboxContentList-cjs.js');
9
8
  var ComboboxContentHeader = require('./ComboboxContentHeader-cjs.js');
@@ -52,12 +51,12 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
52
51
  const parentNodeId = floatingUi_react.useFloatingParentNodeId();
53
52
  const nodeId = floatingUi_react.useFloatingNodeId();
54
53
  useRefocusOnActivator.useRefocusOnActivator_2(open);
55
- const popperRef = useFocusTrap.useFocusTrap_2(open);
54
+ const floatingRef = useFocusTrap.useFocusTrap_2(open);
56
55
  const { floatingStyles, update, context } = floatingUi_react.useFloating({
57
56
  nodeId,
58
57
  elements: {
59
58
  reference: wrapperRef.current,
60
- floating: popperRef.current,
59
+ floating: floatingRef.current,
61
60
  },
62
61
  open,
63
62
  onOpenChange: openState => {
@@ -65,9 +64,8 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
65
64
  handleClose();
66
65
  },
67
66
  middleware: [
68
- floatingUi_react.autoPlacement({ allowedPlacements: ["bottom-start", "top-start"] }),
69
67
  floatingUi_react.offset(COMBOBOX_OFFSET),
70
- floatingUi_react.shift({ padding: COMBOBOX_OFFSET }),
68
+ floatingUi_react.flip({ fallbackPlacements: ["top-start", "bottom-end", "top-end"] }),
71
69
  ],
72
70
  placement: "bottom-start",
73
71
  whileElementsMounted: floatingUi_react.autoUpdate,
@@ -83,11 +81,11 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
83
81
  React.useEffect(() => {
84
82
  var _a;
85
83
  if (open) {
86
- (_a = popperRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleContentKeydown);
84
+ (_a = floatingRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleContentKeydown);
87
85
  }
88
86
  return () => {
89
87
  var _a;
90
- (_a = popperRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleContentKeydown);
88
+ (_a = floatingRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleContentKeydown);
91
89
  };
92
90
  }, [open, optionsListRef, filteredOptions]);
93
91
  function handleContentKeydown(event) {
@@ -126,8 +124,8 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
126
124
  }
127
125
  }
128
126
  return {
129
- popperRef,
130
- popperStyles: floatingStyles,
127
+ floatingRef,
128
+ floatingStyles,
131
129
  floatingProps: getFloatingProps(),
132
130
  nodeId,
133
131
  parentNodeId,
@@ -137,7 +135,7 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
137
135
  function ComboboxContent(props) {
138
136
  const optionsExist = props.options.length > 0;
139
137
  const { onClear, onSelectAll, optionsListRef } = useComboboxContent(props.open, props.selected);
140
- const { popperRef, popperStyles, floatingProps, nodeId, parentNodeId } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
138
+ const { floatingRef, floatingStyles, floatingProps, nodeId, parentNodeId } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
141
139
  // options that are passed back to consumers via onSelectAll callback
142
140
  // should only contain id and label
143
141
  const optionsData = React.useMemo(() => {
@@ -146,9 +144,9 @@ function ComboboxContent(props) {
146
144
  label: option.label,
147
145
  }));
148
146
  }, [props.options]);
149
- const content = (React.createElement("div", Object.assign({ ref: popperRef, id: constants.COMBOBOX_MENU_ID, "data-testid": constants.COMBOBOX_MENU_ID, "data-elevation": "elevated", tabIndex: 0, className: classnames(styles.content, {
147
+ const content = (React.createElement("div", Object.assign({ ref: floatingRef, id: constants.COMBOBOX_MENU_ID, "data-testid": constants.COMBOBOX_MENU_ID, "data-elevation": "elevated", tabIndex: 0, className: classnames(styles.content, {
150
148
  [styles.hidden]: !props.open,
151
- }), style: popperStyles }, floatingProps),
149
+ }), style: floatingStyles }, floatingProps),
152
150
  React.createElement(ComboboxContentSearch.ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue, handleSearchChange: props.handleSearchChange }),
153
151
  props.multiselect && (optionsExist || props.selected.length > 0) && (React.createElement(ComboboxContentHeader.ComboboxContentHeader, { hasOptionsVisible: optionsExist, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
154
152
  props.selectedStateSetter([]);
@@ -166,9 +164,7 @@ function ComboboxContent(props) {
166
164
  React.createElement(floatingUi_react.FloatingNode, { id: nodeId },
167
165
  React.createElement(floatingUi_react.FloatingPortal, null, content))));
168
166
  }
169
- return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document)
170
- ? ReactDOM.createPortal(content, document.body)
171
- : content;
167
+ return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) ? (React.createElement(floatingUi_react.FloatingPortal, null, content)) : (content);
172
168
  }
173
169
 
174
170
  exports.ComboboxContent = ComboboxContent;
@@ -1,7 +1,6 @@
1
1
  import React__default, { useContext, useRef, useEffect, useMemo } from 'react';
2
2
  import classnames from 'classnames';
3
- import { d as useFloatingParentNodeId, e as useFloatingNodeId, u as useFloating, g as autoPlacement, o as offset, s as shift, b as autoUpdate, h as useDismiss, i as useInteractions, j as FloatingTree, k as FloatingNode, F as FloatingPortal } from './floating-ui.react-es.js';
4
- import ReactDOM__default from 'react-dom';
3
+ import { g as useFloatingParentNodeId, h as useFloatingNodeId, u as useFloating, o as offset, f as flip, b as autoUpdate, c as useDismiss, d as useInteractions, i as FloatingTree, j as FloatingNode, F as FloatingPortal } from './floating-ui.react-es.js';
5
4
  import { C as ComboboxContentSearch } from './ComboboxContentSearch-es.js';
6
5
  import { C as ComboboxContentList } from './ComboboxContentList-es.js';
7
6
  import { C as ComboboxContentHeader } from './ComboboxContentHeader-es.js';
@@ -50,12 +49,12 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
50
49
  const parentNodeId = useFloatingParentNodeId();
51
50
  const nodeId = useFloatingNodeId();
52
51
  useRefocusOnActivator_2(open);
53
- const popperRef = useFocusTrap_2(open);
52
+ const floatingRef = useFocusTrap_2(open);
54
53
  const { floatingStyles, update, context } = useFloating({
55
54
  nodeId,
56
55
  elements: {
57
56
  reference: wrapperRef.current,
58
- floating: popperRef.current,
57
+ floating: floatingRef.current,
59
58
  },
60
59
  open,
61
60
  onOpenChange: openState => {
@@ -63,9 +62,8 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
63
62
  handleClose();
64
63
  },
65
64
  middleware: [
66
- autoPlacement({ allowedPlacements: ["bottom-start", "top-start"] }),
67
65
  offset(COMBOBOX_OFFSET),
68
- shift({ padding: COMBOBOX_OFFSET }),
66
+ flip({ fallbackPlacements: ["top-start", "bottom-end", "top-end"] }),
69
67
  ],
70
68
  placement: "bottom-start",
71
69
  whileElementsMounted: autoUpdate,
@@ -81,11 +79,11 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
81
79
  useEffect(() => {
82
80
  var _a;
83
81
  if (open) {
84
- (_a = popperRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleContentKeydown);
82
+ (_a = floatingRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("keydown", handleContentKeydown);
85
83
  }
86
84
  return () => {
87
85
  var _a;
88
- (_a = popperRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleContentKeydown);
86
+ (_a = floatingRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener("keydown", handleContentKeydown);
89
87
  };
90
88
  }, [open, optionsListRef, filteredOptions]);
91
89
  function handleContentKeydown(event) {
@@ -124,8 +122,8 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
124
122
  }
125
123
  }
126
124
  return {
127
- popperRef,
128
- popperStyles: floatingStyles,
125
+ floatingRef,
126
+ floatingStyles,
129
127
  floatingProps: getFloatingProps(),
130
128
  nodeId,
131
129
  parentNodeId,
@@ -135,7 +133,7 @@ function useComboboxAccessibility(selectionCallback, filteredOptions, optionsLis
135
133
  function ComboboxContent(props) {
136
134
  const optionsExist = props.options.length > 0;
137
135
  const { onClear, onSelectAll, optionsListRef } = useComboboxContent(props.open, props.selected);
138
- const { popperRef, popperStyles, floatingProps, nodeId, parentNodeId } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
136
+ const { floatingRef, floatingStyles, floatingProps, nodeId, parentNodeId } = useComboboxAccessibility(props.handleSelection, props.options, optionsListRef, props.open, props.wrapperRef);
139
137
  // options that are passed back to consumers via onSelectAll callback
140
138
  // should only contain id and label
141
139
  const optionsData = useMemo(() => {
@@ -144,9 +142,9 @@ function ComboboxContent(props) {
144
142
  label: option.label,
145
143
  }));
146
144
  }, [props.options]);
147
- const content = (React__default.createElement("div", Object.assign({ ref: popperRef, id: COMBOBOX_MENU_ID, "data-testid": COMBOBOX_MENU_ID, "data-elevation": "elevated", tabIndex: 0, className: classnames(styles.content, {
145
+ const content = (React__default.createElement("div", Object.assign({ ref: floatingRef, id: COMBOBOX_MENU_ID, "data-testid": COMBOBOX_MENU_ID, "data-elevation": "elevated", tabIndex: 0, className: classnames(styles.content, {
148
146
  [styles.hidden]: !props.open,
149
- }), style: popperStyles }, floatingProps),
147
+ }), style: floatingStyles }, floatingProps),
150
148
  React__default.createElement(ComboboxContentSearch, { open: props.open, placeholder: props.subjectNoun, searchValue: props.searchValue, setSearchValue: props.setSearchValue, handleSearchChange: props.handleSearchChange }),
151
149
  props.multiselect && (optionsExist || props.selected.length > 0) && (React__default.createElement(ComboboxContentHeader, { hasOptionsVisible: optionsExist, subjectNoun: props.subjectNoun, selectedCount: props.selected.length, onClearAll: () => {
152
150
  props.selectedStateSetter([]);
@@ -164,9 +162,7 @@ function ComboboxContent(props) {
164
162
  React__default.createElement(FloatingNode, { id: nodeId },
165
163
  React__default.createElement(FloatingPortal, null, content))));
166
164
  }
167
- return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document)
168
- ? ReactDOM__default.createPortal(content, document.body)
169
- : content;
165
+ return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) ? (React__default.createElement(FloatingPortal, null, content)) : (content);
170
166
  }
171
167
 
172
168
  export { ComboboxContent as C };
@@ -13,7 +13,6 @@ require('../Icon-cjs.js');
13
13
  require('@jobber/design');
14
14
  require('../Menu-cjs.js');
15
15
  require('framer-motion');
16
- require('../useOnKeyDown-cjs.js');
17
16
  require('../useRefocusOnActivator-cjs.js');
18
17
  require('../floating-ui.react-cjs.js');
19
18
  require('react-dom');
@@ -21,6 +20,7 @@ require('../useFocusTrap-cjs.js');
21
20
  require('../useIsMounted-cjs.js');
22
21
  require('../useSafeLayoutEffect-cjs.js');
23
22
  require('../useFormFieldFocus-cjs.js');
23
+ require('../maxHeight-cjs.js');
24
24
  require('../Content-cjs.js');
25
25
  require('../Emphasis-cjs.js');
26
26
 
@@ -11,7 +11,6 @@ import '../Icon-es.js';
11
11
  import '@jobber/design';
12
12
  import '../Menu-es.js';
13
13
  import 'framer-motion';
14
- import '../useOnKeyDown-es.js';
15
14
  import '../useRefocusOnActivator-es.js';
16
15
  import '../floating-ui.react-es.js';
17
16
  import 'react-dom';
@@ -19,5 +18,6 @@ import '../useFocusTrap-es.js';
19
18
  import '../useIsMounted-es.js';
20
19
  import '../useSafeLayoutEffect-es.js';
21
20
  import '../useFormFieldFocus-es.js';
21
+ import '../maxHeight-es.js';
22
22
  import '../Content-es.js';
23
23
  import '../Emphasis-es.js';
@@ -4,7 +4,6 @@ var Menu = require('../Menu-cjs.js');
4
4
  require('react');
5
5
  require('classnames');
6
6
  require('framer-motion');
7
- require('../useOnKeyDown-cjs.js');
8
7
  require('../useRefocusOnActivator-cjs.js');
9
8
  require('../floating-ui.react-cjs.js');
10
9
  require('react-dom');
@@ -18,6 +17,7 @@ require('../Icon-cjs.js');
18
17
  require('@jobber/design');
19
18
  require('../Typography-cjs.js');
20
19
  require('../useFormFieldFocus-cjs.js');
20
+ require('../maxHeight-cjs.js');
21
21
 
22
22
 
23
23
 
@@ -2,7 +2,6 @@ export { M as Menu } from '../Menu-es.js';
2
2
  import 'react';
3
3
  import 'classnames';
4
4
  import 'framer-motion';
5
- import '../useOnKeyDown-es.js';
6
5
  import '../useRefocusOnActivator-es.js';
7
6
  import '../floating-ui.react-es.js';
8
7
  import 'react-dom';
@@ -16,3 +15,4 @@ import '../Icon-es.js';
16
15
  import '@jobber/design';
17
16
  import '../Typography-es.js';
18
17
  import '../useFormFieldFocus-es.js';
18
+ import '../maxHeight-es.js';
package/dist/Menu-cjs.js CHANGED
@@ -3,7 +3,6 @@
3
3
  var React = require('react');
4
4
  var classnames = require('classnames');
5
5
  var framerMotion = require('framer-motion');
6
- var useOnKeyDown = require('./useOnKeyDown-cjs.js');
7
6
  var useRefocusOnActivator = require('./useRefocusOnActivator-cjs.js');
8
7
  var floatingUi_react = require('./floating-ui.react-cjs.js');
9
8
  var useFocusTrap = require('./useFocusTrap-cjs.js');
@@ -12,6 +11,7 @@ var Button = require('./Button-cjs.js');
12
11
  var Typography = require('./Typography-cjs.js');
13
12
  var Icon = require('./Icon-cjs.js');
14
13
  var useFormFieldFocus = require('./useFormFieldFocus-cjs.js');
14
+ var maxHeight = require('./maxHeight-cjs.js');
15
15
 
16
16
  var useWindowDimensions$1 = {};
17
17
 
@@ -47,7 +47,7 @@ var styles = {"wrapper":"fpi0W91w2ag-","floatingContainer":"ba-Kj6mvQUw-","menu"
47
47
 
48
48
  const SMALL_SCREEN_BREAKPOINT = 490;
49
49
  const MENU_OFFSET = 6;
50
- const MENU_MAX_HEIGHT_VH = 72; // 72vh as percentage
50
+ const MENU_MAX_HEIGHT_PERCENTAGE = 72;
51
51
  const variation = {
52
52
  overlayStartStop: { opacity: 0 },
53
53
  startOrStop: (placement) => {
@@ -72,7 +72,6 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
72
72
  const wrapperClasses = classnames(styles.wrapper, {
73
73
  [styles.fullWidth]: fullWidth,
74
74
  });
75
- useOnKeyDown.useOnKeyDown_2(handleKeyboardShortcut, ["Escape"]);
76
75
  // useRefocusOnActivator must come before useFocusTrap for them both to work
77
76
  useRefocusOnActivator.useRefocusOnActivator_2(visible);
78
77
  const menuRef = useFocusTrap.useFocusTrap_2(visible);
@@ -90,11 +89,12 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
90
89
  const menuElement = elements.floating.querySelector('[role="menu"]');
91
90
  if (menuElement) {
92
91
  const viewportHeight = window.innerHeight;
93
- const maxHeightVh = (viewportHeight * MENU_MAX_HEIGHT_VH) / 100;
94
- // Use the smaller of 72vh or available space
95
- const maxHeight = Math.min(maxHeightVh, availableHeight);
92
+ const maxHeightVh = (viewportHeight * MENU_MAX_HEIGHT_PERCENTAGE) / 100;
93
+ const maxHeight$1 = maxHeight.calculateMaxHeight(availableHeight, {
94
+ maxHeight: maxHeightVh,
95
+ });
96
96
  Object.assign(menuElement.style, {
97
- maxHeight: `${maxHeight}px`,
97
+ maxHeight: `${maxHeight$1}px`,
98
98
  });
99
99
  }
100
100
  },
@@ -105,6 +105,8 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
105
105
  },
106
106
  whileElementsMounted: floatingUi_react.autoUpdate,
107
107
  });
108
+ const dismiss = floatingUi_react.useDismiss(context);
109
+ const { getFloatingProps } = floatingUi_react.useInteractions([dismiss]);
108
110
  const positionAttributes = width >= SMALL_SCREEN_BREAKPOINT
109
111
  ? {
110
112
  style: floatingStyles,
@@ -127,7 +129,7 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
127
129
  type: "tween",
128
130
  duration: 0.15,
129
131
  } }),
130
- React.createElement("div", Object.assign({ ref: refs.setFloating, className: styles.floatingContainer }, positionAttributes, useFormFieldFocus.formFieldFocusAttribute), items.length > 0 && (React.createElement(framerMotion.motion.div, { className: classnames(styles.menu, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.menu), role: "menu", "data-elevation": "elevated", "aria-labelledby": buttonID, id: menuID, onClick: hide, variants: variation, initial: "startOrStop", animate: "done", exit: "startOrStop", custom: context === null || context === void 0 ? void 0 : context.placement, ref: menuRef, transition: {
132
+ React.createElement("div", Object.assign({ ref: refs.setFloating, className: styles.floatingContainer }, getFloatingProps(), positionAttributes, useFormFieldFocus.formFieldFocusAttribute), items.length > 0 && (React.createElement(framerMotion.motion.div, { className: classnames(styles.menu, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.menu), role: "menu", "data-elevation": "elevated", "aria-labelledby": buttonID, id: menuID, onClick: hide, variants: variation, initial: "startOrStop", animate: "done", exit: "startOrStop", custom: context === null || context === void 0 ? void 0 : context.placement, ref: menuRef, transition: {
131
133
  type: "tween",
132
134
  duration: 0.25,
133
135
  }, style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.menu }, items.map((item, key) => (React.createElement("div", { key: key, className: styles.section },
@@ -142,14 +144,6 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
142
144
  function hide() {
143
145
  setVisible(false);
144
146
  }
145
- function handleKeyboardShortcut(event) {
146
- const { key } = event;
147
- if (!visible)
148
- return;
149
- event.preventDefault();
150
- event.stopPropagation();
151
- key === "Escape" && hide();
152
- }
153
147
  function handleParentClick(event) {
154
148
  // Since the menu is being rendered within the same parent as the activator,
155
149
  // we need to stop the click event from bubbling up. If the Menu component
package/dist/Menu-es.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import React__default, { useState, useId, useRef } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { AnimatePresence, motion } from 'framer-motion';
4
- import { u as useOnKeyDown_2 } from './useOnKeyDown-es.js';
5
4
  import { u as useRefocusOnActivator_2 } from './useRefocusOnActivator-es.js';
6
- import { u as useFloating, F as FloatingPortal, o as offset, f as flip, c as size, b as autoUpdate } from './floating-ui.react-es.js';
5
+ import { u as useFloating, c as useDismiss, d as useInteractions, F as FloatingPortal, o as offset, f as flip, e as size, b as autoUpdate } from './floating-ui.react-es.js';
7
6
  import { u as useFocusTrap_2 } from './useFocusTrap-es.js';
8
7
  import { u as useIsMounted_2 } from './useIsMounted-es.js';
9
8
  import { B as Button } from './Button-es.js';
10
9
  import { T as Typography } from './Typography-es.js';
11
10
  import { I as Icon } from './Icon-es.js';
12
11
  import { f as formFieldFocusAttribute } from './useFormFieldFocus-es.js';
12
+ import { c as calculateMaxHeight } from './maxHeight-es.js';
13
13
 
14
14
  var useWindowDimensions$1 = {};
15
15
 
@@ -45,7 +45,7 @@ var styles = {"wrapper":"fpi0W91w2ag-","floatingContainer":"ba-Kj6mvQUw-","menu"
45
45
 
46
46
  const SMALL_SCREEN_BREAKPOINT = 490;
47
47
  const MENU_OFFSET = 6;
48
- const MENU_MAX_HEIGHT_VH = 72; // 72vh as percentage
48
+ const MENU_MAX_HEIGHT_PERCENTAGE = 72;
49
49
  const variation = {
50
50
  overlayStartStop: { opacity: 0 },
51
51
  startOrStop: (placement) => {
@@ -70,7 +70,6 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
70
70
  const wrapperClasses = classnames(styles.wrapper, {
71
71
  [styles.fullWidth]: fullWidth,
72
72
  });
73
- useOnKeyDown_2(handleKeyboardShortcut, ["Escape"]);
74
73
  // useRefocusOnActivator must come before useFocusTrap for them both to work
75
74
  useRefocusOnActivator_2(visible);
76
75
  const menuRef = useFocusTrap_2(visible);
@@ -88,9 +87,10 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
88
87
  const menuElement = elements.floating.querySelector('[role="menu"]');
89
88
  if (menuElement) {
90
89
  const viewportHeight = window.innerHeight;
91
- const maxHeightVh = (viewportHeight * MENU_MAX_HEIGHT_VH) / 100;
92
- // Use the smaller of 72vh or available space
93
- const maxHeight = Math.min(maxHeightVh, availableHeight);
90
+ const maxHeightVh = (viewportHeight * MENU_MAX_HEIGHT_PERCENTAGE) / 100;
91
+ const maxHeight = calculateMaxHeight(availableHeight, {
92
+ maxHeight: maxHeightVh,
93
+ });
94
94
  Object.assign(menuElement.style, {
95
95
  maxHeight: `${maxHeight}px`,
96
96
  });
@@ -103,6 +103,8 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
103
103
  },
104
104
  whileElementsMounted: autoUpdate,
105
105
  });
106
+ const dismiss = useDismiss(context);
107
+ const { getFloatingProps } = useInteractions([dismiss]);
106
108
  const positionAttributes = width >= SMALL_SCREEN_BREAKPOINT
107
109
  ? {
108
110
  style: floatingStyles,
@@ -125,7 +127,7 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
125
127
  type: "tween",
126
128
  duration: 0.15,
127
129
  } }),
128
- React__default.createElement("div", Object.assign({ ref: refs.setFloating, className: styles.floatingContainer }, positionAttributes, formFieldFocusAttribute), items.length > 0 && (React__default.createElement(motion.div, { className: classnames(styles.menu, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.menu), role: "menu", "data-elevation": "elevated", "aria-labelledby": buttonID, id: menuID, onClick: hide, variants: variation, initial: "startOrStop", animate: "done", exit: "startOrStop", custom: context === null || context === void 0 ? void 0 : context.placement, ref: menuRef, transition: {
130
+ React__default.createElement("div", Object.assign({ ref: refs.setFloating, className: styles.floatingContainer }, getFloatingProps(), positionAttributes, formFieldFocusAttribute), items.length > 0 && (React__default.createElement(motion.div, { className: classnames(styles.menu, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.menu), role: "menu", "data-elevation": "elevated", "aria-labelledby": buttonID, id: menuID, onClick: hide, variants: variation, initial: "startOrStop", animate: "done", exit: "startOrStop", custom: context === null || context === void 0 ? void 0 : context.placement, ref: menuRef, transition: {
129
131
  type: "tween",
130
132
  duration: 0.25,
131
133
  }, style: UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.menu }, items.map((item, key) => (React__default.createElement("div", { key: key, className: styles.section },
@@ -140,14 +142,6 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
140
142
  function hide() {
141
143
  setVisible(false);
142
144
  }
143
- function handleKeyboardShortcut(event) {
144
- const { key } = event;
145
- if (!visible)
146
- return;
147
- event.preventDefault();
148
- event.stopPropagation();
149
- key === "Escape" && hide();
150
- }
151
145
  function handleParentClick(event) {
152
146
  // Since the menu is being rendered within the same parent as the activator,
153
147
  // we need to stop the click event from bubbling up. If the Menu component
@@ -9,7 +9,7 @@ import { H as Heading } from '../Heading-es.js';
9
9
  import { B as Button } from '../Button-es.js';
10
10
  import { B as ButtonDismiss } from '../ButtonDismiss-es.js';
11
11
  import { n as noop } from '../noop-es.js';
12
- import { e as useFloatingNodeId, u as useFloating, m as useClick, h as useDismiss, n as useRole, i as useInteractions, d as useFloatingParentNodeId, j as FloatingTree, k as FloatingNode, F as FloatingPortal, p as FloatingOverlay, q as FloatingFocusManager } from '../floating-ui.react-es.js';
12
+ import { h as useFloatingNodeId, u as useFloating, m as useClick, c as useDismiss, n as useRole, d as useInteractions, g as useFloatingParentNodeId, i as FloatingTree, j as FloatingNode, F as FloatingPortal, p as FloatingOverlay, q as FloatingFocusManager } from '../floating-ui.react-es.js';
13
13
  import { b as identity } from '../identity-es.js';
14
14
  import { A as AtlantisPortalContent } from '../AtlantisPortalContent-es.js';
15
15
  import '../Typography-es.js';
@@ -23,7 +23,6 @@ require('../Icon-cjs.js');
23
23
  require('@jobber/design');
24
24
  require('../Menu-cjs.js');
25
25
  require('framer-motion');
26
- require('../useOnKeyDown-cjs.js');
27
26
  require('../useRefocusOnActivator-cjs.js');
28
27
  require('../floating-ui.react-cjs.js');
29
28
  require('react-dom');
@@ -31,6 +30,7 @@ require('../useFocusTrap-cjs.js');
31
30
  require('../useIsMounted-cjs.js');
32
31
  require('../useSafeLayoutEffect-cjs.js');
33
32
  require('../useFormFieldFocus-cjs.js');
33
+ require('../maxHeight-cjs.js');
34
34
 
35
35
 
36
36
 
@@ -21,7 +21,6 @@ import '../Icon-es.js';
21
21
  import '@jobber/design';
22
22
  import '../Menu-es.js';
23
23
  import 'framer-motion';
24
- import '../useOnKeyDown-es.js';
25
24
  import '../useRefocusOnActivator-es.js';
26
25
  import '../floating-ui.react-es.js';
27
26
  import 'react-dom';
@@ -29,3 +28,4 @@ import '../useFocusTrap-es.js';
29
28
  import '../useIsMounted-es.js';
30
29
  import '../useSafeLayoutEffect-es.js';
31
30
  import '../useFormFieldFocus-es.js';
31
+ import '../maxHeight-es.js';
@@ -3,8 +3,8 @@ import React, { CSSProperties } from "react";
3
3
  import { PopoverProviderProps } from "./Popover.types";
4
4
  interface PopoverContextProps {
5
5
  setArrowElement: (element: HTMLElement | null) => void;
6
- popperStyles: {
7
- popper: CSSProperties;
6
+ floatingStyles: {
7
+ float: CSSProperties;
8
8
  arrow?: {
9
9
  x?: number;
10
10
  y?: number;
@@ -4,8 +4,8 @@ var Popover = require('../Popover-cjs.js');
4
4
  require('../tslib.es6-cjs.js');
5
5
  require('react');
6
6
  require('classnames');
7
- require('react-dom');
8
7
  require('../floating-ui.react-cjs.js');
8
+ require('react-dom');
9
9
  require('../useRefocusOnActivator-cjs.js');
10
10
  require('../AtlantisPortalContent-cjs.js');
11
11
  require('../AtlantisThemeContext-cjs.js');
@@ -2,8 +2,8 @@ export { P as Popover, u as usePopoverContext, a as usePopoverStyles } from '../
2
2
  import '../tslib.es6-es.js';
3
3
  import 'react';
4
4
  import 'classnames';
5
- import 'react-dom';
6
5
  import '../floating-ui.react-es.js';
6
+ import 'react-dom';
7
7
  import '../useRefocusOnActivator-es.js';
8
8
  import '../AtlantisPortalContent-es.js';
9
9
  import '../AtlantisThemeContext-es.js';
@@ -1,16 +1,13 @@
1
1
  import { PopoverProps } from "./Popover.types";
2
2
  export declare const usePopover: ({ preferredPlacement, attachTo, open, }: Pick<PopoverProps, "preferredPlacement" | "attachTo" | "open">) => {
3
- setPopperElement: ((node: HTMLElement | null) => void) & ((node: HTMLElement | null) => void);
3
+ setFloatingElement: ((node: HTMLElement | null) => void) & ((node: HTMLElement | null) => void);
4
4
  setArrowElement: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null | undefined>>;
5
- popperStyles: {
6
- popper: import("react").CSSProperties;
5
+ floatingStyles: {
6
+ float: import("react").CSSProperties;
7
7
  arrow: (Partial<import("@floating-ui/core").Coords> & {
8
8
  centerOffset: number;
9
9
  alignmentOffset?: number;
10
10
  }) | undefined;
11
11
  };
12
12
  placement: import("@floating-ui/utils").Placement;
13
- attributes: {
14
- popper: {};
15
- };
16
13
  };
@@ -3,7 +3,6 @@
3
3
  var tslib_es6 = require('./tslib.es6-cjs.js');
4
4
  var React = require('react');
5
5
  var classnames = require('classnames');
6
- var ReactDOM = require('react-dom');
7
6
  var floatingUi_react = require('./floating-ui.react-cjs.js');
8
7
  var useRefocusOnActivator = require('./useRefocusOnActivator-cjs.js');
9
8
  var AtlantisPortalContent = require('./AtlantisPortalContent-cjs.js');
@@ -56,14 +55,13 @@ const usePopover = ({ preferredPlacement, attachTo, open, }) => {
56
55
  });
57
56
  useRefocusOnActivator.useRefocusOnActivator_2(open);
58
57
  return {
59
- setPopperElement: refs.setFloating,
58
+ setFloatingElement: refs.setFloating,
60
59
  setArrowElement,
61
- popperStyles: {
62
- popper: floatingStyles,
60
+ floatingStyles: {
61
+ float: floatingStyles,
63
62
  arrow: middlewareData.arrow,
64
63
  },
65
64
  placement,
66
- attributes: { popper: {} },
67
65
  };
68
66
  };
69
67
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -82,7 +80,7 @@ const usePopoverStyles = () => {
82
80
  };
83
81
 
84
82
  const PopoverContext = React.createContext({
85
- popperStyles: { popper: {} },
83
+ floatingStyles: { float: {} },
86
84
  setArrowElement: () => {
87
85
  // noop
88
86
  },
@@ -91,7 +89,7 @@ function usePopoverContext() {
91
89
  return React.useContext(PopoverContext);
92
90
  }
93
91
  function PopoverProvider({ children, preferredPlacement = "auto", attachTo, open, UNSAFE_className, UNSAFE_style, }) {
94
- const { setPopperElement, setArrowElement, popperStyles, placement } = usePopover({
92
+ const { setFloatingElement, setArrowElement, floatingStyles, placement } = usePopover({
95
93
  preferredPlacement,
96
94
  attachTo,
97
95
  open,
@@ -100,18 +98,18 @@ function PopoverProvider({ children, preferredPlacement = "auto", attachTo, open
100
98
  return null;
101
99
  return (React.createElement(PopoverContext.Provider, { value: {
102
100
  setArrowElement,
103
- popperStyles,
101
+ floatingStyles,
104
102
  placement,
105
103
  } },
106
- React.createElement(PopoverWrapper, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, setPopperElement: setPopperElement, placement: placement }, children)));
104
+ React.createElement(PopoverWrapper, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, setFloatingElement: setFloatingElement, placement: placement }, children)));
107
105
  }
108
- function PopoverWrapper({ children, setPopperElement, UNSAFE_className, UNSAFE_style, placement, }) {
106
+ function PopoverWrapper({ children, setFloatingElement, UNSAFE_className, UNSAFE_style, placement, }) {
109
107
  const popoverStyles = usePopoverStyles();
110
- const { popperStyles } = usePopoverContext();
108
+ const { floatingStyles } = usePopoverContext();
111
109
  const classes = classnames(popoverStyles.container, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container);
112
110
  const content = (React.createElement(AtlantisPortalContent.AtlantisPortalContent, null,
113
- React.createElement("div", { role: "dialog", "data-elevation": "elevated", ref: setPopperElement, style: Object.assign(Object.assign({}, popperStyles.popper), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container), className: classes, "data-popover-placement": placement, "data-testid": "ATL-Popover-Container" }, children)));
114
- return ReactDOM.createPortal(content, document.body);
111
+ React.createElement("div", { role: "dialog", "data-elevation": "elevated", ref: setFloatingElement, style: Object.assign(Object.assign({}, floatingStyles.float), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container), className: classes, "data-popover-placement": placement, "data-testid": "ATL-Popover-Container" }, children)));
112
+ return React.createElement(floatingUi_react.FloatingPortal, null, content);
115
113
  }
116
114
 
117
115
  function Popover({ onRequestClose, children, attachTo, open, preferredPlacement = "auto", UNSAFE_className, UNSAFE_style, }) {
@@ -122,8 +120,8 @@ function Popover({ onRequestClose, children, attachTo, open, preferredPlacement
122
120
  }
123
121
  Popover.Provider = PopoverProvider;
124
122
  Popover.Arrow = function PopoverArrow({ UNSAFE_className, UNSAFE_style, }) {
125
- var _a, _b, _c, _d;
126
- const { setArrowElement, popperStyles, placement } = usePopoverContext();
123
+ var _a, _b;
124
+ const { setArrowElement, floatingStyles, placement } = usePopoverContext();
127
125
  const popoverStyles = usePopoverStyles();
128
126
  const classes = classnames(popoverStyles.arrow, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.arrow);
129
127
  // the arrow will get positioned opposite to the placement side
@@ -134,11 +132,13 @@ Popover.Arrow = function PopoverArrow({ UNSAFE_className, UNSAFE_style, }) {
134
132
  left: "right",
135
133
  };
136
134
  const staticSide = staticSideMap[placement];
135
+ const arrowX = (_a = floatingStyles.arrow) === null || _a === void 0 ? void 0 : _a.x;
136
+ const arrowY = (_b = floatingStyles.arrow) === null || _b === void 0 ? void 0 : _b.y;
137
137
  const arrowStyles = {
138
138
  position: "absolute",
139
139
  // only left or top will be defined at a time
140
- left: ((_a = popperStyles.arrow) === null || _a === void 0 ? void 0 : _a.x) != null ? `${(_b = popperStyles.arrow) === null || _b === void 0 ? void 0 : _b.x}px` : "",
141
- top: ((_c = popperStyles.arrow) === null || _c === void 0 ? void 0 : _c.y) != null ? `${(_d = popperStyles.arrow) === null || _d === void 0 ? void 0 : _d.y}px` : "",
140
+ left: arrowX !== null && arrowX !== undefined ? `${arrowX}px` : "",
141
+ top: arrowY !== null && arrowY !== undefined ? `${arrowY}px` : "",
142
142
  right: "",
143
143
  bottom: "",
144
144
  [staticSide]: "var(--popover--position--offset)",
@@ -1,8 +1,7 @@
1
1
  import { _ as __rest } from './tslib.es6-es.js';
2
2
  import React__default, { useState, useMemo, createContext, useContext } from 'react';
3
3
  import classnames from 'classnames';
4
- import ReactDOM__default from 'react-dom';
5
- import { o as offset, s as shift, l as limitShift, g as autoPlacement, f as flip, a as arrow, u as useFloating, b as autoUpdate } from './floating-ui.react-es.js';
4
+ import { o as offset, s as shift, l as limitShift, k as autoPlacement, f as flip, a as arrow, u as useFloating, b as autoUpdate, F as FloatingPortal } from './floating-ui.react-es.js';
6
5
  import { u as useRefocusOnActivator_2 } from './useRefocusOnActivator-es.js';
7
6
  import { A as AtlantisPortalContent } from './AtlantisPortalContent-es.js';
8
7
  import { B as ButtonDismiss } from './ButtonDismiss-es.js';
@@ -54,14 +53,13 @@ const usePopover = ({ preferredPlacement, attachTo, open, }) => {
54
53
  });
55
54
  useRefocusOnActivator_2(open);
56
55
  return {
57
- setPopperElement: refs.setFloating,
56
+ setFloatingElement: refs.setFloating,
58
57
  setArrowElement,
59
- popperStyles: {
60
- popper: floatingStyles,
58
+ floatingStyles: {
59
+ float: floatingStyles,
61
60
  arrow: middlewareData.arrow,
62
61
  },
63
62
  placement,
64
- attributes: { popper: {} },
65
63
  };
66
64
  };
67
65
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -80,7 +78,7 @@ const usePopoverStyles = () => {
80
78
  };
81
79
 
82
80
  const PopoverContext = createContext({
83
- popperStyles: { popper: {} },
81
+ floatingStyles: { float: {} },
84
82
  setArrowElement: () => {
85
83
  // noop
86
84
  },
@@ -89,7 +87,7 @@ function usePopoverContext() {
89
87
  return useContext(PopoverContext);
90
88
  }
91
89
  function PopoverProvider({ children, preferredPlacement = "auto", attachTo, open, UNSAFE_className, UNSAFE_style, }) {
92
- const { setPopperElement, setArrowElement, popperStyles, placement } = usePopover({
90
+ const { setFloatingElement, setArrowElement, floatingStyles, placement } = usePopover({
93
91
  preferredPlacement,
94
92
  attachTo,
95
93
  open,
@@ -98,18 +96,18 @@ function PopoverProvider({ children, preferredPlacement = "auto", attachTo, open
98
96
  return null;
99
97
  return (React__default.createElement(PopoverContext.Provider, { value: {
100
98
  setArrowElement,
101
- popperStyles,
99
+ floatingStyles,
102
100
  placement,
103
101
  } },
104
- React__default.createElement(PopoverWrapper, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, setPopperElement: setPopperElement, placement: placement }, children)));
102
+ React__default.createElement(PopoverWrapper, { UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style, setFloatingElement: setFloatingElement, placement: placement }, children)));
105
103
  }
106
- function PopoverWrapper({ children, setPopperElement, UNSAFE_className, UNSAFE_style, placement, }) {
104
+ function PopoverWrapper({ children, setFloatingElement, UNSAFE_className, UNSAFE_style, placement, }) {
107
105
  const popoverStyles = usePopoverStyles();
108
- const { popperStyles } = usePopoverContext();
106
+ const { floatingStyles } = usePopoverContext();
109
107
  const classes = classnames(popoverStyles.container, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.container);
110
108
  const content = (React__default.createElement(AtlantisPortalContent, null,
111
- React__default.createElement("div", { role: "dialog", "data-elevation": "elevated", ref: setPopperElement, style: Object.assign(Object.assign({}, popperStyles.popper), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container), className: classes, "data-popover-placement": placement, "data-testid": "ATL-Popover-Container" }, children)));
112
- return ReactDOM__default.createPortal(content, document.body);
109
+ React__default.createElement("div", { role: "dialog", "data-elevation": "elevated", ref: setFloatingElement, style: Object.assign(Object.assign({}, floatingStyles.float), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.container), className: classes, "data-popover-placement": placement, "data-testid": "ATL-Popover-Container" }, children)));
110
+ return React__default.createElement(FloatingPortal, null, content);
113
111
  }
114
112
 
115
113
  function Popover({ onRequestClose, children, attachTo, open, preferredPlacement = "auto", UNSAFE_className, UNSAFE_style, }) {
@@ -120,8 +118,8 @@ function Popover({ onRequestClose, children, attachTo, open, preferredPlacement
120
118
  }
121
119
  Popover.Provider = PopoverProvider;
122
120
  Popover.Arrow = function PopoverArrow({ UNSAFE_className, UNSAFE_style, }) {
123
- var _a, _b, _c, _d;
124
- const { setArrowElement, popperStyles, placement } = usePopoverContext();
121
+ var _a, _b;
122
+ const { setArrowElement, floatingStyles, placement } = usePopoverContext();
125
123
  const popoverStyles = usePopoverStyles();
126
124
  const classes = classnames(popoverStyles.arrow, UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.arrow);
127
125
  // the arrow will get positioned opposite to the placement side
@@ -132,11 +130,13 @@ Popover.Arrow = function PopoverArrow({ UNSAFE_className, UNSAFE_style, }) {
132
130
  left: "right",
133
131
  };
134
132
  const staticSide = staticSideMap[placement];
133
+ const arrowX = (_a = floatingStyles.arrow) === null || _a === void 0 ? void 0 : _a.x;
134
+ const arrowY = (_b = floatingStyles.arrow) === null || _b === void 0 ? void 0 : _b.y;
135
135
  const arrowStyles = {
136
136
  position: "absolute",
137
137
  // only left or top will be defined at a time
138
- left: ((_a = popperStyles.arrow) === null || _a === void 0 ? void 0 : _a.x) != null ? `${(_b = popperStyles.arrow) === null || _b === void 0 ? void 0 : _b.x}px` : "",
139
- top: ((_c = popperStyles.arrow) === null || _c === void 0 ? void 0 : _c.y) != null ? `${(_d = popperStyles.arrow) === null || _d === void 0 ? void 0 : _d.y}px` : "",
138
+ left: arrowX !== null && arrowX !== undefined ? `${arrowX}px` : "",
139
+ top: arrowY !== null && arrowY !== undefined ? `${arrowY}px` : "",
140
140
  right: "",
141
141
  bottom: "",
142
142
  [staticSide]: "var(--popover--position--offset)",
@@ -6029,4 +6029,4 @@ function useRole(context, props) {
6029
6029
  } : {}, [enabled, reference, floating, item]);
6030
6030
  }
6031
6031
 
6032
- export { FloatingPortal as F, arrow as a, autoUpdate as b, size as c, useFloatingParentNodeId as d, useFloatingNodeId as e, flip as f, autoPlacement as g, useDismiss as h, useInteractions as i, FloatingTree as j, FloatingNode as k, limitShift as l, useClick as m, useRole as n, offset as o, FloatingOverlay as p, FloatingFocusManager as q, shift as s, useFloating as u };
6032
+ export { FloatingPortal as F, arrow as a, autoUpdate as b, useDismiss as c, useInteractions as d, size as e, flip as f, useFloatingParentNodeId as g, useFloatingNodeId as h, FloatingTree as i, FloatingNode as j, autoPlacement as k, limitShift as l, useClick as m, useRole as n, offset as o, FloatingOverlay as p, FloatingFocusManager as q, shift as s, useFloating as u };
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ var Heading = require('./Heading-cjs.js');
12
12
  var Text = require('./Text-cjs.js');
13
13
  var Icon = require('./Icon-cjs.js');
14
14
  require('./useSafeLayoutEffect-cjs.js');
15
+ require('@jobber/design');
15
16
  require('./useIsMounted-cjs.js');
16
17
  var Avatar = require('./Avatar-cjs.js');
17
18
  var Banner = require('./Banner-cjs.js');
@@ -99,7 +100,6 @@ var showToast = require('./showToast-cjs.js');
99
100
  var Tooltip = require('./Tooltip-cjs.js');
100
101
  var Typography = require('./Typography-cjs.js');
101
102
  require('framer-motion');
102
- require('@jobber/design');
103
103
  require('./_commonjsHelpers-cjs.js');
104
104
  require('./identity-cjs.js');
105
105
  require('./isTypedArray-cjs.js');
@@ -113,6 +113,7 @@ require('./tslib.es6-cjs.js');
113
113
  require('./useDebounce-cjs.js');
114
114
  require('./floating-ui.react-cjs.js');
115
115
  require('react-dom');
116
+ require('./maxHeight-cjs.js');
116
117
  require('./useOnKeyDown-cjs.js');
117
118
  require('color');
118
119
  require('react-router-dom');
package/dist/index.mjs CHANGED
@@ -10,6 +10,7 @@ export { H as Heading } from './Heading-es.js';
10
10
  export { T as Text } from './Text-es.js';
11
11
  export { I as Icon } from './Icon-es.js';
12
12
  import './useSafeLayoutEffect-es.js';
13
+ import '@jobber/design';
13
14
  import './useIsMounted-es.js';
14
15
  export { A as Avatar } from './Avatar-es.js';
15
16
  export { B as Banner } from './Banner-es.js';
@@ -97,7 +98,6 @@ export { T as Toast, s as showToast } from './showToast-es.js';
97
98
  export { T as Tooltip } from './Tooltip-es.js';
98
99
  export { T as Typography } from './Typography-es.js';
99
100
  import 'framer-motion';
100
- import '@jobber/design';
101
101
  import './_commonjsHelpers-es.js';
102
102
  import './identity-es.js';
103
103
  import './isTypedArray-es.js';
@@ -111,6 +111,7 @@ import './tslib.es6-es.js';
111
111
  import './useDebounce-es.js';
112
112
  import './floating-ui.react-es.js';
113
113
  import 'react-dom';
114
+ import './maxHeight-es.js';
114
115
  import './useOnKeyDown-es.js';
115
116
  import 'color';
116
117
  import 'react-router-dom';
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var design = require('@jobber/design');
4
+
5
+ /**
6
+ * Calculates the appropriate max height for floating elements based on available space.
7
+ *
8
+ * This utility encapsulates the common pattern of:
9
+ * - Using a preferred max height when space allows
10
+ * - Falling back to available height minus edge padding when constrained
11
+ *
12
+ * @param availableHeight - The available height from FloatingUI's size middleware
13
+ * @param options - Configuration for max height, and edge padding
14
+ * @returns The calculated max height in pixels
15
+ */
16
+ function calculateMaxHeight(availableHeight, options) {
17
+ const { maxHeight, edgePadding = design.tokens["space-base"] } = options;
18
+ if (availableHeight > maxHeight) {
19
+ return maxHeight;
20
+ }
21
+ return Math.min(maxHeight, Math.max(availableHeight - edgePadding, 0));
22
+ }
23
+
24
+ exports.calculateMaxHeight = calculateMaxHeight;
@@ -0,0 +1,22 @@
1
+ import { tokens } from '@jobber/design';
2
+
3
+ /**
4
+ * Calculates the appropriate max height for floating elements based on available space.
5
+ *
6
+ * This utility encapsulates the common pattern of:
7
+ * - Using a preferred max height when space allows
8
+ * - Falling back to available height minus edge padding when constrained
9
+ *
10
+ * @param availableHeight - The available height from FloatingUI's size middleware
11
+ * @param options - Configuration for max height, and edge padding
12
+ * @returns The calculated max height in pixels
13
+ */
14
+ function calculateMaxHeight(availableHeight, options) {
15
+ const { maxHeight, edgePadding = tokens["space-base"] } = options;
16
+ if (availableHeight > maxHeight) {
17
+ return maxHeight;
18
+ }
19
+ return Math.min(maxHeight, Math.max(availableHeight - edgePadding, 0));
20
+ }
21
+
22
+ export { calculateMaxHeight as c };
@@ -12,6 +12,7 @@ var _isIterateeCall = require('./_isIterateeCall-cjs.js');
12
12
  var debounce = require('./debounce-cjs.js');
13
13
  var Icon = require('./Icon-cjs.js');
14
14
  var floatingUi_react = require('./floating-ui.react-cjs.js');
15
+ var maxHeight = require('./maxHeight-cjs.js');
15
16
 
16
17
  var baseEach = _baseEach._baseEach,
17
18
  isArrayLike = isTypedArray.isArrayLike_1;
@@ -583,9 +584,11 @@ function useRepositionMenu(attachTo) {
583
584
  floatingUi_react.flip({ fallbackPlacements: ["top"] }),
584
585
  floatingUi_react.size({
585
586
  apply({ availableHeight, elements }) {
586
- const maxHeight = Math.min(PREFERRED_MAX_HEIGHT, availableHeight);
587
+ const maxHeight$1 = maxHeight.calculateMaxHeight(availableHeight, {
588
+ maxHeight: PREFERRED_MAX_HEIGHT,
589
+ });
587
590
  Object.assign(elements.floating.style, {
588
- maxHeight: `${maxHeight}px`,
591
+ maxHeight: `${maxHeight$1}px`,
589
592
  });
590
593
  },
591
594
  }),
@@ -9,7 +9,8 @@ import { i as identity_1 } from './identity-es.js';
9
9
  import { _ as _baseRest, a as _isIterateeCall } from './_isIterateeCall-es.js';
10
10
  import { a as debounce } from './debounce-es.js';
11
11
  import { I as Icon } from './Icon-es.js';
12
- import { u as useFloating, o as offset, f as flip, c as size, b as autoUpdate } from './floating-ui.react-es.js';
12
+ import { u as useFloating, o as offset, f as flip, e as size, b as autoUpdate } from './floating-ui.react-es.js';
13
+ import { c as calculateMaxHeight } from './maxHeight-es.js';
13
14
 
14
15
  var baseEach = _baseEach,
15
16
  isArrayLike = isArrayLike_1;
@@ -581,7 +582,9 @@ function useRepositionMenu(attachTo) {
581
582
  flip({ fallbackPlacements: ["top"] }),
582
583
  size({
583
584
  apply({ availableHeight, elements }) {
584
- const maxHeight = Math.min(PREFERRED_MAX_HEIGHT, availableHeight);
585
+ const maxHeight = calculateMaxHeight(availableHeight, {
586
+ maxHeight: PREFERRED_MAX_HEIGHT,
587
+ });
585
588
  Object.assign(elements.floating.style, {
586
589
  maxHeight: `${maxHeight}px`,
587
590
  });
@@ -0,0 +1,23 @@
1
+ export interface MaxHeightOptions {
2
+ /**
3
+ * The preferred maximum height in pixels
4
+ */
5
+ readonly maxHeight: number;
6
+ /**
7
+ * Edge padding to ensure the element doesn't touch screen edges
8
+ * @default tokens["space-base"]
9
+ */
10
+ readonly edgePadding?: number;
11
+ }
12
+ /**
13
+ * Calculates the appropriate max height for floating elements based on available space.
14
+ *
15
+ * This utility encapsulates the common pattern of:
16
+ * - Using a preferred max height when space allows
17
+ * - Falling back to available height minus edge padding when constrained
18
+ *
19
+ * @param availableHeight - The available height from FloatingUI's size middleware
20
+ * @param options - Configuration for max height, and edge padding
21
+ * @returns The calculated max height in pixels
22
+ */
23
+ export declare function calculateMaxHeight(availableHeight: number, options: MaxHeightOptions): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "6.80.0",
3
+ "version": "6.81.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -542,5 +542,5 @@
542
542
  "> 1%",
543
543
  "IE 10"
544
544
  ],
545
- "gitHead": "fb31413a164542a3481767f2ae2d31c172e86f35"
545
+ "gitHead": "0a0c72d9d554c30657ac0c9d0a88f8261770ac2e"
546
546
  }