@neovici/cosmoz-dropdown 7.4.1 → 7.5.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.
@@ -85,27 +85,31 @@ const style = css `
85
85
  }
86
86
  `;
87
87
  const CosmozDropdownNext = (host) => {
88
- const { placement = 'bottom span-right', openOnHover, openOnFocus } = host;
88
+ const { placement = 'bottom span-right', disabled, openOnHover, openOnFocus, } = host;
89
89
  const popoverRef = useRef();
90
90
  const [opened, setOpened] = useProperty('opened', false);
91
91
  // Call showPopover/hidePopover synchronously so the browser associates
92
92
  // the popover with the current user-gesture. Deferring to a microtask
93
93
  // (useEffect) causes light-dismiss to immediately close the popover.
94
94
  const open = useCallback(() => {
95
+ if (disabled)
96
+ return;
95
97
  setOpened(true);
96
98
  popoverRef.current?.showPopover();
97
- }, []);
99
+ }, [disabled]);
98
100
  const close = useCallback(() => {
99
101
  setOpened(false);
100
102
  popoverRef.current?.hidePopover();
101
103
  }, []);
102
104
  const toggle = useCallback(() => {
105
+ if (disabled)
106
+ return;
103
107
  const popover = popoverRef.current;
104
108
  if (popover?.matches(':popover-open'))
105
109
  close();
106
110
  else
107
111
  open();
108
- }, []);
112
+ }, [disabled]);
109
113
  // Sync native popover when `opened` is set externally via property binding
110
114
  useEffect(() => {
111
115
  const popover = popoverRef.current;
@@ -119,7 +123,15 @@ const CosmozDropdownNext = (host) => {
119
123
  useEffect(() => {
120
124
  host.toggleAttribute('opened', !!opened);
121
125
  }, [opened]);
122
- useAutoOpen({ host, popoverRef, openOnHover, openOnFocus, open, close });
126
+ const { scheduleClose, cancelClose } = useAutoOpen({
127
+ host,
128
+ popoverRef,
129
+ disabled,
130
+ openOnHover,
131
+ openOnFocus,
132
+ open,
133
+ close,
134
+ });
123
135
  // With open-on-focus, only open (not toggle) on click to avoid racing
124
136
  // with the focusin handler
125
137
  const handleClick = openOnFocus ? open : toggle;
@@ -139,6 +151,8 @@ const CosmozDropdownNext = (host) => {
139
151
  style="position-area: ${placement}"
140
152
  @toggle=${onToggle}
141
153
  @select=${close}
154
+ @focusout=${scheduleClose}
155
+ @focusin=${cancelClose}
142
156
  ${ref((el) => el && (popoverRef.current = el))}
143
157
  >
144
158
  <slot></slot>
@@ -147,6 +161,11 @@ const CosmozDropdownNext = (host) => {
147
161
  };
148
162
  customElements.define('cosmoz-dropdown-next', component(CosmozDropdownNext, {
149
163
  styleSheets: [style],
150
- observedAttributes: ['placement', 'open-on-hover', 'open-on-focus'],
164
+ observedAttributes: [
165
+ 'placement',
166
+ 'disabled',
167
+ 'open-on-hover',
168
+ 'open-on-focus',
169
+ ],
151
170
  shadowRootInit: { mode: 'open', delegatesFocus: true },
152
171
  }));
@@ -3,10 +3,14 @@ interface UseAutoOpenOptions {
3
3
  popoverRef: {
4
4
  current?: HTMLElement;
5
5
  };
6
+ disabled?: boolean;
6
7
  openOnHover?: boolean;
7
8
  openOnFocus?: boolean;
8
9
  open: () => void;
9
10
  close: () => void;
10
11
  }
11
- export declare const useAutoOpen: ({ host, popoverRef, openOnHover, openOnFocus, open, close, }: UseAutoOpenOptions) => void;
12
+ export declare const useAutoOpen: ({ host, popoverRef, disabled, openOnHover, openOnFocus, open, close, }: UseAutoOpenOptions) => {
13
+ scheduleClose: () => void;
14
+ cancelClose: () => void;
15
+ };
12
16
  export {};
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useRef } from '@pionjs/pion';
2
- export const useAutoOpen = ({ host, popoverRef, openOnHover, openOnFocus, open, close, }) => {
2
+ export const useAutoOpen = ({ host, popoverRef, disabled, openOnHover, openOnFocus, open, close, }) => {
3
3
  const closeTimeout = useRef();
4
4
  const cancelClose = () => clearTimeout(closeTimeout.current);
5
5
  const scheduleClose = () => {
@@ -10,20 +10,21 @@ export const useAutoOpen = ({ host, popoverRef, openOnHover, openOnFocus, open,
10
10
  (host.matches(':hover') || popover?.matches(':hover'))) {
11
11
  return;
12
12
  }
13
- if (openOnFocus &&
14
- (host.matches(':focus-within') || popover?.matches(':focus-within'))) {
13
+ if (host.matches(':focus-within') || popover?.matches(':focus-within')) {
15
14
  return;
16
15
  }
17
16
  close();
18
17
  }, 100);
19
18
  };
20
19
  const handleEnter = () => {
20
+ if (disabled)
21
+ return;
21
22
  cancelClose();
22
23
  open();
23
24
  };
24
25
  // Auto-open on hover
25
26
  useEffect(() => {
26
- if (!openOnHover)
27
+ if (!openOnHover || disabled)
27
28
  return;
28
29
  host.addEventListener('pointerenter', handleEnter);
29
30
  host.addEventListener('pointerleave', scheduleClose);
@@ -32,10 +33,10 @@ export const useAutoOpen = ({ host, popoverRef, openOnHover, openOnFocus, open,
32
33
  host.removeEventListener('pointerenter', handleEnter);
33
34
  host.removeEventListener('pointerleave', scheduleClose);
34
35
  };
35
- }, [openOnHover, host]);
36
+ }, [openOnHover, disabled, host]);
36
37
  // Auto-open on focus
37
38
  useEffect(() => {
38
- if (!openOnFocus)
39
+ if (!openOnFocus || disabled)
39
40
  return;
40
41
  host.addEventListener('focusin', handleEnter);
41
42
  host.addEventListener('focusout', scheduleClose);
@@ -44,5 +45,6 @@ export const useAutoOpen = ({ host, popoverRef, openOnHover, openOnFocus, open,
44
45
  host.removeEventListener('focusin', handleEnter);
45
46
  host.removeEventListener('focusout', scheduleClose);
46
47
  };
47
- }, [openOnFocus, host]);
48
+ }, [openOnFocus, disabled, host]);
49
+ return { scheduleClose, cancelClose };
48
50
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-dropdown",
3
- "version": "7.4.1",
3
+ "version": "7.5.0",
4
4
  "description": "A simple dropdown web component",
5
5
  "keywords": [
6
6
  "lit-html",