@goplusvn/core 0.1.98 → 0.1.99

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 0.1.99 — Native Event Isolation ngăn chặn hoàn toàn việc Dialog/Sheet cha cướp focus của ô tìm kiếm
2
+
3
+ Khi người dùng click hoặc chạm vào ô tìm kiếm hoặc danh sách của Popover nằm trong Dialog/Sheet/Modal,
4
+ Radix Dialog trên document lắng nghe native pointerdown/touchstart và gọi preventDefault().
5
+ Bằng cách cô lập native event trên cả PopoverContent và SearchInputRef (pointerdown, mousedown, touchstart),
6
+ Dialog cha không bao giờ can thiệp vào các thao tác chạm/click/focus bên trong dropdown.
7
+
8
+ **Đổi**
9
+
10
+ - `ui/primitives/combobox.tsx` & `ui/forms/multi-select.tsx` — bổ sung native event listener `stopPropagation`
11
+ cho `searchInputRef` và `onPointerDownCapture` trên `PopoverContent` + `Input`.
12
+
1
13
  ## 0.1.98 — Chuẩn hóa Modal FocusScope cho Combobox/MultiSelect khi nằm trong Dialog/Sheet/Modal
2
14
 
3
15
  Khi Combobox hoặc MultiSelect nằm trong Modal/Dialog/Sheet (như Modal thanh toán POS hay Sheet bộ lọc nâng cao),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@goplusvn/core",
3
3
  "description": "GoPlusVN Platform Kit - ERP kernel: layout, RBAC, CRUD, multi-tenant, system pages",
4
- "version": "0.1.98",
4
+ "version": "0.1.99",
5
5
  "private": false,
6
6
  "publishConfig": {
7
7
  "registry": "https://registry.npmjs.org",
@@ -414,12 +414,26 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
414
414
  return { start, end };
415
415
  }, [isVirtual, scrollTop, filteredOptions.length]);
416
416
 
417
- // Reset search when dropdown closes
417
+ // Reset search when dropdown closes + Native event isolation cho ô search input
418
+ // Ngăn Radix Dialog's DismissableLayer bắt native pointerdown/touchstart trên document
419
+ // và gọi preventDefault() làm mất focus khi ô input nằm trong Dialog/Sheet/Modal.
418
420
  useEffect(() => {
419
421
  if (!open) {
420
422
  setSearchValue("");
421
423
  setScrollTop(0);
424
+ return;
422
425
  }
426
+ const el = searchInputRef.current;
427
+ if (!el) return;
428
+ const stop = (e: Event) => e.stopPropagation();
429
+ el.addEventListener("pointerdown", stop);
430
+ el.addEventListener("mousedown", stop);
431
+ el.addEventListener("touchstart", stop);
432
+ return () => {
433
+ el.removeEventListener("pointerdown", stop);
434
+ el.removeEventListener("mousedown", stop);
435
+ el.removeEventListener("touchstart", stop);
436
+ };
423
437
  }, [open]);
424
438
 
425
439
  // Reset highlight khi mở/lọc thay đổi
@@ -734,6 +748,10 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
734
748
  e.preventDefault();
735
749
  searchInputRef.current?.focus();
736
750
  }}
751
+ onPointerDownCapture={(e) => {
752
+ // Native event isolation: ngăn Dialog/Sheet cha bắt pointerdown trên document và gọi preventDefault()
753
+ e.stopPropagation();
754
+ }}
737
755
  className="z-[100] flex w-[var(--radix-popover-trigger-width)] min-w-[15rem] max-w-[calc(100vw-1rem)] flex-col overflow-hidden rounded-md border bg-popover/95 p-0 text-popover-foreground shadow-lg shadow-black/5 backdrop-blur-md"
738
756
  style={{
739
757
  maxHeight:
@@ -755,7 +773,13 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
755
773
  onChange={(e) => {
756
774
  setSearchValue(e.target.value);
757
775
  }}
758
- onPointerDown={(e) => {
776
+ onPointerDownCapture={(e) => {
777
+ e.stopPropagation();
778
+ }}
779
+ onMouseDownCapture={(e) => {
780
+ e.stopPropagation();
781
+ }}
782
+ onTouchStartCapture={(e) => {
759
783
  e.stopPropagation();
760
784
  }}
761
785
  onKeyDown={(e) => {
@@ -80,11 +80,25 @@ export function Combobox({
80
80
  });
81
81
  }, [options, searchValue]);
82
82
 
83
- // Reset search when dropdown closes
83
+ // Reset search when dropdown closes + Native event isolation cho ô search input
84
+ // Ngăn Radix Dialog's DismissableLayer bắt native pointerdown/touchstart trên document
85
+ // và gọi preventDefault() làm mất focus khi ô input nằm trong Dialog/Sheet/Modal.
84
86
  useEffect(() => {
85
87
  if (!open) {
86
88
  setSearchValue("");
89
+ return;
87
90
  }
91
+ const el = searchInputRef.current;
92
+ if (!el) return;
93
+ const stop = (e: Event) => e.stopPropagation();
94
+ el.addEventListener("pointerdown", stop);
95
+ el.addEventListener("mousedown", stop);
96
+ el.addEventListener("touchstart", stop);
97
+ return () => {
98
+ el.removeEventListener("pointerdown", stop);
99
+ el.removeEventListener("mousedown", stop);
100
+ el.removeEventListener("touchstart", stop);
101
+ };
88
102
  }, [open]);
89
103
 
90
104
  const handleSelect = useCallback(
@@ -180,6 +194,10 @@ export function Combobox({
180
194
  e.preventDefault();
181
195
  searchInputRef.current?.focus();
182
196
  }}
197
+ onPointerDownCapture={(e) => {
198
+ // Native event isolation: ngăn Dialog/Sheet cha bắt pointerdown trên document và gọi preventDefault()
199
+ e.stopPropagation();
200
+ }}
183
201
  className="z-[100] w-[var(--radix-popover-trigger-width)] min-w-[12rem] max-w-[calc(100vw-1rem)] p-0 flex flex-col overflow-hidden"
184
202
  style={{
185
203
  maxHeight: `min(${maxHeight}, var(--radix-popover-content-available-height, ${maxHeight}))`,
@@ -195,7 +213,13 @@ export function Combobox({
195
213
  onChange={(e) => {
196
214
  setSearchValue(e.target.value);
197
215
  }}
198
- onPointerDown={(e) => {
216
+ onPointerDownCapture={(e) => {
217
+ e.stopPropagation();
218
+ }}
219
+ onMouseDownCapture={(e) => {
220
+ e.stopPropagation();
221
+ }}
222
+ onTouchStartCapture={(e) => {
199
223
  e.stopPropagation();
200
224
  }}
201
225
  onKeyDown={(e) => {
@@ -22,7 +22,7 @@
22
22
  "prepare": "husky || true"
23
23
  },
24
24
  "dependencies": {
25
- "@goerp/core": "npm:@goplusvn/core@^0.1.98",
25
+ "@goerp/core": "npm:@goplusvn/core@^0.1.99",
26
26
  "@hookform/resolvers": "3.9.0",
27
27
  "@prisma/adapter-pg": "^7.0.0",
28
28
  "@prisma/client": "^7.0.0",