@jobber/components 6.77.0 → 6.80.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.
@@ -3,7 +3,7 @@ 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, q 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, c 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
8
  import { H as Heading } from './Heading-es.js';
9
9
  import { T as Text } from './Text-es.js';
@@ -14,11 +14,11 @@ require('../Menu-cjs.js');
14
14
  require('framer-motion');
15
15
  require('../useOnKeyDown-cjs.js');
16
16
  require('../useRefocusOnActivator-cjs.js');
17
- require('react-popper');
18
- require('../useIsMounted-cjs.js');
19
- require('../useSafeLayoutEffect-cjs.js');
17
+ require('../floating-ui.react-cjs.js');
20
18
  require('react-dom');
21
19
  require('../useFocusTrap-cjs.js');
20
+ require('../useIsMounted-cjs.js');
21
+ require('../useSafeLayoutEffect-cjs.js');
22
22
  require('../useFormFieldFocus-cjs.js');
23
23
 
24
24
 
@@ -12,9 +12,9 @@ import '../Menu-es.js';
12
12
  import 'framer-motion';
13
13
  import '../useOnKeyDown-es.js';
14
14
  import '../useRefocusOnActivator-es.js';
15
- import 'react-popper';
16
- import '../useIsMounted-es.js';
17
- import '../useSafeLayoutEffect-es.js';
15
+ import '../floating-ui.react-es.js';
18
16
  import 'react-dom';
19
17
  import '../useFocusTrap-es.js';
18
+ import '../useIsMounted-es.js';
19
+ import '../useSafeLayoutEffect-es.js';
20
20
  import '../useFormFieldFocus-es.js';
@@ -1,6 +1,6 @@
1
1
  import React__default, { useContext, useRef, useEffect, useMemo } from 'react';
2
2
  import classnames from 'classnames';
3
- import { c as useFloatingParentNodeId, d as useFloatingNodeId, u as useFloating, e as autoPlacement, o as offset, s as shift, b as autoUpdate, g as useDismiss, h as useInteractions, i as FloatingTree, j as FloatingNode, F as FloatingPortal } from './floating-ui.react-es.js';
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
4
  import ReactDOM__default from 'react-dom';
5
5
  import { C as ComboboxContentSearch } from './ComboboxContentSearch-es.js';
6
6
  import { C as ComboboxContentList } from './ComboboxContentList-es.js';
@@ -15,11 +15,11 @@ require('../Menu-cjs.js');
15
15
  require('framer-motion');
16
16
  require('../useOnKeyDown-cjs.js');
17
17
  require('../useRefocusOnActivator-cjs.js');
18
- require('react-popper');
19
- require('../useIsMounted-cjs.js');
20
- require('../useSafeLayoutEffect-cjs.js');
18
+ require('../floating-ui.react-cjs.js');
21
19
  require('react-dom');
22
20
  require('../useFocusTrap-cjs.js');
21
+ require('../useIsMounted-cjs.js');
22
+ require('../useSafeLayoutEffect-cjs.js');
23
23
  require('../useFormFieldFocus-cjs.js');
24
24
  require('../Content-cjs.js');
25
25
  require('../Emphasis-cjs.js');
@@ -13,11 +13,11 @@ import '../Menu-es.js';
13
13
  import 'framer-motion';
14
14
  import '../useOnKeyDown-es.js';
15
15
  import '../useRefocusOnActivator-es.js';
16
- import 'react-popper';
17
- import '../useIsMounted-es.js';
18
- import '../useSafeLayoutEffect-es.js';
16
+ import '../floating-ui.react-es.js';
19
17
  import 'react-dom';
20
18
  import '../useFocusTrap-es.js';
19
+ import '../useIsMounted-es.js';
20
+ import '../useSafeLayoutEffect-es.js';
21
21
  import '../useFormFieldFocus-es.js';
22
22
  import '../Content-es.js';
23
23
  import '../Emphasis-es.js';
