@kushagradhawan/kookie-ui 0.1.38 → 0.1.39

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 +1 @@
1
- {"version":3,"file":"use-body-pointer-events-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-body-pointer-events-cleanup.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,2BAA2B,SAkC1C"}
1
+ {"version":3,"file":"use-body-pointer-events-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-body-pointer-events-cleanup.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,2BAA2B,SAqE1C"}
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.create;var i=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var l=Object.getOwnPropertyNames;var r=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var n in t)i(e,n,{get:t[n],enumerable:!0})},a=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of l(t))!u.call(e,o)&&o!==n&&i(e,o,{get:()=>t[o],enumerable:!(s=c(t,o))||s.enumerable});return e};var p=(e,t,n)=>(n=e!=null?d(r(e)):{},a(t||!e||!e.__esModule?i(n,"default",{value:e,enumerable:!0}):n,e)),y=e=>a(i({},"__esModule",{value:!0}),e);var g={};m(g,{useBodyPointerEventsCleanup:()=>f});module.exports=y(g);var v=p(require("react"));function f(){v.useEffect(()=>{const e=()=>{document.body.style.pointerEvents==="none"&&(document.querySelector('[data-state="open"][role="dialog"], [data-state="open"][role="alertdialog"]')||(document.body.style.pointerEvents=""))},t=setTimeout(e,100),n=()=>{document.hidden||setTimeout(e,100)};return document.addEventListener("visibilitychange",n),()=>{clearTimeout(t),document.removeEventListener("visibilitychange",n)}},[])}
1
+ "use strict";var b=Object.create;var i=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var p=(e,t)=>{for(var o in t)i(e,o,{get:t[o],enumerable:!0})},s=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of v(t))!E.call(e,r)&&r!==o&&i(e,r,{get:()=>t[r],enumerable:!(n=y(t,r))||n.enumerable});return e};var w=(e,t,o)=>(o=e!=null?b(f(e)):{},s(t||!e||!e.__esModule?i(o,"default",{value:e,enumerable:!0}):o,e)),L=e=>s(i({},"__esModule",{value:!0}),e);var h={};p(h,{useBodyPointerEventsCleanup:()=>k});module.exports=L(h);var O=w(require("react"));let a=!1;function k(){O.useEffect(()=>{if(typeof document>"u")return;let e;const t=()=>!!document.querySelector('[role="dialog"][aria-modal="true"], [role="alertdialog"][aria-modal="true"]'),o=()=>{document.body.style.pointerEvents==="none"&&!t()&&(document.body.style.pointerEvents="")},n=(d=50)=>{e&&window.clearTimeout(e),e=window.setTimeout(o,d)};if(n(100),a)return()=>{e&&window.clearTimeout(e)};a=!0;const r=()=>n(50),u=d=>{(d.key==="Escape"||d.key==="Enter"||d.key===" ")&&n(50)},c=()=>{document.hidden||n(50)},l=()=>n(0),m=()=>n(0);return document.addEventListener("pointerup",r,!0),document.addEventListener("click",r,!0),document.addEventListener("keydown",u,!0),document.addEventListener("keyup",u,!0),document.addEventListener("visibilitychange",c),document.addEventListener("transitionend",l,!0),document.addEventListener("animationend",m,!0),new MutationObserver(()=>n(0)).observe(document.body,{attributes:!0,attributeFilter:["style"]}),new MutationObserver(()=>n(0)).observe(document,{childList:!0,subtree:!0}),()=>{e&&window.clearTimeout(e)}},[])}
2
2
  //# sourceMappingURL=use-body-pointer-events-cleanup.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/use-body-pointer-events-cleanup.ts"],
