@neovici/cosmoz-dropdown 7.4.0 → 7.4.1

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,4 +1,4 @@
1
- import { component, css, useEffect, useProperty, useRef } from '@pionjs/pion';
1
+ import { component, css, useCallback, useEffect, useProperty, useRef, } from '@pionjs/pion';
2
2
  import { html } from 'lit-html';
3
3
  import { ref } from 'lit-html/directives/ref.js';
4
4
  import { useAutoOpen } from './use-auto-open.js';
@@ -88,43 +88,50 @@ const CosmozDropdownNext = (host) => {
88
88
  const { placement = 'bottom span-right', openOnHover, openOnFocus } = host;
89
89
  const popoverRef = useRef();
90
90
  const [opened, setOpened] = useProperty('opened', false);
91
- const open = () => setOpened(true);
92
- const close = () => setOpened(false);
93
- const toggle = () => setOpened((v) => !v);
94
- // Drive the native popover from the `opened` property
91
+ // Call showPopover/hidePopover synchronously so the browser associates
92
+ // the popover with the current user-gesture. Deferring to a microtask
93
+ // (useEffect) causes light-dismiss to immediately close the popover.
94
+ const open = useCallback(() => {
95
+ setOpened(true);
96
+ popoverRef.current?.showPopover();
97
+ }, []);
98
+ const close = useCallback(() => {
99
+ setOpened(false);
100
+ popoverRef.current?.hidePopover();
101
+ }, []);
102
+ const toggle = useCallback(() => {
103
+ const popover = popoverRef.current;
104
+ if (popover?.matches(':popover-open'))
105
+ close();
106
+ else
107
+ open();
108
+ }, []);
109
+ // Sync native popover when `opened` is set externally via property binding
95
110
  useEffect(() => {
96
111
  const popover = popoverRef.current;
97
112
  if (!popover)
98
113
  return;
99
- if (opened && !popover.matches(':popover-open'))
114
+ if (opened)
100
115
  popover.showPopover();
101
- if (!opened && popover.matches(':popover-open'))
116
+ else
102
117
  popover.hidePopover();
103
118
  }, [opened]);
104
- // Attribute reflection — sync property → attribute for CSS selectors.
105
119
  useEffect(() => {
106
120
  host.toggleAttribute('opened', !!opened);
107
121
  }, [opened]);
108
122
  useAutoOpen({ host, popoverRef, openOnHover, openOnFocus, open, close });
109
- // When open-on-focus is active, clicking the button should only open
110
- // (not toggle), since focusin already handles opening and toggle would
111
- // race with the focusin handler (focusin opens, then click toggles closed).
123
+ // With open-on-focus, only open (not toggle) on click to avoid racing
124
+ // with the focusin handler
112
125
  const handleClick = openOnFocus ? open : toggle;
113
- const onToggle = (e) => {
126
+ const onToggle = useCallback((e) => {
114
127
  autofocus(e);
115
- // Sync browser-initiated state changes (light-dismiss, Escape)
116
- // back to the property. The useEffect guards against redundant
117
- // showPopover/hidePopover calls.
118
128
  setOpened(e.newState === 'open');
119
- // Re-dispatch as a composed event so parent components across
120
- // shadow boundaries can observe popover state changes.
121
- // The native ToggleEvent is composed: false, bubbles: false.
122
129
  host.dispatchEvent(new ToggleEvent('dropdown-toggle', {
123
130
  newState: e.newState,
124
131
  oldState: e.oldState,
125
132
  composed: true,
126
133
  }));
127
- };
134
+ }, []);
128
135
  return html `
129
136
  <slot name="button" @click=${handleClick}></slot>
130
137
  <div
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-dropdown",
3
- "version": "7.4.0",
3
+ "version": "7.4.1",
4
4
  "description": "A simple dropdown web component",
5
5
  "keywords": [
6
6
  "lit-html",