@@ -11,6 +11,11 @@ export interface HeadingProps {
11
11
  * Allows overriding of the element rendered. Defaults to the heading specified with level.
12
12
  */
13
13
  readonly element?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span";
14
+ /**
15
+ * The maximum amount of lines the text can occupy before being truncated with "...".
16
+ * Uses predefined string values that correspond to a doubling scale for the amount of lines.
17
+ */
18
+ readonly maxLines?: "single" | "small" | "base" | "large" | "larger" | "unlimited";
14
19
  /**
15
20
  * **Use at your own risk:** Custom classNames for specific elements. This should only be used as a
16
21
  * **last resort**. Using this may result in unexpected side effects.
@@ -25,5 +30,5 @@ export interface HeadingProps {
25
30
  readonly UNSAFE_style?: TypographyProps["UNSAFE_style"];
26
31
  }
27
32
  export type LevelMap = Record<HeadingLevel, TypographyOptions>;
28
- export declare function Heading({ level, children, element, UNSAFE_className, UNSAFE_style, }: HeadingProps): React.JSX.Element;
33
+ export declare function Heading({ level, children, element, maxLines, UNSAFE_className, UNSAFE_style, }: HeadingProps): React.JSX.Element;
29
34
  export {};
@@ -3,7 +3,7 @@
3
3
  var React = require('react');
4
4
  var Typography = require('./Typography-cjs.js');
5
5
 
6
- function Heading({ level = 5, children, element, UNSAFE_className, UNSAFE_style, }) {
6
+ function Heading({ level = 5, children, element, maxLines = "unlimited", UNSAFE_className, UNSAFE_style, }) {
7
7
  const levelMap = {
8
8
  1: {
9
9
  element: "h1",
@@ -43,7 +43,15 @@ function Heading({ level = 5, children, element, UNSAFE_className, UNSAFE_style,
43
43
  textColor: "heading",
44
44
  },
45
45
  };
46
- return (React.createElement(Typography.Typography, Object.assign({}, levelMap[level], { element: element || levelMap[level].element, UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }), children));
46
+ const maxLineToNumber = {
47
+ single: 1,
48
+ small: 2,
49
+ base: 4,
50
+ large: 8,
51
+ larger: 16,
52
+ unlimited: undefined,
53
+ };
54
+ return (React.createElement(Typography.Typography, Object.assign({}, levelMap[level], { element: element || levelMap[level].element, numberOfLines: maxLineToNumber[maxLines], UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }), children));
47
55
  }
48
56
 
49
57
  exports.Heading = Heading;
@@ -1,7 +1,7 @@
1
1
  import React__default from 'react';
2
2
  import { T as Typography } from './Typography-es.js';
3
3
 
4
- function Heading({ level = 5, children, element, UNSAFE_className, UNSAFE_style, }) {
4
+ function Heading({ level = 5, children, element, maxLines = "unlimited", UNSAFE_className, UNSAFE_style, }) {
5
5
  const levelMap = {
6
6
  1: {
7
7
  element: "h1",
@@ -41,7 +41,15 @@ function Heading({ level = 5, children, element, UNSAFE_className, UNSAFE_style,
41
41
  textColor: "heading",
42
42
  },
43
43
  };
44
- return (React__default.createElement(Typography, Object.assign({}, levelMap[level], { element: element || levelMap[level].element, UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }), children));
44
+ const maxLineToNumber = {
45
+ single: 1,
46
+ small: 2,
47
+ base: 4,
48
+ large: 8,
49
+ larger: 16,
50
+ unlimited: undefined,
51
+ };
52
+ return (React__default.createElement(Typography, Object.assign({}, levelMap[level], { element: element || levelMap[level].element, numberOfLines: maxLineToNumber[maxLines], UNSAFE_className: UNSAFE_className, UNSAFE_style: UNSAFE_style }), children));
45
53
  }
46
54
 
47
55
  export { Heading as H };
@@ -180,7 +180,7 @@ function dateToTimeString(date) {
180
180
  // Return the time string in HH:MM format
181
181
  return `${hours}:${minutes}`;
182
182
  }
183
- function timeStringToDate(timeString) {
183
+ function timeStringToDate(timeString, baseDate) {
184
184
  try {
185
185
  const [hours, minutes] = timeString.split(":").map(Number);
186
186
  if (isNaN(hours) ||
@@ -191,7 +191,10 @@ function timeStringToDate(timeString) {
191
191
  minutes > 60) {
192
192
  return undefined;
193
193
  }
194
- const date = new Date();
194
+ // Try to preserve the Date part of the Date object as long as it is valid
195
+ const date = baseDate instanceof Date && !isNaN(baseDate.getTime())
196
+ ? new Date(baseDate)
197
+ : new Date();
195
198
  date.setHours(hours, minutes, 0, 0);
196
199
  return date;
197
200
  }
@@ -221,7 +224,7 @@ function InputTimeRebuilt(_a) {
221
224
  handleChange(event.target.value);
222
225
  }
223
226
  function handleChange(newValue) {
224
- onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue));
227
+ onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue, value));
225
228
  }
226
229
  function handleBlur(event) {
227
230
  var _a;
@@ -260,7 +263,7 @@ function InputTime$1(_a) {
260
263
  !isNaN(parseInt(e.key, 10)) && setTypedTime(prev => prev + e.key);
261
264
  }, wrapperRef: wrapperRef })));
262
265
  function handleChange(newValue) {
263
- onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue));
266
+ onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue, value));
264
267
  }
265
268
  function handleBlur() {
266
269
  var _a;
@@ -178,7 +178,7 @@ function dateToTimeString(date) {
178
178
  // Return the time string in HH:MM format
179
179
  return `${hours}:${minutes}`;
180
180
  }
181
- function timeStringToDate(timeString) {
181
+ function timeStringToDate(timeString, baseDate) {
182
182
  try {
183
183
  const [hours, minutes] = timeString.split(":").map(Number);
184
184
  if (isNaN(hours) ||
@@ -189,7 +189,10 @@ function timeStringToDate(timeString) {
189
189
  minutes > 60) {
190
190
  return undefined;
191
191
  }
192
- const date = new Date();
192
+ // Try to preserve the Date part of the Date object as long as it is valid
193
+ const date = baseDate instanceof Date && !isNaN(baseDate.getTime())
194
+ ? new Date(baseDate)
195
+ : new Date();
193
196
  date.setHours(hours, minutes, 0, 0);
194
197
  return date;
195
198
  }
@@ -219,7 +222,7 @@ function InputTimeRebuilt(_a) {
219
222
  handleChange(event.target.value);
220
223
  }
221
224
  function handleChange(newValue) {
222
- onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue));
225
+ onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue, value));
223
226
  }
224
227
  function handleBlur(event) {
225
228
  var _a;
@@ -258,7 +261,7 @@ function InputTime$1(_a) {
258
261
  !isNaN(parseInt(e.key, 10)) && setTypedTime(prev => prev + e.key);
259
262
  }, wrapperRef: wrapperRef })));
260
263
  function handleChange(newValue) {
261
- onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue));
264
+ onChange === null || onChange === void 0 ? void 0 : onChange(timeStringToDate(newValue, value));
262
265
  }
263
266
  function handleBlur() {
264
267
  var _a;
@@ -1,2 +1,2 @@
1
1
  export declare function dateToTimeString(date?: Date): string;
2
- export declare function timeStringToDate(timeString: string): Date | undefined;
2
+ export declare function timeStringToDate(timeString: string, baseDate?: Date): Date | undefined;
@@ -6,11 +6,11 @@ require('classnames');
6
6
  require('framer-motion');
7
7
  require('../useOnKeyDown-cjs.js');
8
8
  require('../useRefocusOnActivator-cjs.js');
9
- require('react-popper');
10
- require('../useIsMounted-cjs.js');
11
- require('../useSafeLayoutEffect-cjs.js');
9
+ require('../floating-ui.react-cjs.js');
12
10
  require('react-dom');
13
11
  require('../useFocusTrap-cjs.js');
12
+ require('../useIsMounted-cjs.js');
13
+ require('../useSafeLayoutEffect-cjs.js');
14
14
  require('../Button-cjs.js');
15
15
  require('react-router-dom');
16
16
  require('../tslib.es6-cjs.js');
@@ -4,11 +4,11 @@ import 'classnames';
4
4
  import 'framer-motion';
5
5
  import '../useOnKeyDown-es.js';
6
6
  import '../useRefocusOnActivator-es.js';
7
- import 'react-popper';
8
- import '../useIsMounted-es.js';
9
- import '../useSafeLayoutEffect-es.js';
7
+ import '../floating-ui.react-es.js';
10
8
  import 'react-dom';
11
9
  import '../useFocusTrap-es.js';
10
+ import '../useIsMounted-es.js';
11
+ import '../useSafeLayoutEffect-es.js';
12
12
  import '../Button-es.js';
13
13
  import 'react-router-dom';
14
14
  import '../tslib.es6-es.js';
package/dist/Menu-cjs.js CHANGED
@@ -5,10 +5,9 @@ var classnames = require('classnames');
5
5
  var framerMotion = require('framer-motion');
6
6
  var useOnKeyDown = require('./useOnKeyDown-cjs.js');
7
7
  var useRefocusOnActivator = require('./useRefocusOnActivator-cjs.js');
8
- var reactPopper = require('react-popper');
9
- var useIsMounted = require('./useIsMounted-cjs.js');
10
- var ReactDOM = require('react-dom');
8
+ var floatingUi_react = require('./floating-ui.react-cjs.js');
11
9
  var useFocusTrap = require('./useFocusTrap-cjs.js');
10
+ var useIsMounted = require('./useIsMounted-cjs.js');
12
11
  var Button = require('./Button-cjs.js');
13
12
  var Typography = require('./Typography-cjs.js');
14
13
  var Icon = require('./Icon-cjs.js');
@@ -44,10 +43,11 @@ function useWindowDimensions() {
44
43
  return windowDimensions;
45
44
  }
46
45
 
47
- var styles = {"wrapper":"fpi0W91w2ag-","popperContainer":"pyIy8jHif3g-","menu":"-DayvgvIcVo-","section":"X0W9r8kjA6Q-","sectionHeader":"Bq7pLWj3jm4-","action":"M1BgN-oCmKw-","destructive":"U9ihZZavz9w-","overlay":"_7we5hh6kYs8-","fullWidth":"_5OJ7B6mFcwk-","screenReaderOnly":"Bzvkz60bwWE-","spinning":"_0-VzuzHdi8o-"};
46
+ var styles = {"wrapper":"fpi0W91w2ag-","floatingContainer":"ba-Kj6mvQUw-","menu":"-DayvgvIcVo-","section":"X0W9r8kjA6Q-","sectionHeader":"Bq7pLWj3jm4-","action":"M1BgN-oCmKw-","destructive":"U9ihZZavz9w-","overlay":"_7we5hh6kYs8-","fullWidth":"_5OJ7B6mFcwk-","screenReaderOnly":"Bzvkz60bwWE-","spinning":"_0-VzuzHdi8o-"};
48
47
 
49
48
  const SMALL_SCREEN_BREAKPOINT = 490;
50
49
  const MENU_OFFSET = 6;
50
+ const MENU_MAX_HEIGHT_VH = 72; // 72vh as percentage
51
51
  const variation = {
52
52
  overlayStartStop: { opacity: 0 },
53
53
  startOrStop: (placement) => {
@@ -64,7 +64,7 @@ const variation = {
64
64
  function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
65
65
  var _a;
66
66
  const [visible, setVisible] = React.useState(false);
67
- const popperRef = React.useRef(null);
67
+ const [referenceElement, setReferenceElement] = React.useState(null);
68
68
  const { width } = useWindowDimensions_2();
69
69
  const buttonID = React.useId();
70
70
  const menuID = React.useId();
@@ -76,32 +76,45 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
76
76
  // useRefocusOnActivator must come before useFocusTrap for them both to work
77
77
  useRefocusOnActivator.useRefocusOnActivator_2(visible);
78
78
  const menuRef = useFocusTrap.useFocusTrap_2(visible);
79
- const [popperElement, setPopperElement] = React.useState(null);
80
- const { styles: popperStyles, attributes, state, } = reactPopper.usePopper(popperRef.current, popperElement, {
79
+ const { refs, floatingStyles, context } = floatingUi_react.useFloating({
80
+ open: visible,
81
+ onOpenChange: setVisible,
81
82
  placement: "bottom-start",
82
83
  strategy: "fixed",
83
- modifiers: [
84
- {
85
- name: "flip",
86
- options: {
87
- flipVariations: true,
84
+ middleware: [
85
+ floatingUi_react.offset(MENU_OFFSET),
86
+ floatingUi_react.flip({ flipAlignment: false }),
87
+ floatingUi_react.size({
88
+ apply({ availableHeight, elements }) {
89
+ // The inner element is the scrollable menu that requires the max height
90
+ const menuElement = elements.floating.querySelector('[role="menu"]');
91
+ if (menuElement) {
92
+ 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);
96
+ Object.assign(menuElement.style, {
97
+ maxHeight: `${maxHeight}px`,
98
+ });
99
+ }
88
100
  },
89
- },
90
- {
91
- name: "offset",
92
- options: {
93
- offset: [0, MENU_OFFSET],
94
- },
95
- },
101
+ }),
96
102
  ],
103
+ elements: {
104
+ reference: referenceElement,
105
+ },
106
+ whileElementsMounted: floatingUi_react.autoUpdate,
97
107
  });
98
108
  const positionAttributes = width >= SMALL_SCREEN_BREAKPOINT
99
- ? Object.assign(Object.assign({}, attributes.popper), { style: popperStyles.popper }) : {};
109
+ ? {
110
+ style: floatingStyles,
111
+ }
112
+ : {};
100
113
  if (!activator) {
101
114
  activator = (React.createElement(Button.Button, { fullWidth: true, label: "More Actions", icon: "more", type: "secondary" }));
102
115
  }
103
116
  return (React.createElement("div", { className: wrapperClasses, onClick: handleParentClick },
104
- React.createElement("div", { ref: popperRef }, React.cloneElement(activator, {
117
+ React.createElement("div", { ref: setReferenceElement }, React.cloneElement(activator, {
105
118
  onClick: toggle(activator.props.onClick),
106
119
  id: buttonID,
107
120
  ariaControls: menuID,
@@ -114,7 +127,7 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
114
127
  type: "tween",
115
128
  duration: 0.15,
116
129
  } }),
117
- React.createElement("div", Object.assign({ ref: setPopperElement, className: styles.popperContainer }, 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: state === null || state === void 0 ? void 0 : state.placement, ref: menuRef, transition: {
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: {
118
131
  type: "tween",
119
132
  duration: 0.25,
120
133
  }, 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 },
@@ -166,7 +179,7 @@ function MenuPortal({ children }) {
166
179
  if (!(mounted === null || mounted === void 0 ? void 0 : mounted.current)) {
167
180
  return null;
168
181
  }
169
- return ReactDOM.createPortal(children, document.body);
182
+ return React.createElement(floatingUi_react.FloatingPortal, null, children);
170
183
  }
171
184
 
172
185
  exports.Menu = Menu;
package/dist/Menu-es.js CHANGED
@@ -1,12 +1,11 @@
1
- import React__default, { useState, useRef, useId } from 'react';
1
+ import React__default, { useState, useId, useRef } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { AnimatePresence, motion } from 'framer-motion';
4
4
  import { u as useOnKeyDown_2 } from './useOnKeyDown-es.js';
5
5
  import { u as useRefocusOnActivator_2 } from './useRefocusOnActivator-es.js';
6
- import { usePopper } from 'react-popper';
7
- import { u as useIsMounted_2 } from './useIsMounted-es.js';
8
- import ReactDOM__default from 'react-dom';
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';
9
7
  import { u as useFocusTrap_2 } from './useFocusTrap-es.js';
8
+ import { u as useIsMounted_2 } from './useIsMounted-es.js';
10
9
  import { B as Button } from './Button-es.js';
11
10
  import { T as Typography } from './Typography-es.js';
12
11
  import { I as Icon } from './Icon-es.js';
@@ -42,10 +41,11 @@ function useWindowDimensions() {
42
41
  return windowDimensions;
43
42
  }
44
43
 
45
- var styles = {"wrapper":"fpi0W91w2ag-","popperContainer":"pyIy8jHif3g-","menu":"-DayvgvIcVo-","section":"X0W9r8kjA6Q-","sectionHeader":"Bq7pLWj3jm4-","action":"M1BgN-oCmKw-","destructive":"U9ihZZavz9w-","overlay":"_7we5hh6kYs8-","fullWidth":"_5OJ7B6mFcwk-","screenReaderOnly":"Bzvkz60bwWE-","spinning":"_0-VzuzHdi8o-"};
44
+ var styles = {"wrapper":"fpi0W91w2ag-","floatingContainer":"ba-Kj6mvQUw-","menu":"-DayvgvIcVo-","section":"X0W9r8kjA6Q-","sectionHeader":"Bq7pLWj3jm4-","action":"M1BgN-oCmKw-","destructive":"U9ihZZavz9w-","overlay":"_7we5hh6kYs8-","fullWidth":"_5OJ7B6mFcwk-","screenReaderOnly":"Bzvkz60bwWE-","spinning":"_0-VzuzHdi8o-"};
46
45
 
47
46
  const SMALL_SCREEN_BREAKPOINT = 490;
48
47
  const MENU_OFFSET = 6;
48
+ const MENU_MAX_HEIGHT_VH = 72; // 72vh as percentage
49
49
  const variation = {
50
50
  overlayStartStop: { opacity: 0 },
51
51
  startOrStop: (placement) => {
@@ -62,7 +62,7 @@ const variation = {
62
62
  function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
63
63
  var _a;
64
64
  const [visible, setVisible] = useState(false);
65
- const popperRef = useRef(null);
65
+ const [referenceElement, setReferenceElement] = useState(null);
66
66
  const { width } = useWindowDimensions_2();
67
67
  const buttonID = useId();
68
68
  const menuID = useId();
@@ -74,32 +74,45 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
74
74
  // useRefocusOnActivator must come before useFocusTrap for them both to work
75
75
  useRefocusOnActivator_2(visible);
76
76
  const menuRef = useFocusTrap_2(visible);
77
- const [popperElement, setPopperElement] = useState(null);
78
- const { styles: popperStyles, attributes, state, } = usePopper(popperRef.current, popperElement, {
77
+ const { refs, floatingStyles, context } = useFloating({
78
+ open: visible,
79
+ onOpenChange: setVisible,
79
80
  placement: "bottom-start",
80
81
  strategy: "fixed",
81
- modifiers: [
82
- {
83
- name: "flip",
84
- options: {
85
- flipVariations: true,
82
+ middleware: [
83
+ offset(MENU_OFFSET),
84
+ flip({ flipAlignment: false }),
85
+ size({
86
+ apply({ availableHeight, elements }) {
87
+ // The inner element is the scrollable menu that requires the max height
88
+ const menuElement = elements.floating.querySelector('[role="menu"]');
89
+ if (menuElement) {
90
+ 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);
94
+ Object.assign(menuElement.style, {
95
+ maxHeight: `${maxHeight}px`,
96
+ });
97
+ }
86
98
  },
87
- },
88
- {
89
- name: "offset",
90
- options: {
91
- offset: [0, MENU_OFFSET],
92
- },
93
- },
99
+ }),
94
100
  ],
101
+ elements: {
102
+ reference: referenceElement,
103
+ },
104
+ whileElementsMounted: autoUpdate,
95
105
  });
96
106
  const positionAttributes = width >= SMALL_SCREEN_BREAKPOINT
97
- ? Object.assign(Object.assign({}, attributes.popper), { style: popperStyles.popper }) : {};
107
+ ? {
108
+ style: floatingStyles,
109
+ }
110
+ : {};
98
111
  if (!activator) {
99
112
  activator = (React__default.createElement(Button, { fullWidth: true, label: "More Actions", icon: "more", type: "secondary" }));
100
113
  }
101
114
  return (React__default.createElement("div", { className: wrapperClasses, onClick: handleParentClick },
102
- React__default.createElement("div", { ref: popperRef }, React__default.cloneElement(activator, {
115
+ React__default.createElement("div", { ref: setReferenceElement }, React__default.cloneElement(activator, {
103
116
  onClick: toggle(activator.props.onClick),
104
117
  id: buttonID,
105
118
  ariaControls: menuID,
@@ -112,7 +125,7 @@ function Menu({ activator, items, UNSAFE_className, UNSAFE_style, }) {
112
125
  type: "tween",
113
126
  duration: 0.15,
114
127
  } }),
115
- React__default.createElement("div", Object.assign({ ref: setPopperElement, className: styles.popperContainer }, 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: state === null || state === void 0 ? void 0 : state.placement, ref: menuRef, transition: {
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: {
116
129
  type: "tween",
117
130
  duration: 0.25,
118
131
  }, 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 },
@@ -164,7 +177,7 @@ function MenuPortal({ children }) {
164
177
  if (!(mounted === null || mounted === void 0 ? void 0 : mounted.current)) {
165
178
  return null;
166
179
  }
167
- return ReactDOM__default.createPortal(children, document.body);
180
+ return React__default.createElement(FloatingPortal, null, children);
168
181
  }
169
182
 
170
183
  export { Menu as M };
@@ -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 { d as useFloatingNodeId, u as useFloating, k as useClick, g as useDismiss, m as useRole, h as useInteractions, c as useFloatingParentNodeId, i as FloatingTree, j as FloatingNode, F as FloatingPortal, n as FloatingOverlay, p as FloatingFocusManager } from '../floating-ui.react-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';
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';
@@ -25,11 +25,11 @@ require('../Menu-cjs.js');
25
25
  require('framer-motion');
26
26
  require('../useOnKeyDown-cjs.js');
27
27
  require('../useRefocusOnActivator-cjs.js');
28
- require('react-popper');
29
- require('../useIsMounted-cjs.js');
30
- require('../useSafeLayoutEffect-cjs.js');
28
+ require('../floating-ui.react-cjs.js');
31
29
  require('react-dom');
32
30
  require('../useFocusTrap-cjs.js');
31
+ require('../useIsMounted-cjs.js');
32
+ require('../useSafeLayoutEffect-cjs.js');
33
33
  require('../useFormFieldFocus-cjs.js');
34
34
 
35
35
 
@@ -23,9 +23,9 @@ import '../Menu-es.js';
23
23
  import 'framer-motion';
24
24
  import '../useOnKeyDown-es.js';
25
25
  import '../useRefocusOnActivator-es.js';
26
- import 'react-popper';
27
- import '../useIsMounted-es.js';
28
- import '../useSafeLayoutEffect-es.js';
26
+ import '../floating-ui.react-es.js';
29
27
  import 'react-dom';
30
28
  import '../useFocusTrap-es.js';
29
+ import '../useIsMounted-es.js';
30
+ import '../useSafeLayoutEffect-es.js';
31
31
  import '../useFormFieldFocus-es.js';
@@ -2,7 +2,7 @@ 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
4
  import ReactDOM__default from 'react-dom';
5
- import { o as offset, s as shift, l as limitShift, e as autoPlacement, f as flip, a as arrow, u as useFloating, b as autoUpdate } from './floating-ui.react-es.js';
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';
6
6
  import { u as useRefocusOnActivator_2 } from './useRefocusOnActivator-es.js';
7
7
  import { A as AtlantisPortalContent } from './AtlantisPortalContent-es.js';
8
8
  import { B as ButtonDismiss } from './ButtonDismiss-es.js';
@@ -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, useFloatingParentNodeId as c, useFloatingNodeId as d, autoPlacement as e, flip as f, useDismiss as g, useInteractions as h, FloatingTree as i, FloatingNode as j, useClick as k, limitShift as l, useRole as m, FloatingOverlay as n, offset as o, FloatingFocusManager as p, size as q, shift as s, useFloating as u };
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 };
package/dist/styles.css CHANGED
@@ -2506,7 +2506,7 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
2506
2506
  position: relative;
2507
2507
  }
2508
2508
 
2509
- .pyIy8jHif3g- {
2509
+ .ba-Kj6mvQUw- {
2510
2510
  z-index: 1001;
2511
2511
  z-index: var(--elevation-modal);
2512
2512
  }
@@ -2516,19 +2516,19 @@ a._7BLGtYNuJOU-.zgRx3ehZ2z8-:hover {
2516
2516
  --menu-offset: var(--space-smallest);
2517
2517
  z-index: 1001;
2518
2518
  z-index: var(--elevation-modal);
2519
- max-height: 72vh;
2520
2519
  box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.1), 0px 4px 12px 0px rgba(0, 0, 0, 0.05);
2521
2520
  box-shadow: var(--shadow-base);
2521
+ box-sizing: border-box;
2522
2522
  padding: 8px;
2523
2523
  padding: var(--menu-space);
2524
2524
  padding-bottom: calc(env(safe-area-inset-bottom) + 8px);
2525
2525
  padding-bottom: calc(env(safe-area-inset-bottom) + var(--menu-space));
2526
2526
  border-radius: 8px 8px 0 0;
2527
2527
  border-radius: var(--radius-base) var(--radius-base) 0 0;
2528
- -webkit-overflow-scrolling: touch;
2529
2528
  overflow-y: scroll;
2530
2529
  background-color: rgba(255, 255, 255, 1);
2531
2530
  background-color: var(--color-surface);
2531
+ -webkit-overflow-scrolling: touch;
2532
2532
  }
2533
2533
 
2534
2534
  @media (max-width: 489px) {
@@ -9,7 +9,7 @@ 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, q as size, b as autoUpdate } from './floating-ui.react-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';
13
13
 
14
14
  var baseEach = _baseEach,
15
15
  isArrayLike = isArrayLike_1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "6.77.0",
3
+ "version": "6.80.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -479,7 +479,7 @@
479
479
  "@types/react-datepicker": "^4.8.0",
480
480
  "@types/react-router": "5.1.7",
481
481
  "@types/react-router-dom": "^5.3.3",
482
- "axios": "^1.6.0",
482
+ "axios": "^1.11.0",
483
483
  "classnames": "^2.3.2",
484
484
  "color": "^3.1.2",
485
485
  "filesize": "^6.1.0",
@@ -523,7 +523,7 @@
523
523
  "@jobber/design": "*",
524
524
  "@jobber/hooks": ">=2",
525
525
  "@tanstack/react-table": "^8",
526
- "axios": "^1",
526
+ "axios": "^1.11.0",
527
527
  "classnames": "^2",
528
528
  "color": "^4",
529
529
  "date-fns": "^2.30.0",
@@ -542,5 +542,5 @@
542
542
  "> 1%",
543
543
  "IE 10"
544
544
  ],
545
- "gitHead": "284376c3bbf5298daf999ad4be17984cf699b73d"
545
+ "gitHead": "fb31413a164542a3481767f2ae2d31c172e86f35"
546
546
  }