4
- "sourcesContent": ["import * as React from 'react';\n\n/**\n * Hook to cleanup stuck pointer-events: none on document.body\n *\n * This addresses an issue where react-remove-scroll (used by Radix UI Dialog)\n * sometimes fails to restore body pointer-events after dialog closes,\n * leaving the page unclickable.\n */\nexport function useBodyPointerEventsCleanup() {\n React.useEffect(() => {\n const cleanup = () => {\n // Only intervene if body has pointer-events: none\n if (document.body.style.pointerEvents === 'none') {\n // Check if there are any actually open dialogs/overlays\n const hasOpenDialogs = document.querySelector(\n '[data-state=\"open\"][role=\"dialog\"], [data-state=\"open\"][role=\"alertdialog\"]',\n );\n\n if (!hasOpenDialogs) {\n // Safe to restore pointer events\n document.body.style.pointerEvents = '';\n }\n }\n };\n\n // Run cleanup after a small delay to allow for state transitions\n const timeoutId = setTimeout(cleanup, 100);\n\n // Also run cleanup on visibility change (tab switching)\n const handleVisibilityChange = () => {\n if (!document.hidden) {\n setTimeout(cleanup, 100);\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, []);\n}\n"],
5
- "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAuB,oBAShB,SAASF,GAA8B,CAC5CE,EAAM,UAAU,IAAM,CACpB,MAAMC,EAAU,IAAM,CAEhB,SAAS,KAAK,MAAM,gBAAkB,SAEjB,SAAS,cAC9B,6EACF,IAIE,SAAS,KAAK,MAAM,cAAgB,IAG1C,EAGMC,EAAY,WAAWD,EAAS,GAAG,EAGnCE,EAAyB,IAAM,CAC9B,SAAS,QACZ,WAAWF,EAAS,GAAG,CAE3B,EAEA,gBAAS,iBAAiB,mBAAoBE,CAAsB,EAE7D,IAAM,CACX,aAAaD,CAAS,EACtB,SAAS,oBAAoB,mBAAoBC,CAAsB,CACzE,CACF,EAAG,CAAC,CAAC,CACP",
6
- "names": ["use_body_pointer_events_cleanup_exports", "__export", "useBodyPointerEventsCleanup", "__toCommonJS", "React", "cleanup", "timeoutId", "handleVisibilityChange"]
4
+ "sourcesContent": ["import * as React from 'react';\n\nlet bodyCleanupInstalled = false;\n\n/**\n * Hook to cleanup stuck pointer-events: none on document.body\n *\n * This addresses an issue where react-remove-scroll (used by Radix UI Dialog)\n * sometimes fails to restore body pointer-events after dialog closes,\n * leaving the page unclickable.\n */\nexport function useBodyPointerEventsCleanup() {\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n\n let timeoutId: number | undefined;\n\n const hasOpenModal = (): boolean => {\n // Detect any open modal dialogs/alertdialogs\n return Boolean(\n document.querySelector(\n '[role=\"dialog\"][aria-modal=\"true\"], [role=\"alertdialog\"][aria-modal=\"true\"]',\n ),\n );\n };\n\n const cleanup = () => {\n if (document.body.style.pointerEvents === 'none' && !hasOpenModal()) {\n document.body.style.pointerEvents = '';\n }\n };\n\n const scheduleCleanup = (delay = 50) => {\n if (timeoutId) window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(cleanup, delay);\n };\n\n // Initial run to catch already-stuck state\n scheduleCleanup(100);\n\n // If already installed globally, don't re-register listeners/observers\n if (bodyCleanupInstalled) {\n return () => {\n if (timeoutId) window.clearTimeout(timeoutId);\n };\n }\n\n bodyCleanupInstalled = true;\n\n const onPointer = () => scheduleCleanup(50);\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' || event.key === 'Enter' || event.key === ' ') scheduleCleanup(50);\n };\n const onVisibility = () => {\n if (!document.hidden) scheduleCleanup(50);\n };\n const onTransitionEnd = () => scheduleCleanup(0);\n const onAnimationEnd = () => scheduleCleanup(0);\n\n // Listen for common interactions that close overlays/menus\n document.addEventListener('pointerup', onPointer, true);\n document.addEventListener('click', onPointer, true);\n document.addEventListener('keydown', onKey, true);\n document.addEventListener('keyup', onKey, true);\n document.addEventListener('visibilitychange', onVisibility);\n document.addEventListener('transitionend', onTransitionEnd, true);\n document.addEventListener('animationend', onAnimationEnd, true);\n\n // Observe body style changes (where pointer-events is applied) and DOM mutations\n const bodyObserver = new MutationObserver(() => scheduleCleanup(0));\n bodyObserver.observe(document.body, { attributes: true, attributeFilter: ['style'] });\n\n const domObserver = new MutationObserver(() => scheduleCleanup(0));\n domObserver.observe(document, { childList: true, subtree: true });\n\n // Keep listeners/observers for the app lifetime to ensure cleanup even after overlays unmount\n return () => {\n if (timeoutId) window.clearTimeout(timeoutId);\n };\n }, []);\n}\n"],
5
+ "mappings": "0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAuB,oBAEvB,IAAIC,EAAuB,GASpB,SAASH,GAA8B,CAC5CE,EAAM,UAAU,IAAM,CACpB,GAAI,OAAO,SAAa,IAAa,OAErC,IAAIE,EAEJ,MAAMC,EAAe,IAEZ,EACL,SAAS,cACP,6EACF,EAIEC,EAAU,IAAM,CAChB,SAAS,KAAK,MAAM,gBAAkB,QAAU,CAACD,EAAa,IAChE,SAAS,KAAK,MAAM,cAAgB,GAExC,EAEME,EAAkB,CAACC,EAAQ,KAAO,CAClCJ,GAAW,OAAO,aAAaA,CAAS,EAC5CA,EAAY,OAAO,WAAWE,EAASE,CAAK,CAC9C,EAMA,GAHAD,EAAgB,GAAG,EAGfJ,EACF,MAAO,IAAM,CACPC,GAAW,OAAO,aAAaA,CAAS,CAC9C,EAGFD,EAAuB,GAEvB,MAAMM,EAAY,IAAMF,EAAgB,EAAE,EACpCG,EAASC,GAAyB,EAClCA,EAAM,MAAQ,UAAYA,EAAM,MAAQ,SAAWA,EAAM,MAAQ,MAAKJ,EAAgB,EAAE,CAC9F,EACMK,EAAe,IAAM,CACpB,SAAS,QAAQL,EAAgB,EAAE,CAC1C,EACMM,EAAkB,IAAMN,EAAgB,CAAC,EACzCO,EAAiB,IAAMP,EAAgB,CAAC,EAG9C,gBAAS,iBAAiB,YAAaE,EAAW,EAAI,EACtD,SAAS,iBAAiB,QAASA,EAAW,EAAI,EAClD,SAAS,iBAAiB,UAAWC,EAAO,EAAI,EAChD,SAAS,iBAAiB,QAASA,EAAO,EAAI,EAC9C,SAAS,iBAAiB,mBAAoBE,CAAY,EAC1D,SAAS,iBAAiB,gBAAiBC,EAAiB,EAAI,EAChE,SAAS,iBAAiB,eAAgBC,EAAgB,EAAI,EAGzC,IAAI,iBAAiB,IAAMP,EAAgB,CAAC,CAAC,EACrD,QAAQ,SAAS,KAAM,CAAE,WAAY,GAAM,gBAAiB,CAAC,OAAO,CAAE,CAAC,EAEhE,IAAI,iBAAiB,IAAMA,EAAgB,CAAC,CAAC,EACrD,QAAQ,SAAU,CAAE,UAAW,GAAM,QAAS,EAAK,CAAC,EAGzD,IAAM,CACPH,GAAW,OAAO,aAAaA,CAAS,CAC9C,CACF,EAAG,CAAC,CAAC,CACP",
6
+ "names": ["use_body_pointer_events_cleanup_exports", "__export", "useBodyPointerEventsCleanup", "__toCommonJS", "React", "bodyCleanupInstalled", "timeoutId", "hasOpenModal", "cleanup", "scheduleCleanup", "delay", "onPointer", "onKey", "event", "onVisibility", "onTransitionEnd", "onAnimationEnd"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-body-pointer-events-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-body-pointer-events-cleanup.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,2BAA2B,SAkC1C"}
1
+ {"version":3,"file":"use-body-pointer-events-cleanup.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-body-pointer-events-cleanup.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AACH,wBAAgB,2BAA2B,SAqE1C"}
@@ -1,2 +1,2 @@
1
- import*as o from"react";function s(){o.useEffect(()=>{const e=()=>{document.body.style.pointerEvents==="none"&&(document.querySelector('[data-state="open"][role="dialog"], [data-state="open"][role="alertdialog"]')||(document.body.style.pointerEvents=""))},n=setTimeout(e,100),t=()=>{document.hidden||setTimeout(e,100)};return document.addEventListener("visibilitychange",t),()=>{clearTimeout(n),document.removeEventListener("visibilitychange",t)}},[])}export{s as useBodyPointerEventsCleanup};
1
+ import*as l from"react";let d=!1;function y(){l.useEffect(()=>{if(typeof document>"u")return;let t;const i=()=>!!document.querySelector('[role="dialog"][aria-modal="true"], [role="alertdialog"][aria-modal="true"]'),u=()=>{document.body.style.pointerEvents==="none"&&!i()&&(document.body.style.pointerEvents="")},e=(n=50)=>{t&&window.clearTimeout(t),t=window.setTimeout(u,n)};if(e(100),d)return()=>{t&&window.clearTimeout(t)};d=!0;const o=()=>e(50),r=n=>{(n.key==="Escape"||n.key==="Enter"||n.key===" ")&&e(50)},s=()=>{document.hidden||e(50)},a=()=>e(0),c=()=>e(0);return document.addEventListener("pointerup",o,!0),document.addEventListener("click",o,!0),document.addEventListener("keydown",r,!0),document.addEventListener("keyup",r,!0),document.addEventListener("visibilitychange",s),document.addEventListener("transitionend",a,!0),document.addEventListener("animationend",c,!0),new MutationObserver(()=>e(0)).observe(document.body,{attributes:!0,attributeFilter:["style"]}),new MutationObserver(()=>e(0)).observe(document,{childList:!0,subtree:!0}),()=>{t&&window.clearTimeout(t)}},[])}export{y as useBodyPointerEventsCleanup};
2
2
  //# sourceMappingURL=use-body-pointer-events-cleanup.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/use-body-pointer-events-cleanup.ts"],
4
- "sourcesContent": ["import * as React from 'react';\n\n/**\n * Hook to cleanup stuck pointer-events: none on document.body\n *\n * This addresses an issue where react-remove-scroll (used by Radix UI Dialog)\n * sometimes fails to restore body pointer-events after dialog closes,\n * leaving the page unclickable.\n */\nexport function useBodyPointerEventsCleanup() {\n React.useEffect(() => {\n const cleanup = () => {\n // Only intervene if body has pointer-events: none\n if (document.body.style.pointerEvents === 'none') {\n // Check if there are any actually open dialogs/overlays\n const hasOpenDialogs = document.querySelector(\n '[data-state=\"open\"][role=\"dialog\"], [data-state=\"open\"][role=\"alertdialog\"]',\n );\n\n if (!hasOpenDialogs) {\n // Safe to restore pointer events\n document.body.style.pointerEvents = '';\n }\n }\n };\n\n // Run cleanup after a small delay to allow for state transitions\n const timeoutId = setTimeout(cleanup, 100);\n\n // Also run cleanup on visibility change (tab switching)\n const handleVisibilityChange = () => {\n if (!document.hidden) {\n setTimeout(cleanup, 100);\n }\n };\n\n document.addEventListener('visibilitychange', handleVisibilityChange);\n\n return () => {\n clearTimeout(timeoutId);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, []);\n}\n"],
5
- "mappings": "AAAA,UAAYA,MAAW,QAShB,SAASC,GAA8B,CAC5CD,EAAM,UAAU,IAAM,CACpB,MAAME,EAAU,IAAM,CAEhB,SAAS,KAAK,MAAM,gBAAkB,SAEjB,SAAS,cAC9B,6EACF,IAIE,SAAS,KAAK,MAAM,cAAgB,IAG1C,EAGMC,EAAY,WAAWD,EAAS,GAAG,EAGnCE,EAAyB,IAAM,CAC9B,SAAS,QACZ,WAAWF,EAAS,GAAG,CAE3B,EAEA,gBAAS,iBAAiB,mBAAoBE,CAAsB,EAE7D,IAAM,CACX,aAAaD,CAAS,EACtB,SAAS,oBAAoB,mBAAoBC,CAAsB,CACzE,CACF,EAAG,CAAC,CAAC,CACP",
6
- "names": ["React", "useBodyPointerEventsCleanup", "cleanup", "timeoutId", "handleVisibilityChange"]
4
+ "sourcesContent": ["import * as React from 'react';\n\nlet bodyCleanupInstalled = false;\n\n/**\n * Hook to cleanup stuck pointer-events: none on document.body\n *\n * This addresses an issue where react-remove-scroll (used by Radix UI Dialog)\n * sometimes fails to restore body pointer-events after dialog closes,\n * leaving the page unclickable.\n */\nexport function useBodyPointerEventsCleanup() {\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n\n let timeoutId: number | undefined;\n\n const hasOpenModal = (): boolean => {\n // Detect any open modal dialogs/alertdialogs\n return Boolean(\n document.querySelector(\n '[role=\"dialog\"][aria-modal=\"true\"], [role=\"alertdialog\"][aria-modal=\"true\"]',\n ),\n );\n };\n\n const cleanup = () => {\n if (document.body.style.pointerEvents === 'none' && !hasOpenModal()) {\n document.body.style.pointerEvents = '';\n }\n };\n\n const scheduleCleanup = (delay = 50) => {\n if (timeoutId) window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(cleanup, delay);\n };\n\n // Initial run to catch already-stuck state\n scheduleCleanup(100);\n\n // If already installed globally, don't re-register listeners/observers\n if (bodyCleanupInstalled) {\n return () => {\n if (timeoutId) window.clearTimeout(timeoutId);\n };\n }\n\n bodyCleanupInstalled = true;\n\n const onPointer = () => scheduleCleanup(50);\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape' || event.key === 'Enter' || event.key === ' ') scheduleCleanup(50);\n };\n const onVisibility = () => {\n if (!document.hidden) scheduleCleanup(50);\n };\n const onTransitionEnd = () => scheduleCleanup(0);\n const onAnimationEnd = () => scheduleCleanup(0);\n\n // Listen for common interactions that close overlays/menus\n document.addEventListener('pointerup', onPointer, true);\n document.addEventListener('click', onPointer, true);\n document.addEventListener('keydown', onKey, true);\n document.addEventListener('keyup', onKey, true);\n document.addEventListener('visibilitychange', onVisibility);\n document.addEventListener('transitionend', onTransitionEnd, true);\n document.addEventListener('animationend', onAnimationEnd, true);\n\n // Observe body style changes (where pointer-events is applied) and DOM mutations\n const bodyObserver = new MutationObserver(() => scheduleCleanup(0));\n bodyObserver.observe(document.body, { attributes: true, attributeFilter: ['style'] });\n\n const domObserver = new MutationObserver(() => scheduleCleanup(0));\n domObserver.observe(document, { childList: true, subtree: true });\n\n // Keep listeners/observers for the app lifetime to ensure cleanup even after overlays unmount\n return () => {\n if (timeoutId) window.clearTimeout(timeoutId);\n };\n }, []);\n}\n"],
5
+ "mappings": "AAAA,UAAYA,MAAW,QAEvB,IAAIC,EAAuB,GASpB,SAASC,GAA8B,CAC5CF,EAAM,UAAU,IAAM,CACpB,GAAI,OAAO,SAAa,IAAa,OAErC,IAAIG,EAEJ,MAAMC,EAAe,IAEZ,EACL,SAAS,cACP,6EACF,EAIEC,EAAU,IAAM,CAChB,SAAS,KAAK,MAAM,gBAAkB,QAAU,CAACD,EAAa,IAChE,SAAS,KAAK,MAAM,cAAgB,GAExC,EAEME,EAAkB,CAACC,EAAQ,KAAO,CAClCJ,GAAW,OAAO,aAAaA,CAAS,EAC5CA,EAAY,OAAO,WAAWE,EAASE,CAAK,CAC9C,EAMA,GAHAD,EAAgB,GAAG,EAGfL,EACF,MAAO,IAAM,CACPE,GAAW,OAAO,aAAaA,CAAS,CAC9C,EAGFF,EAAuB,GAEvB,MAAMO,EAAY,IAAMF,EAAgB,EAAE,EACpCG,EAASC,GAAyB,EAClCA,EAAM,MAAQ,UAAYA,EAAM,MAAQ,SAAWA,EAAM,MAAQ,MAAKJ,EAAgB,EAAE,CAC9F,EACMK,EAAe,IAAM,CACpB,SAAS,QAAQL,EAAgB,EAAE,CAC1C,EACMM,EAAkB,IAAMN,EAAgB,CAAC,EACzCO,EAAiB,IAAMP,EAAgB,CAAC,EAG9C,gBAAS,iBAAiB,YAAaE,EAAW,EAAI,EACtD,SAAS,iBAAiB,QAASA,EAAW,EAAI,EAClD,SAAS,iBAAiB,UAAWC,EAAO,EAAI,EAChD,SAAS,iBAAiB,QAASA,EAAO,EAAI,EAC9C,SAAS,iBAAiB,mBAAoBE,CAAY,EAC1D,SAAS,iBAAiB,gBAAiBC,EAAiB,EAAI,EAChE,SAAS,iBAAiB,eAAgBC,EAAgB,EAAI,EAGzC,IAAI,iBAAiB,IAAMP,EAAgB,CAAC,CAAC,EACrD,QAAQ,SAAS,KAAM,CAAE,WAAY,GAAM,gBAAiB,CAAC,OAAO,CAAE,CAAC,EAEhE,IAAI,iBAAiB,IAAMA,EAAgB,CAAC,CAAC,EACrD,QAAQ,SAAU,CAAE,UAAW,GAAM,QAAS,EAAK,CAAC,EAGzD,IAAM,CACPH,GAAW,OAAO,aAAaA,CAAS,CAC9C,CACF,EAAG,CAAC,CAAC,CACP",
6
+ "names": ["React", "bodyCleanupInstalled", "useBodyPointerEventsCleanup", "timeoutId", "hasOpenModal", "cleanup", "scheduleCleanup", "delay", "onPointer", "onKey", "event", "onVisibility", "onTransitionEnd", "onAnimationEnd"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kushagradhawan/kookie-ui",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "A modern React component library with beautiful design tokens, flexible theming, and comprehensive docs",
5
5
  "keywords": [
6
6
  "react",
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
2
 
3
+ let bodyCleanupInstalled = false;
4
+
3
5
  /**
4
6
  * Hook to cleanup stuck pointer-events: none on document.body
5
7
  *
@@ -9,36 +11,71 @@ import * as React from 'react';
9
11
  */
10
12
  export function useBodyPointerEventsCleanup() {
11
13
  React.useEffect(() => {
14
+ if (typeof document === 'undefined') return;
15
+
16
+ let timeoutId: number | undefined;
17
+
18
+ const hasOpenModal = (): boolean => {
19
+ // Detect any open modal dialogs/alertdialogs
20
+ return Boolean(
21
+ document.querySelector(
22
+ '[role="dialog"][aria-modal="true"], [role="alertdialog"][aria-modal="true"]',
23
+ ),
24
+ );
25
+ };
26
+
12
27
  const cleanup = () => {
13
- // Only intervene if body has pointer-events: none
14
- if (document.body.style.pointerEvents === 'none') {
15
- // Check if there are any actually open dialogs/overlays
16
- const hasOpenDialogs = document.querySelector(
17
- '[data-state="open"][role="dialog"], [data-state="open"][role="alertdialog"]',
18
- );
19
-
20
- if (!hasOpenDialogs) {
21
- // Safe to restore pointer events
22
- document.body.style.pointerEvents = '';
23
- }
28
+ if (document.body.style.pointerEvents === 'none' && !hasOpenModal()) {
29
+ document.body.style.pointerEvents = '';
24
30
  }
25
31
  };
26
32
 
27
- // Run cleanup after a small delay to allow for state transitions
28
- const timeoutId = setTimeout(cleanup, 100);
33
+ const scheduleCleanup = (delay = 50) => {
34
+ if (timeoutId) window.clearTimeout(timeoutId);
35
+ timeoutId = window.setTimeout(cleanup, delay);
36
+ };
29
37
 
30
- // Also run cleanup on visibility change (tab switching)
31
- const handleVisibilityChange = () => {
32
- if (!document.hidden) {
33
- setTimeout(cleanup, 100);
34
- }
38
+ // Initial run to catch already-stuck state
39
+ scheduleCleanup(100);
40
+
41
+ // If already installed globally, don't re-register listeners/observers
42
+ if (bodyCleanupInstalled) {
43
+ return () => {
44
+ if (timeoutId) window.clearTimeout(timeoutId);
45
+ };
46
+ }
47
+
48
+ bodyCleanupInstalled = true;
49
+
50
+ const onPointer = () => scheduleCleanup(50);
51
+ const onKey = (event: KeyboardEvent) => {
52
+ if (event.key === 'Escape' || event.key === 'Enter' || event.key === ' ') scheduleCleanup(50);
35
53
  };
54
+ const onVisibility = () => {
55
+ if (!document.hidden) scheduleCleanup(50);
56
+ };
57
+ const onTransitionEnd = () => scheduleCleanup(0);
58
+ const onAnimationEnd = () => scheduleCleanup(0);
59
+
60
+ // Listen for common interactions that close overlays/menus
61
+ document.addEventListener('pointerup', onPointer, true);
62
+ document.addEventListener('click', onPointer, true);
63
+ document.addEventListener('keydown', onKey, true);
64
+ document.addEventListener('keyup', onKey, true);
65
+ document.addEventListener('visibilitychange', onVisibility);
66
+ document.addEventListener('transitionend', onTransitionEnd, true);
67
+ document.addEventListener('animationend', onAnimationEnd, true);
68
+
69
+ // Observe body style changes (where pointer-events is applied) and DOM mutations
70
+ const bodyObserver = new MutationObserver(() => scheduleCleanup(0));
71
+ bodyObserver.observe(document.body, { attributes: true, attributeFilter: ['style'] });
36
72
 
37
- document.addEventListener('visibilitychange', handleVisibilityChange);
73
+ const domObserver = new MutationObserver(() => scheduleCleanup(0));
74
+ domObserver.observe(document, { childList: true, subtree: true });
38
75
 
76
+ // Keep listeners/observers for the app lifetime to ensure cleanup even after overlays unmount
39
77
  return () => {
40
- clearTimeout(timeoutId);
41
- document.removeEventListener('visibilitychange', handleVisibilityChange);
78
+ if (timeoutId) window.clearTimeout(timeoutId);
42
79
  };
43
80
  }, []);
44
81
  }