@basic-ui/core 0.0.47 → 0.0.49

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.
@@ -1,5 +1,6 @@
1
1
  import type { HTMLAttributes, ElementType, KeyboardEvent } from 'react';
2
2
  import {
3
+ useCallback,
3
4
  forwardRef,
4
5
  useEffect,
5
6
  useRef,
@@ -27,12 +28,14 @@ export const MenuList = forwardRef<HTMLUListElement, MenuListProps>(
27
28
  function MenuList(props, forwardedRef) {
28
29
  const {
29
30
  as: Comp = 'ul',
31
+ innerAs,
30
32
  onKeyDown,
31
33
  id: preferredId,
32
34
  defaultActiveItemValue,
33
35
  ...otherProps
34
36
  } = props;
35
37
 
38
+ const interactedOutside = useRef(false);
36
39
  const itemSearchStr = useRef('');
37
40
  const itemSearchClearTimeout = useRef<ReturnType<typeof setTimeout>>();
38
41
 
@@ -95,28 +98,40 @@ export const MenuList = forwardRef<HTMLUListElement, MenuListProps>(
95
98
  defaultActiveItemValue,
96
99
  ]);
97
100
 
98
- useOnClickOutside(
99
- menuListRef,
100
- (e) => {
101
- console.log(isContextMenu.current);
102
- if (
103
- isContextMenu.current ||
104
- (e.target instanceof HTMLElement &&
101
+ const handleClickOutside = useCallback(
102
+ (e: PointerEvent) => {
103
+ if (isContextMenu.current) {
104
+ if (!interactedOutside.current && e.pointerType === 'touch') {
105
+ // First interaction should be ignored, because
106
+ // this is what triggered the context menu to open
107
+ interactedOutside.current = true;
108
+ return;
109
+ }
110
+
111
+ if (e.button === 0) {
112
+ onChange(e as any, false);
113
+ }
114
+ } else {
115
+ if (
116
+ e.target instanceof HTMLElement &&
105
117
  e.target !== buttonRef.current &&
106
- !buttonRef.current?.contains(e.target))
107
- ) {
108
- onChange && onChange(e as any, false);
118
+ !buttonRef.current?.contains(e.target)
119
+ ) {
120
+ onChange(e as any, false);
121
+ }
109
122
  }
110
123
  e.preventDefault();
111
124
  },
112
- true
125
+ [buttonRef, isContextMenu, onChange]
113
126
  );
114
127
 
128
+ useOnClickOutside(menuListRef, handleClickOutside, open);
129
+
115
130
  function handleKeyDown(e: KeyboardEvent<HTMLUListElement>) {
116
131
  switch (e.key) {
117
132
  case 'Escape':
118
133
  case 'Tab': {
119
- onChange && onChange(e, false);
134
+ onChange(e, false);
120
135
  e.preventDefault(); // prevents focusing on next element, because we will be handling it
121
136
  itemSearchStr.current = '';
122
137
  buttonRef.current?.focus();
@@ -200,6 +215,7 @@ export const MenuList = forwardRef<HTMLUListElement, MenuListProps>(
200
215
  }
201
216
 
202
217
  if (!open) {
218
+ interactedOutside.current = false;
203
219
  return null;
204
220
  }
205
221
 
@@ -212,6 +228,7 @@ export const MenuList = forwardRef<HTMLUListElement, MenuListProps>(
212
228
  >
213
229
  <Comp
214
230
  ref={assignMultipleRefs(forwardedRef, menuListRef)}
231
+ as={innerAs}
215
232
  id={menuListIdRef.current}
216
233
  role="menu"
217
234
  aria-labelledby={buttonRef.current?.id}
@@ -13,7 +13,7 @@ export interface MenuPopoverProps extends Omit<PopperProps, 'anchorEl'> {
13
13
 
14
14
  export const MenuPopover = forwardRef<HTMLDivElement, MenuPopoverProps>(
15
15
  function MenuPopover(props, forwardedRef) {
16
- const { as = 'div', ...otherProps } = props;
16
+ const { as = 'div', innerAs, ...otherProps } = props;
17
17
  const { buttonRef, open, offsetFn, isContextMenu } = useMenuContext();
18
18
 
19
19
  if (!open) {
@@ -23,6 +23,7 @@ export const MenuPopover = forwardRef<HTMLDivElement, MenuPopoverProps>(
23
23
  return (
24
24
  <Popper
25
25
  as={as}
26
+ innerAs={innerAs}
26
27
  ref={forwardedRef}
27
28
  anchorEl={buttonRef}
28
29
  offsetFn={offsetFn}
@@ -1,9 +1,11 @@
1
1
  import type { OffsetsFunction } from '@popperjs/core/lib/modifiers/offset';
2
2
  import type {
3
+ Dispatch,
3
4
  KeyboardEvent,
4
5
  MouseEvent,
5
6
  MutableRefObject,
6
7
  PointerEvent,
8
+ SetStateAction,
7
9
  } from 'react';
8
10
  import { createContext, useContext } from 'react';
9
11
 
@@ -14,7 +16,7 @@ export interface MenuContextProps {
14
16
  buttonRef: MutableRefObject<HTMLElement | null>;
15
17
  menuListIdRef: MutableRefObject<undefined | string>;
16
18
  openWithArrowKeyRef: MutableRefObject<string | null>;
17
- onChange?: (
19
+ onChange: (
18
20
  e:
19
21
  | KeyboardEvent<HTMLElement>
20
22
  | MouseEvent<HTMLElement>
@@ -22,8 +24,8 @@ export interface MenuContextProps {
22
24
  isOpen: boolean
23
25
  ) => void;
24
26
  open: boolean;
25
- offset: MutableRefObject<[number, number]>;
26
- offsetFn: OffsetsFunction;
27
+ offsetFn: OffsetsFunction | undefined;
28
+ setOffsetFn: Dispatch<SetStateAction<OffsetsFunction | undefined>>;
27
29
  isContextMenu: MutableRefObject<boolean>;
28
30
  }
29
31