@tribepad/themis 1.6.5 → 1.6.6

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.
Files changed (87) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/elements/AlertDialog/index.js +1 -1
  3. package/dist/elements/AlertDialog/index.js.map +1 -1
  4. package/dist/elements/AlertDialog/index.mjs +1 -1
  5. package/dist/elements/AlertDialog/index.mjs.map +1 -1
  6. package/dist/elements/Breadcrumbs/index.js +1 -1
  7. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  8. package/dist/elements/Breadcrumbs/index.mjs +1 -1
  9. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  10. package/dist/elements/Combobox/Combobox.d.ts.map +1 -1
  11. package/dist/elements/Combobox/index.js +1 -1
  12. package/dist/elements/Combobox/index.js.map +1 -1
  13. package/dist/elements/Combobox/index.mjs +1 -1
  14. package/dist/elements/Combobox/index.mjs.map +1 -1
  15. package/dist/elements/DatePicker/DatePicker.d.ts.map +1 -1
  16. package/dist/elements/DatePicker/DateRangePicker.d.ts.map +1 -1
  17. package/dist/elements/DatePicker/index.js +1 -1
  18. package/dist/elements/DatePicker/index.js.map +1 -1
  19. package/dist/elements/DatePicker/index.mjs +1 -1
  20. package/dist/elements/DatePicker/index.mjs.map +1 -1
  21. package/dist/elements/Dropdown/Dropdown.d.ts.map +1 -1
  22. package/dist/elements/Dropdown/index.js +1 -1
  23. package/dist/elements/Dropdown/index.js.map +1 -1
  24. package/dist/elements/Dropdown/index.mjs +1 -1
  25. package/dist/elements/Dropdown/index.mjs.map +1 -1
  26. package/dist/elements/Filters/FilterPopover.d.ts.map +1 -1
  27. package/dist/elements/Filters/index.js +1 -1
  28. package/dist/elements/Filters/index.js.map +1 -1
  29. package/dist/elements/Filters/index.mjs +1 -1
  30. package/dist/elements/Filters/index.mjs.map +1 -1
  31. package/dist/elements/Modal/Modal.d.ts +1 -1
  32. package/dist/elements/Modal/Modal.d.ts.map +1 -1
  33. package/dist/elements/Modal/Modal.types.d.ts +2 -0
  34. package/dist/elements/Modal/Modal.types.d.ts.map +1 -1
  35. package/dist/elements/Modal/index.js +1 -1
  36. package/dist/elements/Modal/index.js.map +1 -1
  37. package/dist/elements/Modal/index.mjs +1 -1
  38. package/dist/elements/Modal/index.mjs.map +1 -1
  39. package/dist/elements/PageTitle/index.js +1 -1
  40. package/dist/elements/PageTitle/index.js.map +1 -1
  41. package/dist/elements/PageTitle/index.mjs +1 -1
  42. package/dist/elements/PageTitle/index.mjs.map +1 -1
  43. package/dist/elements/Panel/Panel.d.ts.map +1 -1
  44. package/dist/elements/Panel/index.js +1 -1
  45. package/dist/elements/Panel/index.js.map +1 -1
  46. package/dist/elements/Panel/index.mjs +1 -1
  47. package/dist/elements/Panel/index.mjs.map +1 -1
  48. package/dist/elements/Resizable/components/ResizablePopover.d.ts.map +1 -1
  49. package/dist/elements/Resizable/index.js +1 -1
  50. package/dist/elements/Resizable/index.js.map +1 -1
  51. package/dist/elements/Resizable/index.mjs +1 -1
  52. package/dist/elements/Resizable/index.mjs.map +1 -1
  53. package/dist/elements/Select/Select.d.ts.map +1 -1
  54. package/dist/elements/Select/index.js +1 -1
  55. package/dist/elements/Select/index.js.map +1 -1
  56. package/dist/elements/Select/index.mjs +1 -1
  57. package/dist/elements/Select/index.mjs.map +1 -1
  58. package/dist/elements/Sidebar/SidebarMobileDrawer.d.ts.map +1 -1
  59. package/dist/elements/Sidebar/index.js +1 -1
  60. package/dist/elements/Sidebar/index.js.map +1 -1
  61. package/dist/elements/Sidebar/index.mjs +1 -1
  62. package/dist/elements/Sidebar/index.mjs.map +1 -1
  63. package/dist/elements/Table/index.js +1 -1
  64. package/dist/elements/Table/index.js.map +1 -1
  65. package/dist/elements/Table/index.mjs +1 -1
  66. package/dist/elements/Table/index.mjs.map +1 -1
  67. package/dist/elements/Wizard/index.js +1 -1
  68. package/dist/elements/Wizard/index.js.map +1 -1
  69. package/dist/elements/Wizard/index.mjs +1 -1
  70. package/dist/elements/Wizard/index.mjs.map +1 -1
  71. package/dist/elements/index.js +1 -1
  72. package/dist/elements/index.js.map +1 -1
  73. package/dist/elements/index.mjs +1 -1
  74. package/dist/elements/index.mjs.map +1 -1
  75. package/dist/index.js +2 -2
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.mjs +2 -2
  78. package/dist/index.mjs.map +1 -1
  79. package/dist/utils/browserExtensionOverlay.d.ts +36 -0
  80. package/dist/utils/browserExtensionOverlay.d.ts.map +1 -0
  81. package/dist/utils/index.d.ts +1 -0
  82. package/dist/utils/index.d.ts.map +1 -1
  83. package/dist/utils/index.js +1 -1
  84. package/dist/utils/index.js.map +1 -1
  85. package/dist/utils/index.mjs +1 -1
  86. package/dist/utils/index.mjs.map +1 -1
  87. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- 'use strict';var react=require('react'),reactAriaComponents=require('react-aria-components'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');function d(...e){return tailwindMerge.twMerge(clsx.clsx(e))}var B=classVarianceAuthority.cva(["flex flex-col h-full overflow-hidden","bg-[var(--content-background)] text-[var(--content-foreground)]"],{variants:{position:{right:"border-l border-[var(--border)]",left:"border-r border-[var(--border)]"},width:{sm:"w-[300px]",md:"w-[400px]",lg:"w-[500px]",xl:"w-[600px]",auto:"w-auto"}},defaultVariants:{position:"right",width:"md"}}),O=classVarianceAuthority.cva(["flex items-start justify-between","px-4 py-4","border-b border-[var(--border)]"]),I=classVarianceAuthority.cva(["flex-1 overflow-y-auto","px-4 py-4"]),D=classVarianceAuthority.cva(["flex items-center justify-end gap-2","px-4 py-4","border-t border-[var(--border)]"]),H=classVarianceAuthority.cva(["inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"]),A=react.createContext(null);function f(){let e=react.useContext(A);if(!e)throw new Error("Panel compound components must be used within a Panel");return e}function re(e){let[n,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia(e).matches);return react.useEffect(()=>{if(typeof window>"u")return;let o=window.matchMedia(e);o.matches!==n&&t(o.matches);let r=s=>t(s.matches);return o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e,n]),n}function F({children:e,isOpen:n,defaultOpen:t=false,onOpenChange:o,onClose:r,position:s="right",width:p="md",mobileBreakpoint:l=768}){let[i,g]=react.useState(t),c=n!==void 0,x=c?n:i,v=react.useRef(null),h=react.useId(),U=`panel-${h}`,X=`panel-title-${h}`,b=re(`(max-width: ${l-1}px)`),y=react.useCallback(u=>{c||g(u),o?.(u);},[c,o]),C=react.useCallback(()=>{y(false),r?.(),v.current&&window.requestAnimationFrame(()=>{v.current?.focus();});},[y,r]);react.useEffect(()=>{if(!x||b)return;let u=w=>{w.key==="Escape"&&(w.preventDefault(),C());};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[x,b,C]);let q={isOpen:x,setIsOpen:y,panelId:U,titleId:X,triggerRef:v,position:s,width:p,mobileBreakpoint:l,isMobile:b,handleClose:C};return jsxRuntime.jsx(A.Provider,{value:q,children:e})}F.displayName="Panel";function L({children:e,asChild:n=true}){let{isOpen:t,setIsOpen:o,panelId:r,triggerRef:s}=f(),p=react.useCallback(i=>{s.current=i;},[s]),l=react.useCallback(()=>{o(!t);},[o,t]);if(n&&react.isValidElement(e)){let i=e.props;return react.cloneElement(e,{ref:p,"aria-expanded":t,"aria-controls":t?r:void 0,"data-testid":"panel-trigger",onPress:l,onClick:i.onClick?()=>{i.onClick?.(),l();}:l})}return jsxRuntime.jsx(reactAriaComponents.Button,{ref:p,"aria-expanded":t,"aria-controls":t?r:void 0,onPress:l,"data-testid":"panel-trigger",children:e})}L.displayName="PanelTrigger";function E(){let{handleClose:e}=f();return jsxRuntime.jsx(reactAriaComponents.Button,{"aria-label":"Close panel","data-testid":"panel-close",onPress:e,className:H(),children:jsxRuntime.jsx(lucideReact.X,{className:"h-5 w-5"})})}function j({children:e,showClose:n=true,className:t}){let{isOpen:o,isMobile:r,panelId:s,titleId:p,position:l,width:i,handleClose:g}=f();return o?r?jsxRuntime.jsx(reactAriaComponents.ModalOverlay,{isDismissable:true,isOpen:o,onOpenChange:c=>!c&&g(),className:"fixed inset-0 z-50 bg-black/50",children:jsxRuntime.jsx(reactAriaComponents.Modal,{className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:jsxRuntime.jsxs(reactAriaComponents.Dialog,{"aria-labelledby":p,className:d("w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none","flex max-h-[90vh] flex-col",t),children:[n&&jsxRuntime.jsx("div",{className:"absolute right-2 top-2",children:jsxRuntime.jsx(E,{})}),e]})})}):jsxRuntime.jsxs("aside",{id:s,"aria-labelledby":p,"data-testid":"panel-content",className:d(B({position:l,width:i}),t),children:[e,n&&jsxRuntime.jsx("div",{className:"absolute right-2 top-2",children:jsxRuntime.jsx(E,{})})]}):null}j.displayName="PanelContent";function W({children:e,className:n}){return jsxRuntime.jsx("header",{className:d(O(),n),children:jsxRuntime.jsx("div",{className:"flex flex-col gap-1",children:e})})}W.displayName="PanelHeader";function $({children:e,as:n="h2",className:t}){let{titleId:o}=f();return jsxRuntime.jsx(n,{id:o,"aria-live":"polite",className:d("text-lg font-semibold text-[var(--content-foreground)]",t),children:e})}$.displayName="PanelTitle";function z({children:e,className:n}){return jsxRuntime.jsx("p",{className:d("text-sm text-[var(--menu-muted)]",n),children:e})}z.displayName="PanelDescription";function K({children:e,className:n}){return jsxRuntime.jsx("div",{className:d(I(),n),children:e})}K.displayName="PanelBody";function Q({children:e,className:n}){return jsxRuntime.jsx("footer",{className:d(D(),n),children:e})}Q.displayName="PanelFooter";function S({children:e}){let{handleClose:n}=f();if(!react.isValidElement(e))return null;let t=e.props;return react.cloneElement(e,{onPress:()=>{t.onPress?.(),n();},onClick:()=>{t.onClick?.(),n();}})}S.displayName="PanelClose";var le=Object.assign(F,{Trigger:L,Content:j,Header:W,Title:$,Description:z,Body:K,Footer:Q,Close:S});exports.Panel=le;exports.panelBodyVariants=I;exports.panelCloseButtonVariants=H;exports.panelContentVariants=B;exports.panelFooterVariants=D;exports.panelHeaderVariants=O;//# sourceMappingURL=index.js.map
2
+ 'use strict';var react=require('react'),reactAriaComponents=require('react-aria-components'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');function c(...e){return tailwindMerge.twMerge(clsx.clsx(e))}function Y(e){if(!(e instanceof Element))return false;let n=e;for(let r=0;n&&r<100;r++){let l=n.tagName?.toLowerCase()??"";if(l.startsWith("grammarly-")||l.startsWith("lt-")||n.hasAttribute("data-grammarly-shadow-root"))return true;if(n.parentElement)n=n.parentElement;else {let s=n.getRootNode();n=s instanceof ShadowRoot?s.host:null;}}let t=e;for(;t&&!t.tagName.includes("-");)t=t.parentElement;if(!t)return false;let o=t.parentElement;return o===document.body||o===document.documentElement}function E(e){return n=>!Y(n)&&(e?.(n)??true)}var I=classVarianceAuthority.cva(["flex flex-col h-full overflow-hidden","bg-[var(--content-background)] text-[var(--content-foreground)]"],{variants:{position:{right:"border-l border-[var(--border)]",left:"border-r border-[var(--border)]"},width:{sm:"w-[300px]",md:"w-[400px]",lg:"w-[500px]",xl:"w-[600px]",auto:"w-auto"}},defaultVariants:{position:"right",width:"md"}}),B=classVarianceAuthority.cva(["flex items-start justify-between","px-4 py-4","border-b border-[var(--border)]"]),A=classVarianceAuthority.cva(["flex-1 overflow-y-auto","px-4 py-4"]),D=classVarianceAuthority.cva(["flex items-center justify-end gap-2","px-4 py-4","border-t border-[var(--border)]"]),H=classVarianceAuthority.cva(["inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"]),F=react.createContext(null);function f(){let e=react.useContext(F);if(!e)throw new Error("Panel compound components must be used within a Panel");return e}function se(e){let[n,t]=react.useState(()=>typeof window>"u"?false:window.matchMedia(e).matches);return react.useEffect(()=>{if(typeof window>"u")return;let o=window.matchMedia(e);o.matches!==n&&t(o.matches);let r=l=>t(l.matches);return o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e,n]),n}function L({children:e,isOpen:n,defaultOpen:t=false,onOpenChange:o,onClose:r,position:l="right",width:s="md",mobileBreakpoint:i=768}){let[d,g]=react.useState(t),u=n!==void 0,x=u?n:d,b=react.useRef(null),C=react.useId(),K=`panel-${C}`,Q=`panel-title-${C}`,v=se(`(max-width: ${i-1}px)`),h=react.useCallback(p=>{u||g(p),o?.(p);},[u,o]),y=react.useCallback(()=>{h(false),r?.(),b.current&&window.requestAnimationFrame(()=>{b.current?.focus();});},[h,r]);react.useEffect(()=>{if(!x||v)return;let p=w=>{w.key==="Escape"&&(w.preventDefault(),y());};return document.addEventListener("keydown",p),()=>document.removeEventListener("keydown",p)},[x,v,y]);let U={isOpen:x,setIsOpen:h,panelId:K,titleId:Q,triggerRef:b,position:l,width:s,mobileBreakpoint:i,isMobile:v,handleClose:y};return jsxRuntime.jsx(F.Provider,{value:U,children:e})}L.displayName="Panel";function j({children:e,asChild:n=true}){let{isOpen:t,setIsOpen:o,panelId:r,triggerRef:l}=f(),s=react.useCallback(d=>{l.current=d;},[l]),i=react.useCallback(()=>{o(!t);},[o,t]);if(n&&react.isValidElement(e)){let d=e.props;return react.cloneElement(e,{ref:s,"aria-expanded":t,"aria-controls":t?r:void 0,"data-testid":"panel-trigger",onPress:i,onClick:d.onClick?()=>{d.onClick?.(),i();}:i})}return jsxRuntime.jsx(reactAriaComponents.Button,{ref:s,"aria-expanded":t,"aria-controls":t?r:void 0,onPress:i,"data-testid":"panel-trigger",children:e})}j.displayName="PanelTrigger";function N(){let{handleClose:e}=f();return jsxRuntime.jsx(reactAriaComponents.Button,{"aria-label":"Close panel","data-testid":"panel-close",onPress:e,className:H(),children:jsxRuntime.jsx(lucideReact.X,{className:"h-5 w-5"})})}function W({children:e,showClose:n=true,className:t}){let{isOpen:o,isMobile:r,panelId:l,titleId:s,position:i,width:d,handleClose:g}=f();return o?r?jsxRuntime.jsx(reactAriaComponents.ModalOverlay,{isDismissable:true,shouldCloseOnInteractOutside:E(),isOpen:o,onOpenChange:u=>!u&&g(),className:"fixed inset-0 z-50 bg-black/50",children:jsxRuntime.jsx(reactAriaComponents.Modal,{className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:jsxRuntime.jsxs(reactAriaComponents.Dialog,{"aria-labelledby":s,className:c("w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none","flex max-h-[90vh] flex-col",t),children:[n&&jsxRuntime.jsx("div",{className:"absolute right-2 top-2",children:jsxRuntime.jsx(N,{})}),e]})})}):jsxRuntime.jsxs("aside",{id:l,"aria-labelledby":s,"data-testid":"panel-content",className:c(I({position:i,width:d}),t),children:[e,n&&jsxRuntime.jsx("div",{className:"absolute right-2 top-2",children:jsxRuntime.jsx(N,{})})]}):null}W.displayName="PanelContent";function S({children:e,className:n}){return jsxRuntime.jsx("header",{className:c(B(),n),children:jsxRuntime.jsx("div",{className:"flex flex-col gap-1",children:e})})}S.displayName="PanelHeader";function _({children:e,as:n="h2",className:t}){let{titleId:o}=f();return jsxRuntime.jsx(n,{id:o,"aria-live":"polite",className:c("text-lg font-semibold text-[var(--content-foreground)]",t),children:e})}_.displayName="PanelTitle";function X({children:e,className:n}){return jsxRuntime.jsx("p",{className:c("text-sm text-[var(--menu-muted)]",n),children:e})}X.displayName="PanelDescription";function $({children:e,className:n}){return jsxRuntime.jsx("div",{className:c(A(),n),children:e})}$.displayName="PanelBody";function z({children:e,className:n}){return jsxRuntime.jsx("footer",{className:c(D(),n),children:e})}z.displayName="PanelFooter";function G({children:e}){let{handleClose:n}=f();if(!react.isValidElement(e))return null;let t=e.props;return react.cloneElement(e,{onPress:()=>{t.onPress?.(),n();},onClick:()=>{t.onClick?.(),n();}})}G.displayName="PanelClose";var ie=Object.assign(L,{Trigger:j,Content:W,Header:S,Title:_,Description:X,Body:$,Footer:z,Close:G});exports.Panel=ie;exports.panelBodyVariants=A;exports.panelCloseButtonVariants=H;exports.panelContentVariants=I;exports.panelFooterVariants=D;exports.panelHeaderVariants=B;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Panel/Panel.tsx"],"names":["cn","inputs","twMerge","clsx","panelContentVariants","cva","panelHeaderVariants","panelBodyVariants","panelFooterVariants","panelCloseButtonVariants","PanelContext","createContext","usePanelContext","context","useContext","useMediaQuery","query","matches","setMatches","useState","useEffect","media","listener","e","PanelRoot","children","controlledIsOpen","defaultOpen","onOpenChange","onClose","position","width","mobileBreakpoint","uncontrolledIsOpen","setUncontrolledIsOpen","isControlled","isOpen","triggerRef","useRef","uniqueId","useId","panelId","titleId","isMobile","setIsOpen","useCallback","open","handleClose","handleKeyDown","contextValue","jsx","PanelTrigger","asChild","setRef","element","handlePress","isValidElement","childProps","cloneElement","AriaButton","BuiltInCloseButton","X","PanelContent","showClose","className","AriaModalOverlay","AriaModal","jsxs","AriaDialog","PanelHeader","PanelTitle","Tag","PanelDescription","PanelBody","PanelFooter","PanelClose","Panel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\n/**\n * Panel Component - Accessible Non-Modal Sidebar\n * Disclosure pattern + Complementary region for WCAG 2.2 AAA\n *\n * @see plan.md for architecture details\n * @see panel-prd.md for requirements\n * @see ADR 0007 for accessibility decisions\n */\n\nimport {\n type ReactElement,\n type MutableRefObject,\n createContext,\n useContext,\n useState,\n useId,\n useRef,\n useCallback,\n useEffect,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport {\n Button as AriaButton,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n} from \"react-aria-components\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type {\n PanelProps,\n PanelTriggerProps,\n PanelContentProps,\n PanelHeaderProps,\n PanelTitleProps,\n PanelDescriptionProps,\n PanelBodyProps,\n PanelFooterProps,\n PanelCloseProps,\n PanelPosition,\n PanelWidth,\n} from \"./Panel.types\";\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * Panel content variants\n * Controls position-based styling and width\n */\nexport const panelContentVariants = cva(\n [\n \"flex flex-col h-full overflow-hidden\",\n \"bg-[var(--content-background)] text-[var(--content-foreground)]\",\n ],\n {\n variants: {\n position: {\n right: \"border-l border-[var(--border)]\",\n left: \"border-r border-[var(--border)]\",\n },\n width: {\n sm: \"w-[300px]\",\n md: \"w-[400px]\",\n lg: \"w-[500px]\",\n xl: \"w-[600px]\",\n auto: \"w-auto\",\n },\n },\n defaultVariants: {\n position: \"right\",\n width: \"md\",\n },\n }\n);\n\n/**\n * Panel header variants\n */\nexport const panelHeaderVariants = cva([\n \"flex items-start justify-between\",\n \"px-4 py-4\",\n \"border-b border-[var(--border)]\",\n]);\n\n/**\n * Panel body variants\n */\nexport const panelBodyVariants = cva([\"flex-1 overflow-y-auto\", \"px-4 py-4\"]);\n\n/**\n * Panel footer variants\n */\nexport const panelFooterVariants = cva([\n \"flex items-center justify-end gap-2\",\n \"px-4 py-4\",\n \"border-t border-[var(--border)]\",\n]);\n\n/**\n * Close button variants\n */\nexport const panelCloseButtonVariants = cva([\n \"inline-flex items-center justify-center rounded-md\",\n \"min-h-[44px] min-w-[44px]\",\n \"text-[var(--menu-muted)]\",\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2\",\n // No transition - instant state changes (v1)\n]);\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface PanelContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n panelId: string;\n titleId: string;\n triggerRef: MutableRefObject<HTMLElement | null>;\n position: PanelPosition;\n width: PanelWidth;\n mobileBreakpoint: number;\n isMobile: boolean;\n handleClose: () => void;\n}\n\nconst PanelContext = createContext<PanelContextValue | null>(null);\n\nfunction usePanelContext(): PanelContextValue {\n const context = useContext(PanelContext);\n if (!context) {\n throw new Error(\"Panel compound components must be used within a Panel\");\n }\n return context;\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * SSR-safe media query hook\n * Defaults to false on server (desktop mode)\n */\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n // Default to false on server (desktop mode)\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const media = window.matchMedia(query);\n // Sync state after mount (handles SSR mismatch)\n if (media.matches !== matches) {\n setMatches(media.matches);\n }\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\n media.addEventListener(\"change\", listener);\n return () => media.removeEventListener(\"change\", listener);\n }, [query, matches]);\n\n return matches;\n}\n\n// ============================================================================\n// Panel Root\n// ============================================================================\n\nfunction PanelRoot({\n children,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n onClose,\n position = \"right\",\n width = \"md\",\n mobileBreakpoint = 768,\n}: PanelProps): ReactElement {\n // State management (controlled/uncontrolled)\n const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(defaultOpen);\n const isControlled = controlledIsOpen !== undefined;\n const isOpen = isControlled ? controlledIsOpen : uncontrolledIsOpen;\n\n // Refs\n const triggerRef = useRef<HTMLElement | null>(null);\n\n // IDs for ARIA\n const uniqueId = useId();\n const panelId = `panel-${uniqueId}`;\n const titleId = `panel-title-${uniqueId}`;\n\n // Responsive detection\n const isMobile = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);\n\n // State setter\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (!isControlled) {\n setUncontrolledIsOpen(open);\n }\n onOpenChange?.(open);\n },\n [isControlled, onOpenChange]\n );\n\n // Close handler with focus restoration\n const handleClose = useCallback(() => {\n setIsOpen(false);\n onClose?.();\n // Return focus to trigger if it still exists in DOM\n if (triggerRef.current) {\n window.requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n }\n }, [setIsOpen, onClose]);\n\n // Escape key handler (desktop only - mobile handled by React Aria)\n useEffect(() => {\n if (!isOpen || isMobile) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, isMobile, handleClose]);\n\n const contextValue: PanelContextValue = {\n isOpen,\n setIsOpen,\n panelId,\n titleId,\n triggerRef,\n position,\n width,\n mobileBreakpoint,\n isMobile,\n handleClose,\n };\n\n return (\n <PanelContext.Provider value={contextValue}>\n {children}\n </PanelContext.Provider>\n );\n}\nPanelRoot.displayName = \"Panel\";\n\n// ============================================================================\n// Panel.Trigger\n// ============================================================================\n\nfunction PanelTrigger({\n children,\n asChild = true,\n}: PanelTriggerProps): ReactElement | null {\n const { isOpen, setIsOpen, panelId, triggerRef } = usePanelContext();\n\n // Capture ref via callback ref pattern\n const setRef = useCallback(\n (element: HTMLElement | null) => {\n triggerRef.current = element;\n },\n [triggerRef]\n );\n\n const handlePress = useCallback(() => {\n setIsOpen(!isOpen);\n }, [setIsOpen, isOpen]);\n\n // If asChild, clone the child element and add props\n if (asChild && isValidElement(children)) {\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n return cloneElement(children, {\n ref: setRef,\n \"aria-expanded\": isOpen,\n \"aria-controls\": isOpen ? panelId : undefined,\n \"data-testid\": \"panel-trigger\",\n onPress: handlePress,\n onClick: childProps.onClick\n ? () => {\n childProps.onClick?.();\n handlePress();\n }\n : handlePress,\n } as unknown as Record<string, unknown>);\n }\n\n // Fallback: wrap in AriaButton\n return (\n <AriaButton\n ref={setRef}\n aria-expanded={isOpen}\n aria-controls={isOpen ? panelId : undefined}\n onPress={handlePress}\n data-testid=\"panel-trigger\"\n >\n {children}\n </AriaButton>\n );\n}\nPanelTrigger.displayName = \"PanelTrigger\";\n\n// ============================================================================\n// Built-in Close Button\n// ============================================================================\n\nfunction BuiltInCloseButton(): ReactElement {\n const { handleClose } = usePanelContext();\n\n return (\n <AriaButton\n aria-label=\"Close panel\"\n data-testid=\"panel-close\"\n onPress={handleClose}\n className={panelCloseButtonVariants()}\n >\n <X className=\"h-5 w-5\" />\n </AriaButton>\n );\n}\n\n// ============================================================================\n// Panel.Content\n// ============================================================================\n\nfunction PanelContent({\n children,\n showClose = true,\n className,\n}: PanelContentProps): ReactElement | null {\n const { isOpen, isMobile, panelId, titleId, position, width, handleClose } =\n usePanelContext();\n\n if (!isOpen) return null;\n\n // Mobile: Use React Aria Modal primitives\n if (isMobile) {\n return (\n <AriaModalOverlay\n isDismissable\n isOpen={isOpen}\n onOpenChange={(open) => !open && handleClose()}\n className=\"fixed inset-0 z-50 bg-black/50\"\n >\n <AriaModal className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <AriaDialog\n aria-labelledby={titleId}\n className={cn(\n \"w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none\",\n \"flex max-h-[90vh] flex-col\",\n className\n )}\n >\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n {children}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n }\n\n // Desktop: Render aside in-place\n return (\n <aside\n id={panelId}\n aria-labelledby={titleId}\n data-testid=\"panel-content\"\n className={cn(panelContentVariants({ position, width }), className)}\n >\n {children}\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n </aside>\n );\n}\nPanelContent.displayName = \"PanelContent\";\n\n// ============================================================================\n// Panel.Header\n// ============================================================================\n\nfunction PanelHeader({\n children,\n className,\n}: PanelHeaderProps): ReactElement | null {\n // Note: We use a <header> element but DON'T add role=\"banner\"\n // because banner landmarks should not be contained in other landmarks (like aside)\n // The header element still provides structural meaning for the panel\n return (\n <header className={cn(panelHeaderVariants(), className)}>\n <div className=\"flex flex-col gap-1\">{children}</div>\n </header>\n );\n}\nPanelHeader.displayName = \"PanelHeader\";\n\n// ============================================================================\n// Panel.Title\n// ============================================================================\n\nfunction PanelTitle({\n children,\n as: Tag = \"h2\",\n className,\n}: PanelTitleProps): ReactElement | null {\n const { titleId } = usePanelContext();\n\n return (\n <Tag\n id={titleId}\n // aria-live=\"polite\" announces title changes to screen readers\n // This is important for master-detail patterns where panel content\n // updates when selecting different items (e.g., candidate profiles)\n aria-live=\"polite\"\n className={cn(\n \"text-lg font-semibold text-[var(--content-foreground)]\",\n className\n )}\n >\n {children}\n </Tag>\n );\n}\nPanelTitle.displayName = \"PanelTitle\";\n\n// ============================================================================\n// Panel.Description\n// ============================================================================\n\nfunction PanelDescription({\n children,\n className,\n}: PanelDescriptionProps): ReactElement | null {\n return (\n <p className={cn(\"text-sm text-[var(--menu-muted)]\", className)}>\n {children}\n </p>\n );\n}\nPanelDescription.displayName = \"PanelDescription\";\n\n// ============================================================================\n// Panel.Body\n// ============================================================================\n\nfunction PanelBody({ children, className }: PanelBodyProps): ReactElement | null {\n return <div className={cn(panelBodyVariants(), className)}>{children}</div>;\n}\nPanelBody.displayName = \"PanelBody\";\n\n// ============================================================================\n// Panel.Footer\n// ============================================================================\n\nfunction PanelFooter({\n children,\n className,\n}: PanelFooterProps): ReactElement | null {\n // Note: We use a <footer> element but DON'T add role=\"contentinfo\"\n // because contentinfo landmarks should not be contained in other landmarks (like aside)\n // The footer element still provides structural meaning for the panel\n return (\n <footer className={cn(panelFooterVariants(), className)}>\n {children}\n </footer>\n );\n}\nPanelFooter.displayName = \"PanelFooter\";\n\n// ============================================================================\n// Panel.Close\n// ============================================================================\n\nfunction PanelClose({ children }: PanelCloseProps): ReactElement | null {\n const { handleClose } = usePanelContext();\n\n if (!isValidElement(children)) {\n return null;\n }\n\n // Clone the child and add onPress/onClick handler\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n\n return cloneElement(children, {\n onPress: () => {\n childProps.onPress?.();\n handleClose();\n },\n onClick: () => {\n childProps.onClick?.();\n handleClose();\n },\n } as unknown as Record<string, unknown>);\n}\nPanelClose.displayName = \"PanelClose\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Panel Component\n *\n * Accessible non-modal sidebar panel using the disclosure pattern with\n * a complementary region for WCAG 2.2 AAA compliance.\n *\n * @example\n * ```tsx\n * <Panel>\n * <Panel.Trigger>\n * <Button>Open Panel</Button>\n * </Panel.Trigger>\n * <Panel.Content>\n * <Panel.Header>\n * <Panel.Title>Panel Title</Panel.Title>\n * <Panel.Description>Optional description</Panel.Description>\n * </Panel.Header>\n * <Panel.Body>\n * Panel content here\n * </Panel.Body>\n * <Panel.Footer>\n * <Button>Action</Button>\n * </Panel.Footer>\n * </Panel.Content>\n * </Panel>\n * ```\n */\nexport const Panel = Object.assign(PanelRoot, {\n Trigger: PanelTrigger,\n Content: PanelContent,\n Header: PanelHeader,\n Title: PanelTitle,\n Description: PanelDescription,\n Body: PanelBody,\n Footer: PanelFooter,\n Close: PanelClose,\n});\n\n// Named exports for individual components\nexport {\n PanelRoot,\n PanelTrigger,\n PanelContent,\n PanelHeader,\n PanelTitle,\n PanelDescription,\n PanelBody,\n PanelFooter,\n PanelClose,\n};\n\n// Export CVA variant types for customization\nexport type PanelContentVariants = VariantProps<typeof panelContentVariants>;\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/utils/browserExtensionOverlay.ts","../../../src/elements/Panel/Panel.tsx"],"names":["cn","inputs","twMerge","clsx","isExtensionInjectedElement","element","node","depth","tag","root","custom","parent","createInteractOutsideGuard","consumerShouldClose","panelContentVariants","cva","panelHeaderVariants","panelBodyVariants","panelFooterVariants","panelCloseButtonVariants","PanelContext","createContext","usePanelContext","context","useContext","useMediaQuery","query","matches","setMatches","useState","useEffect","media","listener","e","PanelRoot","children","controlledIsOpen","defaultOpen","onOpenChange","onClose","position","width","mobileBreakpoint","uncontrolledIsOpen","setUncontrolledIsOpen","isControlled","isOpen","triggerRef","useRef","uniqueId","useId","panelId","titleId","isMobile","setIsOpen","useCallback","open","handleClose","handleKeyDown","contextValue","jsx","PanelTrigger","asChild","setRef","handlePress","isValidElement","childProps","cloneElement","AriaButton","BuiltInCloseButton","X","PanelContent","showClose","className","AriaModalOverlay","AriaModal","jsxs","AriaDialog","PanelHeader","PanelTitle","Tag","PanelDescription","PanelBody","PanelFooter","PanelClose","Panel"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Detection + dismissal guard for in-page writing-assistant browser extensions\n * (Grammarly, LanguageTool, Wordtune, …).\n *\n * These extensions inject their suggestion UI as elements appended to `<body>`,\n * outside any open overlay's DOM subtree. React Aria's `isDismissable` behaviour\n * treats a click on that injected UI as an \"outside click\" and dismisses the\n * overlay — so clicking a spelling suggestion silently closes the form pop-up\n * and discards the user's in-progress correction.\n *\n * The guard below lets overlays keep open when the interaction lands on an\n * extension-injected node, while every other outside click, Escape, and the\n * close button behave exactly as before.\n */\n\nconst MAX_ANCESTOR_DEPTH = 100;\n\n/**\n * Returns `true` when `element` belongs to an injected in-page writing\n * assistant (Grammarly, LanguageTool, Wordtune, …).\n *\n * UX-ONLY heuristic. This is a deliberately spoofable DOM sniff used solely to\n * keep a form pop-up open when a writing-assistant suggestion is clicked. It is\n * NOT a security/authorization control and must never gate access to data or\n * actions (the frontend is not a security boundary). Pure function — never log\n * the element (it can reference arbitrary DOM / user content).\n */\nexport function isExtensionInjectedElement(element: Element): boolean {\n if (!(element instanceof Element)) return false;\n\n // 1. Known-vendor markers (authoritative). Walk up via parentElement, and\n // climb shadow boundaries via getRootNode().host so detection still finds\n // the <grammarly-extension> host if React Aria's shadowDOM flag is ever\n // enabled (it defaults to false today → the document-level listener\n // already receives the retargeted host, so the parentElement walk alone\n // suffices currently). Depth-bounded as a defensive guard against a\n // crafted/overridden getRootNode/host returning a cycle (which would\n // otherwise hang the tab — a client-side DoS).\n let node: Element | null = element;\n for (let depth = 0; node && depth < MAX_ANCESTOR_DEPTH; depth++) {\n const tag = node.tagName?.toLowerCase() ?? '';\n if (tag.startsWith('grammarly-')) return true; // Grammarly\n if (tag.startsWith('lt-')) return true; // LanguageTool\n if (node.hasAttribute('data-grammarly-shadow-root')) return true;\n\n if (node.parentElement) {\n node = node.parentElement;\n } else {\n const root = node.getRootNode();\n node = root instanceof ShadowRoot ? root.host : null;\n }\n }\n\n // 2. Structural fallback (best-effort, future-proofs the long tail).\n // Extensions inject their UI as a custom element (hyphenated tag name)\n // mounted as a top-level sibling of the React root — i.e. a direct child\n // of <body>/<html>. Our app never renders body-level custom elements, and\n // React Aria portals render plain <div>s, so this stays safe for any\n // future first-party web component nested inside the app tree.\n let custom: Element | null = element;\n while (custom && !custom.tagName.includes('-')) {\n custom = custom.parentElement;\n }\n if (!custom) return false;\n\n const parent = custom.parentElement;\n return parent === document.body || parent === document.documentElement;\n}\n\n/**\n * Builds a `shouldCloseOnInteractOutside` predicate for React Aria overlays\n * that keeps the overlay open when the interaction targets an extension-injected\n * element, while preserving any consumer-supplied predicate.\n *\n * React Aria semantics: the predicate returns `true` ⇒ the overlay should\n * close. So we close only when the element is NOT extension-injected AND the\n * consumer (if any) also agrees it should close.\n */\nexport function createInteractOutsideGuard(\n consumerShouldClose?: (element: Element) => boolean,\n): (element: Element) => boolean {\n return (element: Element): boolean =>\n !isExtensionInjectedElement(element) && (consumerShouldClose?.(element) ?? true);\n}\n","\"use client\";\n\n/**\n * Panel Component - Accessible Non-Modal Sidebar\n * Disclosure pattern + Complementary region for WCAG 2.2 AAA\n *\n * @see plan.md for architecture details\n * @see panel-prd.md for requirements\n * @see ADR 0007 for accessibility decisions\n */\n\nimport {\n type ReactElement,\n type MutableRefObject,\n createContext,\n useContext,\n useState,\n useId,\n useRef,\n useCallback,\n useEffect,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport {\n Button as AriaButton,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n} from \"react-aria-components\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { createInteractOutsideGuard } from \"../../utils/browserExtensionOverlay\";\nimport type {\n PanelProps,\n PanelTriggerProps,\n PanelContentProps,\n PanelHeaderProps,\n PanelTitleProps,\n PanelDescriptionProps,\n PanelBodyProps,\n PanelFooterProps,\n PanelCloseProps,\n PanelPosition,\n PanelWidth,\n} from \"./Panel.types\";\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * Panel content variants\n * Controls position-based styling and width\n */\nexport const panelContentVariants = cva(\n [\n \"flex flex-col h-full overflow-hidden\",\n \"bg-[var(--content-background)] text-[var(--content-foreground)]\",\n ],\n {\n variants: {\n position: {\n right: \"border-l border-[var(--border)]\",\n left: \"border-r border-[var(--border)]\",\n },\n width: {\n sm: \"w-[300px]\",\n md: \"w-[400px]\",\n lg: \"w-[500px]\",\n xl: \"w-[600px]\",\n auto: \"w-auto\",\n },\n },\n defaultVariants: {\n position: \"right\",\n width: \"md\",\n },\n }\n);\n\n/**\n * Panel header variants\n */\nexport const panelHeaderVariants = cva([\n \"flex items-start justify-between\",\n \"px-4 py-4\",\n \"border-b border-[var(--border)]\",\n]);\n\n/**\n * Panel body variants\n */\nexport const panelBodyVariants = cva([\"flex-1 overflow-y-auto\", \"px-4 py-4\"]);\n\n/**\n * Panel footer variants\n */\nexport const panelFooterVariants = cva([\n \"flex items-center justify-end gap-2\",\n \"px-4 py-4\",\n \"border-t border-[var(--border)]\",\n]);\n\n/**\n * Close button variants\n */\nexport const panelCloseButtonVariants = cva([\n \"inline-flex items-center justify-center rounded-md\",\n \"min-h-[44px] min-w-[44px]\",\n \"text-[var(--menu-muted)]\",\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2\",\n // No transition - instant state changes (v1)\n]);\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface PanelContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n panelId: string;\n titleId: string;\n triggerRef: MutableRefObject<HTMLElement | null>;\n position: PanelPosition;\n width: PanelWidth;\n mobileBreakpoint: number;\n isMobile: boolean;\n handleClose: () => void;\n}\n\nconst PanelContext = createContext<PanelContextValue | null>(null);\n\nfunction usePanelContext(): PanelContextValue {\n const context = useContext(PanelContext);\n if (!context) {\n throw new Error(\"Panel compound components must be used within a Panel\");\n }\n return context;\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * SSR-safe media query hook\n * Defaults to false on server (desktop mode)\n */\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n // Default to false on server (desktop mode)\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const media = window.matchMedia(query);\n // Sync state after mount (handles SSR mismatch)\n if (media.matches !== matches) {\n setMatches(media.matches);\n }\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\n media.addEventListener(\"change\", listener);\n return () => media.removeEventListener(\"change\", listener);\n }, [query, matches]);\n\n return matches;\n}\n\n// ============================================================================\n// Panel Root\n// ============================================================================\n\nfunction PanelRoot({\n children,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n onClose,\n position = \"right\",\n width = \"md\",\n mobileBreakpoint = 768,\n}: PanelProps): ReactElement {\n // State management (controlled/uncontrolled)\n const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(defaultOpen);\n const isControlled = controlledIsOpen !== undefined;\n const isOpen = isControlled ? controlledIsOpen : uncontrolledIsOpen;\n\n // Refs\n const triggerRef = useRef<HTMLElement | null>(null);\n\n // IDs for ARIA\n const uniqueId = useId();\n const panelId = `panel-${uniqueId}`;\n const titleId = `panel-title-${uniqueId}`;\n\n // Responsive detection\n const isMobile = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);\n\n // State setter\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (!isControlled) {\n setUncontrolledIsOpen(open);\n }\n onOpenChange?.(open);\n },\n [isControlled, onOpenChange]\n );\n\n // Close handler with focus restoration\n const handleClose = useCallback(() => {\n setIsOpen(false);\n onClose?.();\n // Return focus to trigger if it still exists in DOM\n if (triggerRef.current) {\n window.requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n }\n }, [setIsOpen, onClose]);\n\n // Escape key handler (desktop only - mobile handled by React Aria)\n useEffect(() => {\n if (!isOpen || isMobile) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, isMobile, handleClose]);\n\n const contextValue: PanelContextValue = {\n isOpen,\n setIsOpen,\n panelId,\n titleId,\n triggerRef,\n position,\n width,\n mobileBreakpoint,\n isMobile,\n handleClose,\n };\n\n return (\n <PanelContext.Provider value={contextValue}>\n {children}\n </PanelContext.Provider>\n );\n}\nPanelRoot.displayName = \"Panel\";\n\n// ============================================================================\n// Panel.Trigger\n// ============================================================================\n\nfunction PanelTrigger({\n children,\n asChild = true,\n}: PanelTriggerProps): ReactElement | null {\n const { isOpen, setIsOpen, panelId, triggerRef } = usePanelContext();\n\n // Capture ref via callback ref pattern\n const setRef = useCallback(\n (element: HTMLElement | null) => {\n triggerRef.current = element;\n },\n [triggerRef]\n );\n\n const handlePress = useCallback(() => {\n setIsOpen(!isOpen);\n }, [setIsOpen, isOpen]);\n\n // If asChild, clone the child element and add props\n if (asChild && isValidElement(children)) {\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n return cloneElement(children, {\n ref: setRef,\n \"aria-expanded\": isOpen,\n \"aria-controls\": isOpen ? panelId : undefined,\n \"data-testid\": \"panel-trigger\",\n onPress: handlePress,\n onClick: childProps.onClick\n ? () => {\n childProps.onClick?.();\n handlePress();\n }\n : handlePress,\n } as unknown as Record<string, unknown>);\n }\n\n // Fallback: wrap in AriaButton\n return (\n <AriaButton\n ref={setRef}\n aria-expanded={isOpen}\n aria-controls={isOpen ? panelId : undefined}\n onPress={handlePress}\n data-testid=\"panel-trigger\"\n >\n {children}\n </AriaButton>\n );\n}\nPanelTrigger.displayName = \"PanelTrigger\";\n\n// ============================================================================\n// Built-in Close Button\n// ============================================================================\n\nfunction BuiltInCloseButton(): ReactElement {\n const { handleClose } = usePanelContext();\n\n return (\n <AriaButton\n aria-label=\"Close panel\"\n data-testid=\"panel-close\"\n onPress={handleClose}\n className={panelCloseButtonVariants()}\n >\n <X className=\"h-5 w-5\" />\n </AriaButton>\n );\n}\n\n// ============================================================================\n// Panel.Content\n// ============================================================================\n\nfunction PanelContent({\n children,\n showClose = true,\n className,\n}: PanelContentProps): ReactElement | null {\n const { isOpen, isMobile, panelId, titleId, position, width, handleClose } =\n usePanelContext();\n\n if (!isOpen) return null;\n\n // Mobile: Use React Aria Modal primitives\n if (isMobile) {\n return (\n <AriaModalOverlay\n isDismissable\n shouldCloseOnInteractOutside={createInteractOutsideGuard()}\n isOpen={isOpen}\n onOpenChange={(open) => !open && handleClose()}\n className=\"fixed inset-0 z-50 bg-black/50\"\n >\n <AriaModal className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <AriaDialog\n aria-labelledby={titleId}\n className={cn(\n \"w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none\",\n \"flex max-h-[90vh] flex-col\",\n className\n )}\n >\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n {children}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n }\n\n // Desktop: Render aside in-place\n return (\n <aside\n id={panelId}\n aria-labelledby={titleId}\n data-testid=\"panel-content\"\n className={cn(panelContentVariants({ position, width }), className)}\n >\n {children}\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n </aside>\n );\n}\nPanelContent.displayName = \"PanelContent\";\n\n// ============================================================================\n// Panel.Header\n// ============================================================================\n\nfunction PanelHeader({\n children,\n className,\n}: PanelHeaderProps): ReactElement | null {\n // Note: We use a <header> element but DON'T add role=\"banner\"\n // because banner landmarks should not be contained in other landmarks (like aside)\n // The header element still provides structural meaning for the panel\n return (\n <header className={cn(panelHeaderVariants(), className)}>\n <div className=\"flex flex-col gap-1\">{children}</div>\n </header>\n );\n}\nPanelHeader.displayName = \"PanelHeader\";\n\n// ============================================================================\n// Panel.Title\n// ============================================================================\n\nfunction PanelTitle({\n children,\n as: Tag = \"h2\",\n className,\n}: PanelTitleProps): ReactElement | null {\n const { titleId } = usePanelContext();\n\n return (\n <Tag\n id={titleId}\n // aria-live=\"polite\" announces title changes to screen readers\n // This is important for master-detail patterns where panel content\n // updates when selecting different items (e.g., candidate profiles)\n aria-live=\"polite\"\n className={cn(\n \"text-lg font-semibold text-[var(--content-foreground)]\",\n className\n )}\n >\n {children}\n </Tag>\n );\n}\nPanelTitle.displayName = \"PanelTitle\";\n\n// ============================================================================\n// Panel.Description\n// ============================================================================\n\nfunction PanelDescription({\n children,\n className,\n}: PanelDescriptionProps): ReactElement | null {\n return (\n <p className={cn(\"text-sm text-[var(--menu-muted)]\", className)}>\n {children}\n </p>\n );\n}\nPanelDescription.displayName = \"PanelDescription\";\n\n// ============================================================================\n// Panel.Body\n// ============================================================================\n\nfunction PanelBody({ children, className }: PanelBodyProps): ReactElement | null {\n return <div className={cn(panelBodyVariants(), className)}>{children}</div>;\n}\nPanelBody.displayName = \"PanelBody\";\n\n// ============================================================================\n// Panel.Footer\n// ============================================================================\n\nfunction PanelFooter({\n children,\n className,\n}: PanelFooterProps): ReactElement | null {\n // Note: We use a <footer> element but DON'T add role=\"contentinfo\"\n // because contentinfo landmarks should not be contained in other landmarks (like aside)\n // The footer element still provides structural meaning for the panel\n return (\n <footer className={cn(panelFooterVariants(), className)}>\n {children}\n </footer>\n );\n}\nPanelFooter.displayName = \"PanelFooter\";\n\n// ============================================================================\n// Panel.Close\n// ============================================================================\n\nfunction PanelClose({ children }: PanelCloseProps): ReactElement | null {\n const { handleClose } = usePanelContext();\n\n if (!isValidElement(children)) {\n return null;\n }\n\n // Clone the child and add onPress/onClick handler\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n\n return cloneElement(children, {\n onPress: () => {\n childProps.onPress?.();\n handleClose();\n },\n onClick: () => {\n childProps.onClick?.();\n handleClose();\n },\n } as unknown as Record<string, unknown>);\n}\nPanelClose.displayName = \"PanelClose\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Panel Component\n *\n * Accessible non-modal sidebar panel using the disclosure pattern with\n * a complementary region for WCAG 2.2 AAA compliance.\n *\n * @example\n * ```tsx\n * <Panel>\n * <Panel.Trigger>\n * <Button>Open Panel</Button>\n * </Panel.Trigger>\n * <Panel.Content>\n * <Panel.Header>\n * <Panel.Title>Panel Title</Panel.Title>\n * <Panel.Description>Optional description</Panel.Description>\n * </Panel.Header>\n * <Panel.Body>\n * Panel content here\n * </Panel.Body>\n * <Panel.Footer>\n * <Button>Action</Button>\n * </Panel.Footer>\n * </Panel.Content>\n * </Panel>\n * ```\n */\nexport const Panel = Object.assign(PanelRoot, {\n Trigger: PanelTrigger,\n Content: PanelContent,\n Header: PanelHeader,\n Title: PanelTitle,\n Description: PanelDescription,\n Body: PanelBody,\n Footer: PanelFooter,\n Close: PanelClose,\n});\n\n// Named exports for individual components\nexport {\n PanelRoot,\n PanelTrigger,\n PanelContent,\n PanelHeader,\n PanelTitle,\n PanelDescription,\n PanelBody,\n PanelFooter,\n PanelClose,\n};\n\n// Export CVA variant types for customization\nexport type PanelContentVariants = VariantProps<typeof panelContentVariants>;\n"]}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import {createContext,useState,useRef,useId,useCallback,useEffect,isValidElement,cloneElement,useContext}from'react';import {ModalOverlay,Modal,Dialog,Button}from'react-aria-components';import {cva}from'class-variance-authority';import {X}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs}from'react/jsx-runtime';function d(...e){return twMerge(clsx(e))}var B=cva(["flex flex-col h-full overflow-hidden","bg-[var(--content-background)] text-[var(--content-foreground)]"],{variants:{position:{right:"border-l border-[var(--border)]",left:"border-r border-[var(--border)]"},width:{sm:"w-[300px]",md:"w-[400px]",lg:"w-[500px]",xl:"w-[600px]",auto:"w-auto"}},defaultVariants:{position:"right",width:"md"}}),O=cva(["flex items-start justify-between","px-4 py-4","border-b border-[var(--border)]"]),I=cva(["flex-1 overflow-y-auto","px-4 py-4"]),D=cva(["flex items-center justify-end gap-2","px-4 py-4","border-t border-[var(--border)]"]),H=cva(["inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"]),A=createContext(null);function f(){let e=useContext(A);if(!e)throw new Error("Panel compound components must be used within a Panel");return e}function re(e){let[n,t]=useState(()=>typeof window>"u"?false:window.matchMedia(e).matches);return useEffect(()=>{if(typeof window>"u")return;let o=window.matchMedia(e);o.matches!==n&&t(o.matches);let r=s=>t(s.matches);return o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e,n]),n}function F({children:e,isOpen:n,defaultOpen:t=false,onOpenChange:o,onClose:r,position:s="right",width:p="md",mobileBreakpoint:l=768}){let[i,g]=useState(t),c=n!==void 0,x=c?n:i,v=useRef(null),h=useId(),U=`panel-${h}`,X=`panel-title-${h}`,b=re(`(max-width: ${l-1}px)`),y=useCallback(u=>{c||g(u),o?.(u);},[c,o]),C=useCallback(()=>{y(false),r?.(),v.current&&window.requestAnimationFrame(()=>{v.current?.focus();});},[y,r]);useEffect(()=>{if(!x||b)return;let u=w=>{w.key==="Escape"&&(w.preventDefault(),C());};return document.addEventListener("keydown",u),()=>document.removeEventListener("keydown",u)},[x,b,C]);let q={isOpen:x,setIsOpen:y,panelId:U,titleId:X,triggerRef:v,position:s,width:p,mobileBreakpoint:l,isMobile:b,handleClose:C};return jsx(A.Provider,{value:q,children:e})}F.displayName="Panel";function L({children:e,asChild:n=true}){let{isOpen:t,setIsOpen:o,panelId:r,triggerRef:s}=f(),p=useCallback(i=>{s.current=i;},[s]),l=useCallback(()=>{o(!t);},[o,t]);if(n&&isValidElement(e)){let i=e.props;return cloneElement(e,{ref:p,"aria-expanded":t,"aria-controls":t?r:void 0,"data-testid":"panel-trigger",onPress:l,onClick:i.onClick?()=>{i.onClick?.(),l();}:l})}return jsx(Button,{ref:p,"aria-expanded":t,"aria-controls":t?r:void 0,onPress:l,"data-testid":"panel-trigger",children:e})}L.displayName="PanelTrigger";function E(){let{handleClose:e}=f();return jsx(Button,{"aria-label":"Close panel","data-testid":"panel-close",onPress:e,className:H(),children:jsx(X,{className:"h-5 w-5"})})}function j({children:e,showClose:n=true,className:t}){let{isOpen:o,isMobile:r,panelId:s,titleId:p,position:l,width:i,handleClose:g}=f();return o?r?jsx(ModalOverlay,{isDismissable:true,isOpen:o,onOpenChange:c=>!c&&g(),className:"fixed inset-0 z-50 bg-black/50",children:jsx(Modal,{className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:jsxs(Dialog,{"aria-labelledby":p,className:d("w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none","flex max-h-[90vh] flex-col",t),children:[n&&jsx("div",{className:"absolute right-2 top-2",children:jsx(E,{})}),e]})})}):jsxs("aside",{id:s,"aria-labelledby":p,"data-testid":"panel-content",className:d(B({position:l,width:i}),t),children:[e,n&&jsx("div",{className:"absolute right-2 top-2",children:jsx(E,{})})]}):null}j.displayName="PanelContent";function W({children:e,className:n}){return jsx("header",{className:d(O(),n),children:jsx("div",{className:"flex flex-col gap-1",children:e})})}W.displayName="PanelHeader";function $({children:e,as:n="h2",className:t}){let{titleId:o}=f();return jsx(n,{id:o,"aria-live":"polite",className:d("text-lg font-semibold text-[var(--content-foreground)]",t),children:e})}$.displayName="PanelTitle";function z({children:e,className:n}){return jsx("p",{className:d("text-sm text-[var(--menu-muted)]",n),children:e})}z.displayName="PanelDescription";function K({children:e,className:n}){return jsx("div",{className:d(I(),n),children:e})}K.displayName="PanelBody";function Q({children:e,className:n}){return jsx("footer",{className:d(D(),n),children:e})}Q.displayName="PanelFooter";function S({children:e}){let{handleClose:n}=f();if(!isValidElement(e))return null;let t=e.props;return cloneElement(e,{onPress:()=>{t.onPress?.(),n();},onClick:()=>{t.onClick?.(),n();}})}S.displayName="PanelClose";var le=Object.assign(F,{Trigger:L,Content:j,Header:W,Title:$,Description:z,Body:K,Footer:Q,Close:S});export{le as Panel,I as panelBodyVariants,H as panelCloseButtonVariants,B as panelContentVariants,D as panelFooterVariants,O as panelHeaderVariants};//# sourceMappingURL=index.mjs.map
2
+ import {createContext,useState,useRef,useId,useCallback,useEffect,isValidElement,cloneElement,useContext}from'react';import {ModalOverlay,Modal,Dialog,Button}from'react-aria-components';import {cva}from'class-variance-authority';import {X as X$1}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx,jsxs}from'react/jsx-runtime';function c(...e){return twMerge(clsx(e))}function Y(e){if(!(e instanceof Element))return false;let n=e;for(let r=0;n&&r<100;r++){let l=n.tagName?.toLowerCase()??"";if(l.startsWith("grammarly-")||l.startsWith("lt-")||n.hasAttribute("data-grammarly-shadow-root"))return true;if(n.parentElement)n=n.parentElement;else {let s=n.getRootNode();n=s instanceof ShadowRoot?s.host:null;}}let t=e;for(;t&&!t.tagName.includes("-");)t=t.parentElement;if(!t)return false;let o=t.parentElement;return o===document.body||o===document.documentElement}function E(e){return n=>!Y(n)&&(e?.(n)??true)}var I=cva(["flex flex-col h-full overflow-hidden","bg-[var(--content-background)] text-[var(--content-foreground)]"],{variants:{position:{right:"border-l border-[var(--border)]",left:"border-r border-[var(--border)]"},width:{sm:"w-[300px]",md:"w-[400px]",lg:"w-[500px]",xl:"w-[600px]",auto:"w-auto"}},defaultVariants:{position:"right",width:"md"}}),B=cva(["flex items-start justify-between","px-4 py-4","border-b border-[var(--border)]"]),A=cva(["flex-1 overflow-y-auto","px-4 py-4"]),D=cva(["flex items-center justify-end gap-2","px-4 py-4","border-t border-[var(--border)]"]),H=cva(["inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"]),F=createContext(null);function f(){let e=useContext(F);if(!e)throw new Error("Panel compound components must be used within a Panel");return e}function se(e){let[n,t]=useState(()=>typeof window>"u"?false:window.matchMedia(e).matches);return useEffect(()=>{if(typeof window>"u")return;let o=window.matchMedia(e);o.matches!==n&&t(o.matches);let r=l=>t(l.matches);return o.addEventListener("change",r),()=>o.removeEventListener("change",r)},[e,n]),n}function L({children:e,isOpen:n,defaultOpen:t=false,onOpenChange:o,onClose:r,position:l="right",width:s="md",mobileBreakpoint:i=768}){let[d,g]=useState(t),u=n!==void 0,x=u?n:d,b=useRef(null),C=useId(),K=`panel-${C}`,Q=`panel-title-${C}`,v=se(`(max-width: ${i-1}px)`),h=useCallback(p=>{u||g(p),o?.(p);},[u,o]),y=useCallback(()=>{h(false),r?.(),b.current&&window.requestAnimationFrame(()=>{b.current?.focus();});},[h,r]);useEffect(()=>{if(!x||v)return;let p=w=>{w.key==="Escape"&&(w.preventDefault(),y());};return document.addEventListener("keydown",p),()=>document.removeEventListener("keydown",p)},[x,v,y]);let U={isOpen:x,setIsOpen:h,panelId:K,titleId:Q,triggerRef:b,position:l,width:s,mobileBreakpoint:i,isMobile:v,handleClose:y};return jsx(F.Provider,{value:U,children:e})}L.displayName="Panel";function j({children:e,asChild:n=true}){let{isOpen:t,setIsOpen:o,panelId:r,triggerRef:l}=f(),s=useCallback(d=>{l.current=d;},[l]),i=useCallback(()=>{o(!t);},[o,t]);if(n&&isValidElement(e)){let d=e.props;return cloneElement(e,{ref:s,"aria-expanded":t,"aria-controls":t?r:void 0,"data-testid":"panel-trigger",onPress:i,onClick:d.onClick?()=>{d.onClick?.(),i();}:i})}return jsx(Button,{ref:s,"aria-expanded":t,"aria-controls":t?r:void 0,onPress:i,"data-testid":"panel-trigger",children:e})}j.displayName="PanelTrigger";function N(){let{handleClose:e}=f();return jsx(Button,{"aria-label":"Close panel","data-testid":"panel-close",onPress:e,className:H(),children:jsx(X$1,{className:"h-5 w-5"})})}function W({children:e,showClose:n=true,className:t}){let{isOpen:o,isMobile:r,panelId:l,titleId:s,position:i,width:d,handleClose:g}=f();return o?r?jsx(ModalOverlay,{isDismissable:true,shouldCloseOnInteractOutside:E(),isOpen:o,onOpenChange:u=>!u&&g(),className:"fixed inset-0 z-50 bg-black/50",children:jsx(Modal,{className:"fixed inset-0 z-50 flex items-center justify-center p-4",children:jsxs(Dialog,{"aria-labelledby":s,className:c("w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none","flex max-h-[90vh] flex-col",t),children:[n&&jsx("div",{className:"absolute right-2 top-2",children:jsx(N,{})}),e]})})}):jsxs("aside",{id:l,"aria-labelledby":s,"data-testid":"panel-content",className:c(I({position:i,width:d}),t),children:[e,n&&jsx("div",{className:"absolute right-2 top-2",children:jsx(N,{})})]}):null}W.displayName="PanelContent";function S({children:e,className:n}){return jsx("header",{className:c(B(),n),children:jsx("div",{className:"flex flex-col gap-1",children:e})})}S.displayName="PanelHeader";function _({children:e,as:n="h2",className:t}){let{titleId:o}=f();return jsx(n,{id:o,"aria-live":"polite",className:c("text-lg font-semibold text-[var(--content-foreground)]",t),children:e})}_.displayName="PanelTitle";function X({children:e,className:n}){return jsx("p",{className:c("text-sm text-[var(--menu-muted)]",n),children:e})}X.displayName="PanelDescription";function $({children:e,className:n}){return jsx("div",{className:c(A(),n),children:e})}$.displayName="PanelBody";function z({children:e,className:n}){return jsx("footer",{className:c(D(),n),children:e})}z.displayName="PanelFooter";function G({children:e}){let{handleClose:n}=f();if(!isValidElement(e))return null;let t=e.props;return cloneElement(e,{onPress:()=>{t.onPress?.(),n();},onClick:()=>{t.onClick?.(),n();}})}G.displayName="PanelClose";var ie=Object.assign(L,{Trigger:j,Content:W,Header:S,Title:_,Description:X,Body:$,Footer:z,Close:G});export{ie as Panel,A as panelBodyVariants,H as panelCloseButtonVariants,I as panelContentVariants,D as panelFooterVariants,B as panelHeaderVariants};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Panel/Panel.tsx"],"names":["cn","inputs","twMerge","clsx","panelContentVariants","cva","panelHeaderVariants","panelBodyVariants","panelFooterVariants","panelCloseButtonVariants","PanelContext","createContext","usePanelContext","context","useContext","useMediaQuery","query","matches","setMatches","useState","useEffect","media","listener","e","PanelRoot","children","controlledIsOpen","defaultOpen","onOpenChange","onClose","position","width","mobileBreakpoint","uncontrolledIsOpen","setUncontrolledIsOpen","isControlled","isOpen","triggerRef","useRef","uniqueId","useId","panelId","titleId","isMobile","setIsOpen","useCallback","open","handleClose","handleKeyDown","contextValue","jsx","PanelTrigger","asChild","setRef","element","handlePress","isValidElement","childProps","cloneElement","AriaButton","BuiltInCloseButton","X","PanelContent","showClose","className","AriaModalOverlay","AriaModal","jsxs","AriaDialog","PanelHeader","PanelTitle","Tag","PanelDescription","PanelBody","PanelFooter","PanelClose","Panel"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\n/**\n * Panel Component - Accessible Non-Modal Sidebar\n * Disclosure pattern + Complementary region for WCAG 2.2 AAA\n *\n * @see plan.md for architecture details\n * @see panel-prd.md for requirements\n * @see ADR 0007 for accessibility decisions\n */\n\nimport {\n type ReactElement,\n type MutableRefObject,\n createContext,\n useContext,\n useState,\n useId,\n useRef,\n useCallback,\n useEffect,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport {\n Button as AriaButton,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n} from \"react-aria-components\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport type {\n PanelProps,\n PanelTriggerProps,\n PanelContentProps,\n PanelHeaderProps,\n PanelTitleProps,\n PanelDescriptionProps,\n PanelBodyProps,\n PanelFooterProps,\n PanelCloseProps,\n PanelPosition,\n PanelWidth,\n} from \"./Panel.types\";\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * Panel content variants\n * Controls position-based styling and width\n */\nexport const panelContentVariants = cva(\n [\n \"flex flex-col h-full overflow-hidden\",\n \"bg-[var(--content-background)] text-[var(--content-foreground)]\",\n ],\n {\n variants: {\n position: {\n right: \"border-l border-[var(--border)]\",\n left: \"border-r border-[var(--border)]\",\n },\n width: {\n sm: \"w-[300px]\",\n md: \"w-[400px]\",\n lg: \"w-[500px]\",\n xl: \"w-[600px]\",\n auto: \"w-auto\",\n },\n },\n defaultVariants: {\n position: \"right\",\n width: \"md\",\n },\n }\n);\n\n/**\n * Panel header variants\n */\nexport const panelHeaderVariants = cva([\n \"flex items-start justify-between\",\n \"px-4 py-4\",\n \"border-b border-[var(--border)]\",\n]);\n\n/**\n * Panel body variants\n */\nexport const panelBodyVariants = cva([\"flex-1 overflow-y-auto\", \"px-4 py-4\"]);\n\n/**\n * Panel footer variants\n */\nexport const panelFooterVariants = cva([\n \"flex items-center justify-end gap-2\",\n \"px-4 py-4\",\n \"border-t border-[var(--border)]\",\n]);\n\n/**\n * Close button variants\n */\nexport const panelCloseButtonVariants = cva([\n \"inline-flex items-center justify-center rounded-md\",\n \"min-h-[44px] min-w-[44px]\",\n \"text-[var(--menu-muted)]\",\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2\",\n // No transition - instant state changes (v1)\n]);\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface PanelContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n panelId: string;\n titleId: string;\n triggerRef: MutableRefObject<HTMLElement | null>;\n position: PanelPosition;\n width: PanelWidth;\n mobileBreakpoint: number;\n isMobile: boolean;\n handleClose: () => void;\n}\n\nconst PanelContext = createContext<PanelContextValue | null>(null);\n\nfunction usePanelContext(): PanelContextValue {\n const context = useContext(PanelContext);\n if (!context) {\n throw new Error(\"Panel compound components must be used within a Panel\");\n }\n return context;\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * SSR-safe media query hook\n * Defaults to false on server (desktop mode)\n */\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n // Default to false on server (desktop mode)\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const media = window.matchMedia(query);\n // Sync state after mount (handles SSR mismatch)\n if (media.matches !== matches) {\n setMatches(media.matches);\n }\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\n media.addEventListener(\"change\", listener);\n return () => media.removeEventListener(\"change\", listener);\n }, [query, matches]);\n\n return matches;\n}\n\n// ============================================================================\n// Panel Root\n// ============================================================================\n\nfunction PanelRoot({\n children,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n onClose,\n position = \"right\",\n width = \"md\",\n mobileBreakpoint = 768,\n}: PanelProps): ReactElement {\n // State management (controlled/uncontrolled)\n const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(defaultOpen);\n const isControlled = controlledIsOpen !== undefined;\n const isOpen = isControlled ? controlledIsOpen : uncontrolledIsOpen;\n\n // Refs\n const triggerRef = useRef<HTMLElement | null>(null);\n\n // IDs for ARIA\n const uniqueId = useId();\n const panelId = `panel-${uniqueId}`;\n const titleId = `panel-title-${uniqueId}`;\n\n // Responsive detection\n const isMobile = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);\n\n // State setter\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (!isControlled) {\n setUncontrolledIsOpen(open);\n }\n onOpenChange?.(open);\n },\n [isControlled, onOpenChange]\n );\n\n // Close handler with focus restoration\n const handleClose = useCallback(() => {\n setIsOpen(false);\n onClose?.();\n // Return focus to trigger if it still exists in DOM\n if (triggerRef.current) {\n window.requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n }\n }, [setIsOpen, onClose]);\n\n // Escape key handler (desktop only - mobile handled by React Aria)\n useEffect(() => {\n if (!isOpen || isMobile) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, isMobile, handleClose]);\n\n const contextValue: PanelContextValue = {\n isOpen,\n setIsOpen,\n panelId,\n titleId,\n triggerRef,\n position,\n width,\n mobileBreakpoint,\n isMobile,\n handleClose,\n };\n\n return (\n <PanelContext.Provider value={contextValue}>\n {children}\n </PanelContext.Provider>\n );\n}\nPanelRoot.displayName = \"Panel\";\n\n// ============================================================================\n// Panel.Trigger\n// ============================================================================\n\nfunction PanelTrigger({\n children,\n asChild = true,\n}: PanelTriggerProps): ReactElement | null {\n const { isOpen, setIsOpen, panelId, triggerRef } = usePanelContext();\n\n // Capture ref via callback ref pattern\n const setRef = useCallback(\n (element: HTMLElement | null) => {\n triggerRef.current = element;\n },\n [triggerRef]\n );\n\n const handlePress = useCallback(() => {\n setIsOpen(!isOpen);\n }, [setIsOpen, isOpen]);\n\n // If asChild, clone the child element and add props\n if (asChild && isValidElement(children)) {\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n return cloneElement(children, {\n ref: setRef,\n \"aria-expanded\": isOpen,\n \"aria-controls\": isOpen ? panelId : undefined,\n \"data-testid\": \"panel-trigger\",\n onPress: handlePress,\n onClick: childProps.onClick\n ? () => {\n childProps.onClick?.();\n handlePress();\n }\n : handlePress,\n } as unknown as Record<string, unknown>);\n }\n\n // Fallback: wrap in AriaButton\n return (\n <AriaButton\n ref={setRef}\n aria-expanded={isOpen}\n aria-controls={isOpen ? panelId : undefined}\n onPress={handlePress}\n data-testid=\"panel-trigger\"\n >\n {children}\n </AriaButton>\n );\n}\nPanelTrigger.displayName = \"PanelTrigger\";\n\n// ============================================================================\n// Built-in Close Button\n// ============================================================================\n\nfunction BuiltInCloseButton(): ReactElement {\n const { handleClose } = usePanelContext();\n\n return (\n <AriaButton\n aria-label=\"Close panel\"\n data-testid=\"panel-close\"\n onPress={handleClose}\n className={panelCloseButtonVariants()}\n >\n <X className=\"h-5 w-5\" />\n </AriaButton>\n );\n}\n\n// ============================================================================\n// Panel.Content\n// ============================================================================\n\nfunction PanelContent({\n children,\n showClose = true,\n className,\n}: PanelContentProps): ReactElement | null {\n const { isOpen, isMobile, panelId, titleId, position, width, handleClose } =\n usePanelContext();\n\n if (!isOpen) return null;\n\n // Mobile: Use React Aria Modal primitives\n if (isMobile) {\n return (\n <AriaModalOverlay\n isDismissable\n isOpen={isOpen}\n onOpenChange={(open) => !open && handleClose()}\n className=\"fixed inset-0 z-50 bg-black/50\"\n >\n <AriaModal className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <AriaDialog\n aria-labelledby={titleId}\n className={cn(\n \"w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none\",\n \"flex max-h-[90vh] flex-col\",\n className\n )}\n >\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n {children}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n }\n\n // Desktop: Render aside in-place\n return (\n <aside\n id={panelId}\n aria-labelledby={titleId}\n data-testid=\"panel-content\"\n className={cn(panelContentVariants({ position, width }), className)}\n >\n {children}\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n </aside>\n );\n}\nPanelContent.displayName = \"PanelContent\";\n\n// ============================================================================\n// Panel.Header\n// ============================================================================\n\nfunction PanelHeader({\n children,\n className,\n}: PanelHeaderProps): ReactElement | null {\n // Note: We use a <header> element but DON'T add role=\"banner\"\n // because banner landmarks should not be contained in other landmarks (like aside)\n // The header element still provides structural meaning for the panel\n return (\n <header className={cn(panelHeaderVariants(), className)}>\n <div className=\"flex flex-col gap-1\">{children}</div>\n </header>\n );\n}\nPanelHeader.displayName = \"PanelHeader\";\n\n// ============================================================================\n// Panel.Title\n// ============================================================================\n\nfunction PanelTitle({\n children,\n as: Tag = \"h2\",\n className,\n}: PanelTitleProps): ReactElement | null {\n const { titleId } = usePanelContext();\n\n return (\n <Tag\n id={titleId}\n // aria-live=\"polite\" announces title changes to screen readers\n // This is important for master-detail patterns where panel content\n // updates when selecting different items (e.g., candidate profiles)\n aria-live=\"polite\"\n className={cn(\n \"text-lg font-semibold text-[var(--content-foreground)]\",\n className\n )}\n >\n {children}\n </Tag>\n );\n}\nPanelTitle.displayName = \"PanelTitle\";\n\n// ============================================================================\n// Panel.Description\n// ============================================================================\n\nfunction PanelDescription({\n children,\n className,\n}: PanelDescriptionProps): ReactElement | null {\n return (\n <p className={cn(\"text-sm text-[var(--menu-muted)]\", className)}>\n {children}\n </p>\n );\n}\nPanelDescription.displayName = \"PanelDescription\";\n\n// ============================================================================\n// Panel.Body\n// ============================================================================\n\nfunction PanelBody({ children, className }: PanelBodyProps): ReactElement | null {\n return <div className={cn(panelBodyVariants(), className)}>{children}</div>;\n}\nPanelBody.displayName = \"PanelBody\";\n\n// ============================================================================\n// Panel.Footer\n// ============================================================================\n\nfunction PanelFooter({\n children,\n className,\n}: PanelFooterProps): ReactElement | null {\n // Note: We use a <footer> element but DON'T add role=\"contentinfo\"\n // because contentinfo landmarks should not be contained in other landmarks (like aside)\n // The footer element still provides structural meaning for the panel\n return (\n <footer className={cn(panelFooterVariants(), className)}>\n {children}\n </footer>\n );\n}\nPanelFooter.displayName = \"PanelFooter\";\n\n// ============================================================================\n// Panel.Close\n// ============================================================================\n\nfunction PanelClose({ children }: PanelCloseProps): ReactElement | null {\n const { handleClose } = usePanelContext();\n\n if (!isValidElement(children)) {\n return null;\n }\n\n // Clone the child and add onPress/onClick handler\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n\n return cloneElement(children, {\n onPress: () => {\n childProps.onPress?.();\n handleClose();\n },\n onClick: () => {\n childProps.onClick?.();\n handleClose();\n },\n } as unknown as Record<string, unknown>);\n}\nPanelClose.displayName = \"PanelClose\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Panel Component\n *\n * Accessible non-modal sidebar panel using the disclosure pattern with\n * a complementary region for WCAG 2.2 AAA compliance.\n *\n * @example\n * ```tsx\n * <Panel>\n * <Panel.Trigger>\n * <Button>Open Panel</Button>\n * </Panel.Trigger>\n * <Panel.Content>\n * <Panel.Header>\n * <Panel.Title>Panel Title</Panel.Title>\n * <Panel.Description>Optional description</Panel.Description>\n * </Panel.Header>\n * <Panel.Body>\n * Panel content here\n * </Panel.Body>\n * <Panel.Footer>\n * <Button>Action</Button>\n * </Panel.Footer>\n * </Panel.Content>\n * </Panel>\n * ```\n */\nexport const Panel = Object.assign(PanelRoot, {\n Trigger: PanelTrigger,\n Content: PanelContent,\n Header: PanelHeader,\n Title: PanelTitle,\n Description: PanelDescription,\n Body: PanelBody,\n Footer: PanelFooter,\n Close: PanelClose,\n});\n\n// Named exports for individual components\nexport {\n PanelRoot,\n PanelTrigger,\n PanelContent,\n PanelHeader,\n PanelTitle,\n PanelDescription,\n PanelBody,\n PanelFooter,\n PanelClose,\n};\n\n// Export CVA variant types for customization\nexport type PanelContentVariants = VariantProps<typeof panelContentVariants>;\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/utils/browserExtensionOverlay.ts","../../../src/elements/Panel/Panel.tsx"],"names":["cn","inputs","twMerge","clsx","isExtensionInjectedElement","element","node","depth","tag","root","custom","parent","createInteractOutsideGuard","consumerShouldClose","panelContentVariants","cva","panelHeaderVariants","panelBodyVariants","panelFooterVariants","panelCloseButtonVariants","PanelContext","createContext","usePanelContext","context","useContext","useMediaQuery","query","matches","setMatches","useState","useEffect","media","listener","e","PanelRoot","children","controlledIsOpen","defaultOpen","onOpenChange","onClose","position","width","mobileBreakpoint","uncontrolledIsOpen","setUncontrolledIsOpen","isControlled","isOpen","triggerRef","useRef","uniqueId","useId","panelId","titleId","isMobile","setIsOpen","useCallback","open","handleClose","handleKeyDown","contextValue","jsx","PanelTrigger","asChild","setRef","handlePress","isValidElement","childProps","cloneElement","AriaButton","BuiltInCloseButton","X","PanelContent","showClose","className","AriaModalOverlay","AriaModal","jsxs","AriaDialog","PanelHeader","PanelTitle","Tag","PanelDescription","PanelBody","PanelFooter","PanelClose","Panel"],"mappings":"+WAcO,SAASA,CAAAA,CAAAA,GAAMC,CAAAA,CAA8B,CAClD,OAAOC,OAAAA,CAAQC,IAAAA,CAAKF,CAAM,CAAC,CAC7B,CCWO,SAASG,CAAAA,CAA2BC,CAAAA,CAA2B,CACpE,GAAI,EAAEA,CAAAA,YAAmB,OAAA,CAAA,CAAU,OAAO,MAAA,CAU1C,IAAIC,CAAAA,CAAuBD,CAAAA,CAC3B,IAAA,IAASE,CAAAA,CAAQ,CAAA,CAAGD,CAAAA,EAAQC,CAAAA,CAAQ,GAAA,CAAoBA,CAAAA,EAAAA,CAAS,CAC/D,IAAMC,CAAAA,CAAMF,CAAAA,CAAK,OAAA,EAAS,WAAA,EAAY,EAAK,EAAA,CAG3C,GAFIE,CAAAA,CAAI,UAAA,CAAW,YAAY,CAAA,EAC3BA,CAAAA,CAAI,UAAA,CAAW,KAAK,CAAA,EACpBF,CAAAA,CAAK,YAAA,CAAa,4BAA4B,CAAA,CAAG,OAAO,KAAA,CAE5D,GAAIA,CAAAA,CAAK,aAAA,CACPA,CAAAA,CAAOA,CAAAA,CAAK,aAAA,CAAA,KACP,CACL,IAAMG,CAAAA,CAAOH,CAAAA,CAAK,WAAA,EAAY,CAC9BA,CAAAA,CAAOG,CAAAA,YAAgB,UAAA,CAAaA,CAAAA,CAAK,IAAA,CAAO,KAClD,CACF,CAQA,IAAIC,CAAAA,CAAyBL,CAAAA,CAC7B,KAAOK,CAAAA,EAAU,CAACA,CAAAA,CAAO,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAC3CA,CAAAA,CAASA,CAAAA,CAAO,aAAA,CAElB,GAAI,CAACA,CAAAA,CAAQ,OAAO,MAAA,CAEpB,IAAMC,CAAAA,CAASD,CAAAA,CAAO,aAAA,CACtB,OAAOC,CAAAA,GAAW,QAAA,CAAS,IAAA,EAAQA,CAAAA,GAAW,QAAA,CAAS,eACzD,CAWO,SAASC,CAAAA,CACdC,CAAAA,CAC+B,CAC/B,OAAQR,CAAAA,EACN,CAACD,CAAAA,CAA2BC,CAAO,CAAA,GAAMQ,CAAAA,GAAsBR,CAAO,CAAA,EAAK,IAAA,CAC/E,CC3BO,IAAMS,CAAAA,CAAuBC,GAAAA,CAClC,CACE,sCAAA,CACA,iEACF,CAAA,CACA,CACE,QAAA,CAAU,CACR,QAAA,CAAU,CACR,KAAA,CAAO,iCAAA,CACP,IAAA,CAAM,iCACR,CAAA,CACA,KAAA,CAAO,CACL,EAAA,CAAI,WAAA,CACJ,EAAA,CAAI,WAAA,CACJ,EAAA,CAAI,WAAA,CACJ,EAAA,CAAI,WAAA,CACJ,IAAA,CAAM,QACR,CACF,CAAA,CACA,eAAA,CAAiB,CACf,QAAA,CAAU,OAAA,CACV,KAAA,CAAO,IACT,CACF,CACF,CAAA,CAKaC,CAAAA,CAAsBD,GAAAA,CAAI,CACrC,kCAAA,CACA,WAAA,CACA,iCACF,CAAC,CAAA,CAKYE,CAAAA,CAAoBF,GAAAA,CAAI,CAAC,wBAAA,CAA0B,WAAW,CAAC,CAAA,CAK/DG,CAAAA,CAAsBH,GAAAA,CAAI,CACrC,qCAAA,CACA,WAAA,CACA,iCACF,CAAC,CAAA,CAKYI,CAAAA,CAA2BJ,GAAAA,CAAI,CAC1C,oDAAA,CACA,2BAAA,CACA,0BAAA,CACA,gEAAA,CACA,iDAAA,CACA,8DAEF,CAAC,CAAA,CAmBKK,CAAAA,CAAeC,aAAAA,CAAwC,IAAI,EAEjE,SAASC,CAAAA,EAAqC,CAC5C,IAAMC,CAAAA,CAAUC,UAAAA,CAAWJ,CAAY,CAAA,CACvC,GAAI,CAACG,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,uDAAuD,CAAA,CAEzE,OAAOA,CACT,CAUA,SAASE,EAAAA,CAAcC,CAAAA,CAAwB,CAC7C,GAAM,CAACC,CAAAA,CAASC,CAAU,CAAA,CAAIC,QAAAA,CAAS,IAEjC,OAAO,MAAA,CAAW,GAAA,CAAoB,KAAA,CACnC,MAAA,CAAO,UAAA,CAAWH,CAAK,CAAA,CAAE,OACjC,CAAA,CAED,OAAAI,SAAAA,CAAU,IAAM,CACd,GAAI,OAAO,MAAA,CAAW,GAAA,CAAa,OACnC,IAAMC,CAAAA,CAAQ,MAAA,CAAO,UAAA,CAAWL,CAAK,CAAA,CAEjCK,CAAAA,CAAM,OAAA,GAAYJ,CAAAA,EACpBC,CAAAA,CAAWG,CAAAA,CAAM,OAAO,CAAA,CAE1B,IAAMC,CAAAA,CAAYC,CAAAA,EAA2BL,CAAAA,CAAWK,EAAE,OAAO,CAAA,CACjE,OAAAF,CAAAA,CAAM,gBAAA,CAAiB,QAAA,CAAUC,CAAQ,CAAA,CAClC,IAAMD,CAAAA,CAAM,mBAAA,CAAoB,QAAA,CAAUC,CAAQ,CAC3D,CAAA,CAAG,CAACN,CAAAA,CAAOC,CAAO,CAAC,CAAA,CAEZA,CACT,CAMA,SAASO,CAAAA,CAAU,CACjB,QAAA,CAAAC,CAAAA,CACA,MAAA,CAAQC,CAAAA,CACR,WAAA,CAAAC,CAAAA,CAAc,KAAA,CACd,YAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,QAAA,CAAAC,CAAAA,CAAW,OAAA,CACX,KAAA,CAAAC,CAAAA,CAAQ,IAAA,CACR,gBAAA,CAAAC,CAAAA,CAAmB,GACrB,CAAA,CAA6B,CAE3B,GAAM,CAACC,CAAAA,CAAoBC,CAAqB,CAAA,CAAIf,QAAAA,CAASQ,CAAW,CAAA,CAClEQ,CAAAA,CAAeT,CAAAA,GAAqB,MAAA,CACpCU,CAAAA,CAASD,CAAAA,CAAeT,CAAAA,CAAmBO,CAAAA,CAG3CI,EAAaC,MAAAA,CAA2B,IAAI,CAAA,CAG5CC,CAAAA,CAAWC,KAAAA,EAAM,CACjBC,CAAAA,CAAU,CAAA,MAAA,EAASF,CAAQ,CAAA,CAAA,CAC3BG,CAAAA,CAAU,CAAA,YAAA,EAAeH,CAAQ,CAAA,CAAA,CAGjCI,CAAAA,CAAW5B,EAAAA,CAAc,CAAA,YAAA,EAAeiB,CAAAA,CAAmB,CAAC,CAAA,GAAA,CAAK,CAAA,CAGjEY,CAAAA,CAAYC,WAAAA,CACfC,CAAAA,EAAkB,CACZX,CAAAA,EACHD,CAAAA,CAAsBY,CAAI,CAAA,CAE5BlB,CAAAA,GAAekB,CAAI,EACrB,CAAA,CACA,CAACX,CAAAA,CAAcP,CAAY,CAC7B,CAAA,CAGMmB,CAAAA,CAAcF,WAAAA,CAAY,IAAM,CACpCD,CAAAA,CAAU,KAAK,CAAA,CACff,CAAAA,IAAU,CAENQ,CAAAA,CAAW,OAAA,EACb,MAAA,CAAO,qBAAA,CAAsB,IAAM,CACjCA,CAAAA,CAAW,OAAA,EAAS,KAAA,GACtB,CAAC,EAEL,CAAA,CAAG,CAACO,CAAAA,CAAWf,CAAO,CAAC,CAAA,CAGvBT,SAAAA,CAAU,IAAM,CACd,GAAI,CAACgB,CAAAA,EAAUO,CAAAA,CAAU,OAEzB,IAAMK,CAAAA,CAAiBzB,CAAAA,EAAqB,CACtCA,CAAAA,CAAE,GAAA,GAAQ,QAAA,GACZA,CAAAA,CAAE,cAAA,EAAe,CACjBwB,CAAAA,EAAY,EAEhB,CAAA,CACA,OAAA,QAAA,CAAS,gBAAA,CAAiB,SAAA,CAAWC,CAAa,CAAA,CAC3C,IAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,CAAWA,CAAa,CACpE,CAAA,CAAG,CAACZ,CAAAA,CAAQO,CAAAA,CAAUI,CAAW,CAAC,CAAA,CAElC,IAAME,CAAAA,CAAkC,CACtC,MAAA,CAAAb,CAAAA,CACA,SAAA,CAAAQ,CAAAA,CACA,OAAA,CAAAH,CAAAA,CACA,OAAA,CAAAC,CAAAA,CACA,UAAA,CAAAL,CAAAA,CACA,QAAA,CAAAP,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,gBAAA,CAAAC,CAAAA,CACA,QAAA,CAAAW,CAAAA,CACA,WAAA,CAAAI,CACF,CAAA,CAEA,OACEG,GAAAA,CAACxC,CAAAA,CAAa,QAAA,CAAb,CAAsB,KAAA,CAAOuC,CAAAA,CAC3B,QAAA,CAAAxB,CAAAA,CACH,CAEJ,CACAD,CAAAA,CAAU,WAAA,CAAc,OAAA,CAMxB,SAAS2B,CAAAA,CAAa,CACpB,QAAA,CAAA1B,CAAAA,CACA,OAAA,CAAA2B,CAAAA,CAAU,IACZ,CAAA,CAA2C,CACzC,GAAM,CAAE,MAAA,CAAAhB,CAAAA,CAAQ,SAAA,CAAAQ,CAAAA,CAAW,OAAA,CAAAH,CAAAA,CAAS,UAAA,CAAAJ,CAAW,CAAA,CAAIzB,CAAAA,EAAgB,CAG7DyC,CAAAA,CAASR,WAAAA,CACZlD,CAAAA,EAAgC,CAC/B0C,CAAAA,CAAW,OAAA,CAAU1C,EACvB,CAAA,CACA,CAAC0C,CAAU,CACb,CAAA,CAEMiB,CAAAA,CAAcT,WAAAA,CAAY,IAAM,CACpCD,CAAAA,CAAU,CAACR,CAAM,EACnB,CAAA,CAAG,CAACQ,CAAAA,CAAWR,CAAM,CAAC,CAAA,CAGtB,GAAIgB,CAAAA,EAAWG,cAAAA,CAAe9B,CAAQ,CAAA,CAAG,CACvC,IAAM+B,CAAAA,CAAa/B,CAAAA,CAAS,KAAA,CAI5B,OAAOgC,YAAAA,CAAahC,CAAAA,CAAU,CAC5B,GAAA,CAAK4B,CAAAA,CACL,eAAA,CAAiBjB,CAAAA,CACjB,eAAA,CAAiBA,CAAAA,CAASK,CAAAA,CAAU,MAAA,CACpC,aAAA,CAAe,eAAA,CACf,OAAA,CAASa,CAAAA,CACT,OAAA,CAASE,CAAAA,CAAW,OAAA,CAChB,IAAM,CACJA,CAAAA,CAAW,OAAA,IAAU,CACrBF,CAAAA,GACF,CAAA,CACAA,CACN,CAAuC,CACzC,CAGA,OACEJ,GAAAA,CAACQ,MAAAA,CAAA,CACC,GAAA,CAAKL,CAAAA,CACL,eAAA,CAAejB,CAAAA,CACf,eAAA,CAAeA,CAAAA,CAASK,CAAAA,CAAU,MAAA,CAClC,OAAA,CAASa,CAAAA,CACT,aAAA,CAAY,eAAA,CAEX,QAAA,CAAA7B,CAAAA,CACH,CAEJ,CACA0B,EAAa,WAAA,CAAc,cAAA,CAM3B,SAASQ,CAAAA,EAAmC,CAC1C,GAAM,CAAE,WAAA,CAAAZ,CAAY,CAAA,CAAInC,CAAAA,EAAgB,CAExC,OACEsC,GAAAA,CAACQ,MAAAA,CAAA,CACC,YAAA,CAAW,aAAA,CACX,aAAA,CAAY,aAAA,CACZ,OAAA,CAASX,CAAAA,CACT,SAAA,CAAWtC,CAAAA,EAAyB,CAEpC,QAAA,CAAAyC,GAAAA,CAACU,GAAAA,CAAA,CAAE,SAAA,CAAU,SAAA,CAAU,CAAA,CACzB,CAEJ,CAMA,SAASC,CAAAA,CAAa,CACpB,QAAA,CAAApC,CAAAA,CACA,SAAA,CAAAqC,CAAAA,CAAY,IAAA,CACZ,SAAA,CAAAC,CACF,CAAA,CAA2C,CACzC,GAAM,CAAE,MAAA,CAAA3B,CAAAA,CAAQ,QAAA,CAAAO,CAAAA,CAAU,OAAA,CAAAF,CAAAA,CAAS,OAAA,CAAAC,CAAAA,CAAS,QAAA,CAAAZ,CAAAA,CAAU,KAAA,CAAAC,CAAAA,CAAO,WAAA,CAAAgB,CAAY,CAAA,CACvEnC,CAAAA,EAAgB,CAElB,OAAKwB,CAAAA,CAGDO,CAAAA,CAEAO,GAAAA,CAACc,YAAAA,CAAA,CACC,aAAA,CAAa,IAAA,CACb,4BAAA,CAA8B9D,CAAAA,EAA2B,CACzD,MAAA,CAAQkC,CAAAA,CACR,YAAA,CAAeU,CAAAA,EAAS,CAACA,CAAAA,EAAQC,CAAAA,EAAY,CAC7C,SAAA,CAAU,gCAAA,CAEV,QAAA,CAAAG,GAAAA,CAACe,KAAAA,CAAA,CAAU,SAAA,CAAU,yDAAA,CACnB,QAAA,CAAAC,IAAAA,CAACC,MAAAA,CAAA,CACC,iBAAA,CAAiBzB,CAAAA,CACjB,SAAA,CAAWpD,CAAAA,CACT,wEAAA,CACA,4BAAA,CACAyE,CACF,CAAA,CAEC,QAAA,CAAA,CAAAD,CAAAA,EACCZ,GAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,wBAAA,CACb,QAAA,CAAAA,GAAAA,CAACS,CAAAA,CAAA,EAAmB,CAAA,CACtB,CAAA,CAEDlC,CAAAA,CAAAA,CACH,CAAA,CACF,CAAA,CACF,CAAA,CAMFyC,IAAAA,CAAC,OAAA,CAAA,CACC,EAAA,CAAIzB,CAAAA,CACJ,iBAAA,CAAiBC,CAAAA,CACjB,cAAY,eAAA,CACZ,SAAA,CAAWpD,CAAAA,CAAGc,CAAAA,CAAqB,CAAE,QAAA,CAAA0B,CAAAA,CAAU,KAAA,CAAAC,CAAM,CAAC,CAAA,CAAGgC,CAAS,CAAA,CAEjE,QAAA,CAAA,CAAAtC,CAAAA,CACAqC,CAAAA,EACCZ,GAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,wBAAA,CACb,QAAA,CAAAA,GAAAA,CAACS,CAAAA,CAAA,EAAmB,CAAA,CACtB,CAAA,CAAA,CAEJ,CAAA,CA/CkB,IAiDtB,CACAE,CAAAA,CAAa,WAAA,CAAc,cAAA,CAM3B,SAASO,CAAAA,CAAY,CACnB,QAAA,CAAA3C,CAAAA,CACA,SAAA,CAAAsC,CACF,CAAA,CAA0C,CAIxC,OACEb,GAAAA,CAAC,QAAA,CAAA,CAAO,SAAA,CAAW5D,CAAAA,CAAGgB,CAAAA,EAAoB,CAAGyD,CAAS,CAAA,CACpD,QAAA,CAAAb,GAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,qBAAA,CAAuB,QAAA,CAAAzB,CAAAA,CAAS,CAAA,CACjD,CAEJ,CACA2C,CAAAA,CAAY,WAAA,CAAc,aAAA,CAM1B,SAASC,CAAAA,CAAW,CAClB,QAAA,CAAA5C,CAAAA,CACA,EAAA,CAAI6C,CAAAA,CAAM,IAAA,CACV,SAAA,CAAAP,CACF,CAAA,CAAyC,CACvC,GAAM,CAAE,OAAA,CAAArB,CAAQ,CAAA,CAAI9B,CAAAA,EAAgB,CAEpC,OACEsC,GAAAA,CAACoB,CAAAA,CAAA,CACC,EAAA,CAAI5B,CAAAA,CAIJ,WAAA,CAAU,QAAA,CACV,SAAA,CAAWpD,CAAAA,CACT,wDAAA,CACAyE,CACF,CAAA,CAEC,QAAA,CAAAtC,CAAAA,CACH,CAEJ,CACA4C,CAAAA,CAAW,WAAA,CAAc,YAAA,CAMzB,SAASE,CAAAA,CAAiB,CACxB,QAAA,CAAA9C,CAAAA,CACA,SAAA,CAAAsC,CACF,CAAA,CAA+C,CAC7C,OACEb,GAAAA,CAAC,GAAA,CAAA,CAAE,SAAA,CAAW5D,CAAAA,CAAG,kCAAA,CAAoCyE,CAAS,CAAA,CAC3D,QAAA,CAAAtC,CAAAA,CACH,CAEJ,CACA8C,CAAAA,CAAiB,WAAA,CAAc,kBAAA,CAM/B,SAASC,CAAAA,CAAU,CAAE,QAAA,CAAA/C,CAAAA,CAAU,SAAA,CAAAsC,CAAU,CAAA,CAAwC,CAC/E,OAAOb,GAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAW5D,CAAAA,CAAGiB,CAAAA,EAAkB,CAAGwD,CAAS,CAAA,CAAI,QAAA,CAAAtC,CAAAA,CAAS,CACvE,CACA+C,CAAAA,CAAU,WAAA,CAAc,WAAA,CAMxB,SAASC,CAAAA,CAAY,CACnB,QAAA,CAAAhD,CAAAA,CACA,SAAA,CAAAsC,CACF,CAAA,CAA0C,CAIxC,OACEb,GAAAA,CAAC,QAAA,CAAA,CAAO,SAAA,CAAW5D,CAAAA,CAAGkB,CAAAA,EAAoB,CAAGuD,CAAS,CAAA,CACnD,QAAA,CAAAtC,CAAAA,CACH,CAEJ,CACAgD,CAAAA,CAAY,WAAA,CAAc,aAAA,CAM1B,SAASC,CAAAA,CAAW,CAAE,QAAA,CAAAjD,CAAS,CAAA,CAAyC,CACtE,GAAM,CAAE,WAAA,CAAAsB,CAAY,CAAA,CAAInC,CAAAA,EAAgB,CAExC,GAAI,CAAC2C,cAAAA,CAAe9B,CAAQ,CAAA,CAC1B,OAAO,IAAA,CAIT,IAAM+B,CAAAA,CAAa/B,CAAAA,CAAS,KAAA,CAK5B,OAAOgC,YAAAA,CAAahC,CAAAA,CAAU,CAC5B,OAAA,CAAS,IAAM,CACb+B,CAAAA,CAAW,OAAA,IAAU,CACrBT,CAAAA,GACF,CAAA,CACA,OAAA,CAAS,IAAM,CACbS,CAAAA,CAAW,OAAA,IAAU,CACrBT,CAAAA,GACF,CACF,CAAuC,CACzC,CACA2B,CAAAA,CAAW,WAAA,CAAc,YAAA,CAiClB,IAAMC,EAAAA,CAAQ,MAAA,CAAO,MAAA,CAAOnD,CAAAA,CAAW,CAC5C,OAAA,CAAS2B,CAAAA,CACT,OAAA,CAASU,CAAAA,CACT,MAAA,CAAQO,CAAAA,CACR,KAAA,CAAOC,CAAAA,CACP,WAAA,CAAaE,CAAAA,CACb,IAAA,CAAMC,CAAAA,CACN,MAAA,CAAQC,CAAAA,CACR,KAAA,CAAOC,CACT,CAAC","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Detection + dismissal guard for in-page writing-assistant browser extensions\n * (Grammarly, LanguageTool, Wordtune, …).\n *\n * These extensions inject their suggestion UI as elements appended to `<body>`,\n * outside any open overlay's DOM subtree. React Aria's `isDismissable` behaviour\n * treats a click on that injected UI as an \"outside click\" and dismisses the\n * overlay — so clicking a spelling suggestion silently closes the form pop-up\n * and discards the user's in-progress correction.\n *\n * The guard below lets overlays keep open when the interaction lands on an\n * extension-injected node, while every other outside click, Escape, and the\n * close button behave exactly as before.\n */\n\nconst MAX_ANCESTOR_DEPTH = 100;\n\n/**\n * Returns `true` when `element` belongs to an injected in-page writing\n * assistant (Grammarly, LanguageTool, Wordtune, …).\n *\n * UX-ONLY heuristic. This is a deliberately spoofable DOM sniff used solely to\n * keep a form pop-up open when a writing-assistant suggestion is clicked. It is\n * NOT a security/authorization control and must never gate access to data or\n * actions (the frontend is not a security boundary). Pure function — never log\n * the element (it can reference arbitrary DOM / user content).\n */\nexport function isExtensionInjectedElement(element: Element): boolean {\n if (!(element instanceof Element)) return false;\n\n // 1. Known-vendor markers (authoritative). Walk up via parentElement, and\n // climb shadow boundaries via getRootNode().host so detection still finds\n // the <grammarly-extension> host if React Aria's shadowDOM flag is ever\n // enabled (it defaults to false today → the document-level listener\n // already receives the retargeted host, so the parentElement walk alone\n // suffices currently). Depth-bounded as a defensive guard against a\n // crafted/overridden getRootNode/host returning a cycle (which would\n // otherwise hang the tab — a client-side DoS).\n let node: Element | null = element;\n for (let depth = 0; node && depth < MAX_ANCESTOR_DEPTH; depth++) {\n const tag = node.tagName?.toLowerCase() ?? '';\n if (tag.startsWith('grammarly-')) return true; // Grammarly\n if (tag.startsWith('lt-')) return true; // LanguageTool\n if (node.hasAttribute('data-grammarly-shadow-root')) return true;\n\n if (node.parentElement) {\n node = node.parentElement;\n } else {\n const root = node.getRootNode();\n node = root instanceof ShadowRoot ? root.host : null;\n }\n }\n\n // 2. Structural fallback (best-effort, future-proofs the long tail).\n // Extensions inject their UI as a custom element (hyphenated tag name)\n // mounted as a top-level sibling of the React root — i.e. a direct child\n // of <body>/<html>. Our app never renders body-level custom elements, and\n // React Aria portals render plain <div>s, so this stays safe for any\n // future first-party web component nested inside the app tree.\n let custom: Element | null = element;\n while (custom && !custom.tagName.includes('-')) {\n custom = custom.parentElement;\n }\n if (!custom) return false;\n\n const parent = custom.parentElement;\n return parent === document.body || parent === document.documentElement;\n}\n\n/**\n * Builds a `shouldCloseOnInteractOutside` predicate for React Aria overlays\n * that keeps the overlay open when the interaction targets an extension-injected\n * element, while preserving any consumer-supplied predicate.\n *\n * React Aria semantics: the predicate returns `true` ⇒ the overlay should\n * close. So we close only when the element is NOT extension-injected AND the\n * consumer (if any) also agrees it should close.\n */\nexport function createInteractOutsideGuard(\n consumerShouldClose?: (element: Element) => boolean,\n): (element: Element) => boolean {\n return (element: Element): boolean =>\n !isExtensionInjectedElement(element) && (consumerShouldClose?.(element) ?? true);\n}\n","\"use client\";\n\n/**\n * Panel Component - Accessible Non-Modal Sidebar\n * Disclosure pattern + Complementary region for WCAG 2.2 AAA\n *\n * @see plan.md for architecture details\n * @see panel-prd.md for requirements\n * @see ADR 0007 for accessibility decisions\n */\n\nimport {\n type ReactElement,\n type MutableRefObject,\n createContext,\n useContext,\n useState,\n useId,\n useRef,\n useCallback,\n useEffect,\n cloneElement,\n isValidElement,\n} from \"react\";\nimport {\n Button as AriaButton,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n} from \"react-aria-components\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { createInteractOutsideGuard } from \"../../utils/browserExtensionOverlay\";\nimport type {\n PanelProps,\n PanelTriggerProps,\n PanelContentProps,\n PanelHeaderProps,\n PanelTitleProps,\n PanelDescriptionProps,\n PanelBodyProps,\n PanelFooterProps,\n PanelCloseProps,\n PanelPosition,\n PanelWidth,\n} from \"./Panel.types\";\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * Panel content variants\n * Controls position-based styling and width\n */\nexport const panelContentVariants = cva(\n [\n \"flex flex-col h-full overflow-hidden\",\n \"bg-[var(--content-background)] text-[var(--content-foreground)]\",\n ],\n {\n variants: {\n position: {\n right: \"border-l border-[var(--border)]\",\n left: \"border-r border-[var(--border)]\",\n },\n width: {\n sm: \"w-[300px]\",\n md: \"w-[400px]\",\n lg: \"w-[500px]\",\n xl: \"w-[600px]\",\n auto: \"w-auto\",\n },\n },\n defaultVariants: {\n position: \"right\",\n width: \"md\",\n },\n }\n);\n\n/**\n * Panel header variants\n */\nexport const panelHeaderVariants = cva([\n \"flex items-start justify-between\",\n \"px-4 py-4\",\n \"border-b border-[var(--border)]\",\n]);\n\n/**\n * Panel body variants\n */\nexport const panelBodyVariants = cva([\"flex-1 overflow-y-auto\", \"px-4 py-4\"]);\n\n/**\n * Panel footer variants\n */\nexport const panelFooterVariants = cva([\n \"flex items-center justify-end gap-2\",\n \"px-4 py-4\",\n \"border-t border-[var(--border)]\",\n]);\n\n/**\n * Close button variants\n */\nexport const panelCloseButtonVariants = cva([\n \"inline-flex items-center justify-center rounded-md\",\n \"min-h-[44px] min-w-[44px]\",\n \"text-[var(--menu-muted)]\",\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2\",\n // No transition - instant state changes (v1)\n]);\n\n// ============================================================================\n// Context\n// ============================================================================\n\ninterface PanelContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n panelId: string;\n titleId: string;\n triggerRef: MutableRefObject<HTMLElement | null>;\n position: PanelPosition;\n width: PanelWidth;\n mobileBreakpoint: number;\n isMobile: boolean;\n handleClose: () => void;\n}\n\nconst PanelContext = createContext<PanelContextValue | null>(null);\n\nfunction usePanelContext(): PanelContextValue {\n const context = useContext(PanelContext);\n if (!context) {\n throw new Error(\"Panel compound components must be used within a Panel\");\n }\n return context;\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * SSR-safe media query hook\n * Defaults to false on server (desktop mode)\n */\nfunction useMediaQuery(query: string): boolean {\n const [matches, setMatches] = useState(() => {\n // Default to false on server (desktop mode)\n if (typeof window === \"undefined\") return false;\n return window.matchMedia(query).matches;\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const media = window.matchMedia(query);\n // Sync state after mount (handles SSR mismatch)\n if (media.matches !== matches) {\n setMatches(media.matches);\n }\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\n media.addEventListener(\"change\", listener);\n return () => media.removeEventListener(\"change\", listener);\n }, [query, matches]);\n\n return matches;\n}\n\n// ============================================================================\n// Panel Root\n// ============================================================================\n\nfunction PanelRoot({\n children,\n isOpen: controlledIsOpen,\n defaultOpen = false,\n onOpenChange,\n onClose,\n position = \"right\",\n width = \"md\",\n mobileBreakpoint = 768,\n}: PanelProps): ReactElement {\n // State management (controlled/uncontrolled)\n const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(defaultOpen);\n const isControlled = controlledIsOpen !== undefined;\n const isOpen = isControlled ? controlledIsOpen : uncontrolledIsOpen;\n\n // Refs\n const triggerRef = useRef<HTMLElement | null>(null);\n\n // IDs for ARIA\n const uniqueId = useId();\n const panelId = `panel-${uniqueId}`;\n const titleId = `panel-title-${uniqueId}`;\n\n // Responsive detection\n const isMobile = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);\n\n // State setter\n const setIsOpen = useCallback(\n (open: boolean) => {\n if (!isControlled) {\n setUncontrolledIsOpen(open);\n }\n onOpenChange?.(open);\n },\n [isControlled, onOpenChange]\n );\n\n // Close handler with focus restoration\n const handleClose = useCallback(() => {\n setIsOpen(false);\n onClose?.();\n // Return focus to trigger if it still exists in DOM\n if (triggerRef.current) {\n window.requestAnimationFrame(() => {\n triggerRef.current?.focus();\n });\n }\n }, [setIsOpen, onClose]);\n\n // Escape key handler (desktop only - mobile handled by React Aria)\n useEffect(() => {\n if (!isOpen || isMobile) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n handleClose();\n }\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [isOpen, isMobile, handleClose]);\n\n const contextValue: PanelContextValue = {\n isOpen,\n setIsOpen,\n panelId,\n titleId,\n triggerRef,\n position,\n width,\n mobileBreakpoint,\n isMobile,\n handleClose,\n };\n\n return (\n <PanelContext.Provider value={contextValue}>\n {children}\n </PanelContext.Provider>\n );\n}\nPanelRoot.displayName = \"Panel\";\n\n// ============================================================================\n// Panel.Trigger\n// ============================================================================\n\nfunction PanelTrigger({\n children,\n asChild = true,\n}: PanelTriggerProps): ReactElement | null {\n const { isOpen, setIsOpen, panelId, triggerRef } = usePanelContext();\n\n // Capture ref via callback ref pattern\n const setRef = useCallback(\n (element: HTMLElement | null) => {\n triggerRef.current = element;\n },\n [triggerRef]\n );\n\n const handlePress = useCallback(() => {\n setIsOpen(!isOpen);\n }, [setIsOpen, isOpen]);\n\n // If asChild, clone the child element and add props\n if (asChild && isValidElement(children)) {\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n return cloneElement(children, {\n ref: setRef,\n \"aria-expanded\": isOpen,\n \"aria-controls\": isOpen ? panelId : undefined,\n \"data-testid\": \"panel-trigger\",\n onPress: handlePress,\n onClick: childProps.onClick\n ? () => {\n childProps.onClick?.();\n handlePress();\n }\n : handlePress,\n } as unknown as Record<string, unknown>);\n }\n\n // Fallback: wrap in AriaButton\n return (\n <AriaButton\n ref={setRef}\n aria-expanded={isOpen}\n aria-controls={isOpen ? panelId : undefined}\n onPress={handlePress}\n data-testid=\"panel-trigger\"\n >\n {children}\n </AriaButton>\n );\n}\nPanelTrigger.displayName = \"PanelTrigger\";\n\n// ============================================================================\n// Built-in Close Button\n// ============================================================================\n\nfunction BuiltInCloseButton(): ReactElement {\n const { handleClose } = usePanelContext();\n\n return (\n <AriaButton\n aria-label=\"Close panel\"\n data-testid=\"panel-close\"\n onPress={handleClose}\n className={panelCloseButtonVariants()}\n >\n <X className=\"h-5 w-5\" />\n </AriaButton>\n );\n}\n\n// ============================================================================\n// Panel.Content\n// ============================================================================\n\nfunction PanelContent({\n children,\n showClose = true,\n className,\n}: PanelContentProps): ReactElement | null {\n const { isOpen, isMobile, panelId, titleId, position, width, handleClose } =\n usePanelContext();\n\n if (!isOpen) return null;\n\n // Mobile: Use React Aria Modal primitives\n if (isMobile) {\n return (\n <AriaModalOverlay\n isDismissable\n shouldCloseOnInteractOutside={createInteractOutsideGuard()}\n isOpen={isOpen}\n onOpenChange={(open) => !open && handleClose()}\n className=\"fixed inset-0 z-50 bg-black/50\"\n >\n <AriaModal className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <AriaDialog\n aria-labelledby={titleId}\n className={cn(\n \"w-full max-w-lg rounded-lg bg-[var(--content-background)] outline-none\",\n \"flex max-h-[90vh] flex-col\",\n className\n )}\n >\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n {children}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n }\n\n // Desktop: Render aside in-place\n return (\n <aside\n id={panelId}\n aria-labelledby={titleId}\n data-testid=\"panel-content\"\n className={cn(panelContentVariants({ position, width }), className)}\n >\n {children}\n {showClose && (\n <div className=\"absolute right-2 top-2\">\n <BuiltInCloseButton />\n </div>\n )}\n </aside>\n );\n}\nPanelContent.displayName = \"PanelContent\";\n\n// ============================================================================\n// Panel.Header\n// ============================================================================\n\nfunction PanelHeader({\n children,\n className,\n}: PanelHeaderProps): ReactElement | null {\n // Note: We use a <header> element but DON'T add role=\"banner\"\n // because banner landmarks should not be contained in other landmarks (like aside)\n // The header element still provides structural meaning for the panel\n return (\n <header className={cn(panelHeaderVariants(), className)}>\n <div className=\"flex flex-col gap-1\">{children}</div>\n </header>\n );\n}\nPanelHeader.displayName = \"PanelHeader\";\n\n// ============================================================================\n// Panel.Title\n// ============================================================================\n\nfunction PanelTitle({\n children,\n as: Tag = \"h2\",\n className,\n}: PanelTitleProps): ReactElement | null {\n const { titleId } = usePanelContext();\n\n return (\n <Tag\n id={titleId}\n // aria-live=\"polite\" announces title changes to screen readers\n // This is important for master-detail patterns where panel content\n // updates when selecting different items (e.g., candidate profiles)\n aria-live=\"polite\"\n className={cn(\n \"text-lg font-semibold text-[var(--content-foreground)]\",\n className\n )}\n >\n {children}\n </Tag>\n );\n}\nPanelTitle.displayName = \"PanelTitle\";\n\n// ============================================================================\n// Panel.Description\n// ============================================================================\n\nfunction PanelDescription({\n children,\n className,\n}: PanelDescriptionProps): ReactElement | null {\n return (\n <p className={cn(\"text-sm text-[var(--menu-muted)]\", className)}>\n {children}\n </p>\n );\n}\nPanelDescription.displayName = \"PanelDescription\";\n\n// ============================================================================\n// Panel.Body\n// ============================================================================\n\nfunction PanelBody({ children, className }: PanelBodyProps): ReactElement | null {\n return <div className={cn(panelBodyVariants(), className)}>{children}</div>;\n}\nPanelBody.displayName = \"PanelBody\";\n\n// ============================================================================\n// Panel.Footer\n// ============================================================================\n\nfunction PanelFooter({\n children,\n className,\n}: PanelFooterProps): ReactElement | null {\n // Note: We use a <footer> element but DON'T add role=\"contentinfo\"\n // because contentinfo landmarks should not be contained in other landmarks (like aside)\n // The footer element still provides structural meaning for the panel\n return (\n <footer className={cn(panelFooterVariants(), className)}>\n {children}\n </footer>\n );\n}\nPanelFooter.displayName = \"PanelFooter\";\n\n// ============================================================================\n// Panel.Close\n// ============================================================================\n\nfunction PanelClose({ children }: PanelCloseProps): ReactElement | null {\n const { handleClose } = usePanelContext();\n\n if (!isValidElement(children)) {\n return null;\n }\n\n // Clone the child and add onPress/onClick handler\n const childProps = children.props as unknown as {\n onPress?: () => void;\n onClick?: () => void;\n };\n\n return cloneElement(children, {\n onPress: () => {\n childProps.onPress?.();\n handleClose();\n },\n onClick: () => {\n childProps.onClick?.();\n handleClose();\n },\n } as unknown as Record<string, unknown>);\n}\nPanelClose.displayName = \"PanelClose\";\n\n// ============================================================================\n// Compound Component Export\n// ============================================================================\n\n/**\n * Panel Component\n *\n * Accessible non-modal sidebar panel using the disclosure pattern with\n * a complementary region for WCAG 2.2 AAA compliance.\n *\n * @example\n * ```tsx\n * <Panel>\n * <Panel.Trigger>\n * <Button>Open Panel</Button>\n * </Panel.Trigger>\n * <Panel.Content>\n * <Panel.Header>\n * <Panel.Title>Panel Title</Panel.Title>\n * <Panel.Description>Optional description</Panel.Description>\n * </Panel.Header>\n * <Panel.Body>\n * Panel content here\n * </Panel.Body>\n * <Panel.Footer>\n * <Button>Action</Button>\n * </Panel.Footer>\n * </Panel.Content>\n * </Panel>\n * ```\n */\nexport const Panel = Object.assign(PanelRoot, {\n Trigger: PanelTrigger,\n Content: PanelContent,\n Header: PanelHeader,\n Title: PanelTitle,\n Description: PanelDescription,\n Body: PanelBody,\n Footer: PanelFooter,\n Close: PanelClose,\n});\n\n// Named exports for individual components\nexport {\n PanelRoot,\n PanelTrigger,\n PanelContent,\n PanelHeader,\n PanelTitle,\n PanelDescription,\n PanelBody,\n PanelFooter,\n PanelClose,\n};\n\n// Export CVA variant types for customization\nexport type PanelContentVariants = VariantProps<typeof panelContentVariants>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ResizablePopover.d.ts","sourceRoot":"","sources":["../../../../src/elements/Resizable/components/ResizablePopover.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQlE,UAAU,qBAAqB;IAC7B,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,8BAA8B;IAC9B,UAAU,EAAE,SAAS,CAAC;IACtB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,mBAAmB;IACnB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,mCAAmC;IACnC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACnD,gCAAgC;IAChC,SAAS,EAAE,YAAY,GAAG,UAAU,CAAC;CACtC;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,kHA8N5B,CAAC"}
1
+ {"version":3,"file":"ResizablePopover.d.ts","sourceRoot":"","sources":["../../../../src/elements/Resizable/components/ResizablePopover.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQlE,UAAU,qBAAqB;IAC7B,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,8BAA8B;IAC9B,UAAU,EAAE,SAAS,CAAC;IACtB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7D,mBAAmB;IACnB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,mCAAmC;IACnC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACnD,gCAAgC;IAChC,SAAS,EAAE,YAAY,GAAG,UAAU,CAAC;CACtC;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,kHA+N5B,CAAC"}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- 'use strict';var react=require('react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),reactAriaComponents=require('react-aria-components');function z(...r){return tailwindMerge.twMerge(clsx.clsx(r))}var ie=react.createContext(null);ie.displayName="ResizableContext";function K(){let r=react.useContext(ie);if(!r)throw new Error("useResizableContext must be used within a ResizablePanelGroup. Make sure ResizablePanel and ResizableHandle are children of ResizablePanelGroup.");return r}function Pe({direction:r,groupLabel:e,sizes:a,onSizesChange:t}){let[m,n]=react.useState([]),[i,l]=react.useState([]),o=react.useRef(null),c=react.useRef(null),v=react.useRef(null),f=react.useRef(false),T=a!==void 0,h=T?a:m,R=react.useCallback(b=>{T?t?.(b):n(b);},[T,t]),P=react.useCallback((b,s)=>{l(_=>{let A=[..._];return A[b]=s,A});},[]),D=react.useCallback(b=>{l(s=>{let _=[...s];return delete _[b],_.filter(Boolean)});},[]);react.useEffect(()=>{if(T||f.current)return;let s=i.filter(Boolean).length;if(s<2)return;if(h.length<s||h.some(A=>A===void 0)){let A=[],p=100/s;for(let d=0;d<s;d++)A[d]=p;f.current=true,n(A);}},[i,h,T]),react.useEffect(()=>()=>{v.current&&clearTimeout(v.current),c.current&&(document.body.removeChild(c.current),c.current=null);},[]);let E=react.useCallback(b=>{if(!c.current){let s=document.createElement("div");s.setAttribute("aria-live","polite"),s.setAttribute("aria-atomic","true"),s.className="sr-only",s.style.cssText="position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;",document.body.appendChild(s),c.current=s;}c.current.textContent=b,v.current&&clearTimeout(v.current),v.current=setTimeout(()=>{c.current&&(c.current.textContent="");},1e3);},[]);return {direction:r,groupLabel:e,sizes:h,setSizes:R,panels:i,registerPanel:P,unregisterPanel:D,announce:E,containerRef:o}}var De=react.forwardRef(function({direction:e,groupLabel:a,sizes:t,onSizesChange:m,className:n,children:i},l){let o=Pe({direction:e,groupLabel:a,sizes:t,onSizesChange:m});return react.useImperativeHandle(l,()=>o.containerRef.current,[o.containerRef]),jsxRuntime.jsx(ie.Provider,{value:o,children:jsxRuntime.jsx("div",{ref:o.containerRef,role:"group","aria-label":`${a}, ${e}`,"data-direction":e,className:z("flex h-full w-full",e==="horizontal"?"flex-row":"flex-col",n),children:i})})});De.displayName="ResizablePanelGroup";var $=10,Y=90,se=300,Ve=zod.z.object({label:zod.z.string().min(1),sizes:zod.z.array(zod.z.number().min(0).max(100))}),gt=zod.z.object({direction:zod.z.enum(["horizontal","vertical"]),groupLabel:zod.z.string().min(1),sizes:zod.z.array(zod.z.number().min(0).max(100)).optional(),onSizesChange:zod.z.function().optional(),className:zod.z.string().optional(),children:zod.z.custom()}),St=zod.z.object({name:zod.z.string().min(1),defaultSize:zod.z.number().min(0).max(100).optional(),minSize:zod.z.number().min(0).max(100).optional().default($),maxSize:zod.z.number().min(0).max(100).optional().default(Y),collapsible:zod.z.boolean().optional().default(false),onCollapse:zod.z.function().optional(),onExpand:zod.z.function().optional(),onResize:zod.z.function().optional(),className:zod.z.string().optional(),children:zod.z.custom()}),Rt=zod.z.object({withHandle:zod.z.boolean().optional().default(true),presets:zod.z.array(Ve).optional(),disabled:zod.z.boolean().optional().default(false),className:zod.z.string().optional()}),xe=classVarianceAuthority.cva(["relative flex items-center justify-center","shrink-0","bg-transparent","transition-colors duration-150","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2","touch-none select-none"],{variants:{direction:{horizontal:["w-3 min-w-[12px]","cursor-col-resize","hover:bg-[var(--accent)]/50","before:absolute before:inset-y-0 before:-inset-x-4","before:min-w-[44px]"],vertical:["h-3 min-h-[12px]","cursor-row-resize","hover:bg-[var(--accent)]/50","before:absolute before:inset-x-0 before:-inset-y-4","before:min-h-[44px]"]},disabled:{true:"cursor-not-allowed opacity-50 pointer-events-none",false:""},isDragging:{true:"bg-[var(--accent)]",false:""}},defaultVariants:{direction:"horizontal",disabled:false,isDragging:false}}),ve=classVarianceAuthority.cva(["flex items-center justify-center","rounded-full","bg-[var(--border)]","text-[var(--menu-muted)]"],{variants:{direction:{horizontal:"h-8 w-1",vertical:"h-1 w-8"}},defaultVariants:{direction:"horizontal"}});var Ce=react.forwardRef(function({name:e,defaultSize:a,minSize:t=$,maxSize:m=Y,collapsible:n=false,onCollapse:i,onExpand:l,onResize:o,className:c,children:v},f){let{sizes:T,registerPanel:h,unregisterPanel:R,containerRef:P}=K(),D=react.useRef(null),[E,b]=react.useState(-1),s=react.useRef(null),_=react.useRef(false),A=react.useRef(-1);react.useEffect(()=>{let d=D.current,x=P.current;if(!d||!x)return;let N=x.querySelectorAll("[data-resizable-panel]"),y=-1;for(let O=0;O<N.length;O++)if(N[O]===d){y=O;break}if(y!==-1)return E!==y&&b(y),_.current||(_.current=true,A.current=y,h(y,{name:e,minSize:t,maxSize:m,collapsible:n})),()=>{_.current&&(R(A.current),_.current=false);}},[P,h,R,e,t,m,n,E]);let p=E>=0?T[E]??50:50;return react.useEffect(()=>{if(s.current===null){s.current=p;return}let d=s.current===0,x=p===0;!d&&x&&i?i():d&&!x&&l&&l(),o&&s.current!==p&&o(p),s.current=p;},[p,i,l,o]),jsxRuntime.jsx("div",{ref:d=>{D.current=d,typeof f=="function"?f(d):f&&(f.current=d);},role:"region","aria-label":e,"data-resizable-panel":"","data-panel-name":e,"data-panel-index":E,"data-collapsed":p===0,style:{flexBasis:`${p}%`,flexGrow:0,flexShrink:0,overflow:"hidden"},className:z("relative",c),children:v})});Ce.displayName="ResizablePanel";function Me(r,e,a){return Math.max(e,Math.min(a,r))}function He(r,e,a,t,m){let n=[...r],i=e[a],l=e[t];if(!i||!l)return r;let o=r[a]??50,c=r[t]??50,v=o+m,f,T=i.collapsible?0:i.minSize,h=i.maxSize,R=l.collapsible?0:l.minSize,P=l.maxSize;return v=Me(v,T,h),f=o+c-v,f=Me(f,R,P),v=o+c-f,n[a]=v,n[t]=f,n}function Fe({direction:r,sizes:e,setSizes:a,panels:t,containerRef:m,leftPanelIndex:n,rightPanelIndex:i,disabled:l=false,announce:o,groupLabel:c,onOpenPopover:v}){let[f,T]=react.useState(false),h=react.useRef(null),R=react.useRef(null),P=react.useRef(0),D=react.useRef(false),E=react.useRef(t),b=react.useRef(e),s=react.useRef(a),_=react.useRef(()=>{}),A=react.useRef(()=>{});react.useEffect(()=>{E.current=t,b.current=e,s.current=a;},[t,e,a]);let p=react.useCallback(()=>{let g=m.current;return g?r==="horizontal"?g.offsetWidth:g.offsetHeight:0},[m,r]),d=react.useCallback(g=>{let L=p();return L===0?0:g/L*100},[p]),x=react.useCallback(g=>{_.current(g);},[]),N=react.useCallback(()=>{A.current();},[]),y=react.useCallback(g=>{if(!h.current||l)return;let V=(r==="horizontal"?g.clientX:g.clientY)-h.current.position,I=d(V),w=He(h.current.sizes,E.current,n,i,I);s.current(w);},[r,l,n,d,i]),O=react.useCallback(()=>{if(R.current&&(clearTimeout(R.current),R.current=null),Date.now()-P.current<se&&!D.current&&v&&!l&&v(),f){T(false);let V=E.current[n],I=Math.round(b.current[n]??50);o&&V&&c&&o(`${V.name} in ${c} resized to ${I} percent`);}h.current=null,D.current=false,document.removeEventListener("pointermove",x),document.removeEventListener("pointerup",N),document.removeEventListener("pointercancel",N),document.body.style.cursor="",document.body.style.userSelect="";},[o,l,c,f,n,v,x,N]);react.useEffect(()=>{_.current=y,A.current=O;});let U=react.useCallback(g=>{if(l)return;g.preventDefault();let L=r==="horizontal"?g.clientX:g.clientY;P.current=Date.now(),D.current=false,h.current={position:L,sizes:[...e],containerSize:p()},R.current=setTimeout(()=>{D.current=true,T(true),document.body.style.cursor=r==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none";},se),document.addEventListener("pointermove",x),document.addEventListener("pointerup",N),document.addEventListener("pointercancel",N),g.pointerType==="mouse"&&(R.current&&(clearTimeout(R.current),R.current=null),D.current=true,T(true),document.body.style.cursor=r==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none");},[r,l,p,x,N,e]),C=react.useCallback(g=>{if(l)return;let L=g.shiftKey?10:1,V=0;switch(g.key){case "ArrowLeft":case "ArrowUp":V=-L;break;case "ArrowRight":case "ArrowDown":V=L;break;case "Home":{let I=t[n];I&&(V=(I.collapsible?0:I.minSize)-(e[n]??50));break}case "End":{let I=t[n];I&&(V=I.maxSize-(e[n]??50));break}case "Enter":case " ":g.preventDefault(),v?.();return;default:return}if(V!==0){g.preventDefault();let I=He(e,t,n,i,V);a(I);let w=t[n],F=Math.round(I[n]??50);o&&w&&c&&o(`${w.name} in ${c} resized to ${F} percent`);}},[o,l,c,n,v,t,i,a,e]);return react.useEffect(()=>{let g=x,L=N;return ()=>{R.current&&clearTimeout(R.current),document.removeEventListener("pointermove",g),document.removeEventListener("pointerup",L),document.removeEventListener("pointercancel",L);}},[x,N]),{isDragging:f,handlePointerDown:U,handleKeyDown:C}}var Se=classVarianceAuthority.cva("inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",{variants:{fullWidth:{true:"w-full",false:""},inVerticalGroup:{true:"items-stretch",false:"items-center"}},defaultVariants:{fullWidth:false,inVerticalGroup:false}}),Re=classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",{variants:{variant:{default:"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1",destructive:"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake",outline:"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)]",secondary:"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]",ghost:"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]",link:"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]"},fullWidth:{true:"w-full",false:""},visualSize:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3 text-xs",lg:"h-11 rounded-md px-6 text-base",icon:"h-10 w-10",dot:"h-5 w-5 rounded-full p-0 min-h-0 min-w-0"},paywall:{true:"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",false:""}},defaultVariants:{variant:"default",visualSize:"default",paywall:false}});var he="data-[pressed]:scale-[0.97]";var ue="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",ce="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";var $e=react.createContext(null);$e.displayName="ButtonGroupContext";function Ye(){return react.useContext($e)}var Ze=react.createContext(null);Ze.displayName="ButtonGroupItemContext";function je(){return react.useContext(Ze)}classVarianceAuthority.cva("inline-flex items-center gap-0",{variants:{orientation:{horizontal:"flex-row",vertical:"flex-col w-full"}},defaultVariants:{orientation:"horizontal"}});var Xe=classVarianceAuthority.cva("",{variants:{orientation:{horizontal:"min-w-[44px]",vertical:"flex min-h-[44px]"},position:{first:"",middle:"",last:"",only:""}},compoundVariants:[{orientation:"horizontal",position:"first",className:"rounded-r-none border-r-0"},{orientation:"horizontal",position:"middle",className:"rounded-none border-r-0"},{orientation:"horizontal",position:"last",className:"rounded-l-none"},{orientation:"vertical",position:"first",className:"rounded-b-none border-b-0"},{orientation:"vertical",position:"middle",className:"rounded-none border-b-0"},{orientation:"vertical",position:"last",className:"rounded-t-none"}],defaultVariants:{orientation:"horizontal",position:"only"}});classVarianceAuthority.cva("bg-[var(--border)]",{variants:{orientation:{horizontal:"w-px h-6 mx-1",vertical:"h-px w-full my-1"}},defaultVariants:{orientation:"horizontal"}});var G=react.memo(react.forwardRef(({className:r,buttonVisualClassName:e,variant:a,size:t,visualSize:m,fullWidth:n,loading:i=false,loadingText:l="Loading...",shortcut:o,children:c,isDisabled:v,paywall:f=false,paywallRedirect:T,paywallDescription:h,onPress:R,...P},D)=>{let E=react.useId(),b=Ye(),s=je(),_=a??b?.variant??"default",A=t??b?.size,p=v??b?.isDisabled??false,d=b?.orientation==="vertical",x=n||d,N=s?Xe({orientation:b?.orientation??"horizontal",position:s.position}):"",y=m??A??"default";return process.env.NODE_ENV!=="production"&&(y==="dot"||y==="icon")&&!P["aria-label"]&&!c&&console.warn('[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'),jsxRuntime.jsx(reactAriaComponents.Button,{ref:D,isDisabled:p||i||void 0,"aria-disabled":f?true:void 0,"aria-describedby":f?E:void 0,onPress:C=>{if(f){T&&window.open(T,"_blank","noopener,noreferrer");return}R?.(C);},className:z(Se({fullWidth:x,inVerticalGroup:d}),r),...P,children:C=>jsxRuntime.jsxs("span",{className:z(Re({variant:_,visualSize:y,paywall:f,fullWidth:x}),N,e,he,"",ue,ce),"data-pressed":C.isPressed||void 0,children:[i&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(lucideReact.Loader2,{className:"motion-safe:animate-spin","aria-hidden":"true"}),jsxRuntime.jsx("span",{className:"sr-only","aria-live":"polite",children:l})]}),!i&&c,f&&jsxRuntime.jsx(lucideReact.Zap,{"data-testid":"zap-icon","aria-hidden":"true",className:"ml-1"}),f&&jsxRuntime.jsxs("span",{id:E,className:"sr-only",children:["Premium feature: ",h||"Upgrade required to access this feature"]}),C.isFocusVisible&&o&&jsxRuntime.jsx("kbd",{className:"ml-auto hidden text-xs opacity-60 lg:inline",children:o})]})})}));G.displayName="Button";var J={sm:"text-xs",default:"text-sm",lg:"text-base"};var de={sm:"h-9",default:"h-10",lg:"h-11"},ee={sm:`${de.sm} px-2 text-xs`,default:`${de.default} px-3 text-sm`,lg:`${de.lg} px-4 text-base`},_e="min-h-[44px] flex items-center";function qe(r,e){return !(r===false||e)}var We="(prefers-reduced-motion: reduce)";function Ct(){return typeof window>"u"?false:window.matchMedia(We).matches}function Ke(){let[r,e]=react.useState(Ct);return react.useEffect(()=>{let a=window.matchMedia(We);e(a.matches);let t=m=>{e(m.matches);};return a.addEventListener("change",t),()=>a.removeEventListener("change",t)},[]),r}var Qe=4294967295,Je=0,et=-2147483647;zod.z.object({value:zod.z.number().nullable().optional(),defaultValue:zod.z.number().optional(),minValue:zod.z.number().optional(),maxValue:zod.z.number().optional(),allowNegative:zod.z.boolean().optional(),step:zod.z.number().positive().optional(),formatOptions:zod.z.custom().optional(),isDisabled:zod.z.boolean().optional(),isReadOnly:zod.z.boolean().optional(),isRequired:zod.z.boolean().optional(),isInvalid:zod.z.boolean().optional(),isWheelDisabled:zod.z.boolean().optional(),validate:zod.z.function().optional(),validationBehavior:zod.z.enum(["native","aria"]).default("native"),label:zod.z.string(),description:zod.z.string().optional(),errorMessage:zod.z.union([zod.z.string(),zod.z.function()]).optional(),stepperLayout:zod.z.enum(["sides","stacked","hidden"]).default("sides"),incrementAriaLabel:zod.z.string().optional(),decrementAriaLabel:zod.z.string().optional(),name:zod.z.string().optional(),size:zod.z.enum(["sm","default","lg"]).default("default"),onChange:zod.z.function().optional(),onFocus:zod.z.function().optional(),onBlur:zod.z.function().optional(),onFocusChange:zod.z.function().optional(),animated:zod.z.boolean().optional().default(true),springConfig:zod.z.object({stiffness:zod.z.number(),damping:zod.z.number()}).optional(),className:zod.z.string().optional(),autoFocus:zod.z.boolean().optional()});var tt=classVarianceAuthority.cva(["inline-flex items-center rounded-md border","bg-[var(--content-background)] text-[var(--content-foreground)]","transition-colors duration-200","focus-within:ring-2 focus-within:ring-[var(--ring)] focus-within:ring-offset-2","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50"],{variants:{size:{sm:`${ee.sm}`,default:`${ee.default}`,lg:`${ee.lg}`},isInvalid:{true:"border-[var(--destructive-background)] focus-within:ring-[var(--destructive-background)]",false:"border-[var(--input-border)] hover:border-[var(--input-border)]/80"}},defaultVariants:{size:"default",isInvalid:false}}),nt=classVarianceAuthority.cva(["flex-1 bg-transparent text-center tabular-nums","min-w-0","focus:outline-none","[appearance:textfield]","[&::-webkit-outer-spin-button]:appearance-none","[&::-webkit-inner-spin-button]:appearance-none"],{variants:{size:{sm:`px-2 ${J.sm}`,default:`px-3 ${J.default}`,lg:`px-4 ${J.lg}`}},defaultVariants:{size:"default"}}),te=classVarianceAuthority.cva(["flex items-center justify-center","transition-colors duration-150","select-none","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]","focus-visible:ring-inset","active:bg-[var(--accent)]/80","disabled:pointer-events-none disabled:opacity-50"],{variants:{size:{sm:"min-w-8 min-h-8 text-sm",default:"min-w-10 min-h-10 text-base",lg:"min-w-12 min-h-12 text-lg"},position:{left:"rounded-l-md border-r border-[var(--input-border)]",right:"rounded-r-md border-l border-[var(--input-border)]",top:"rounded-tr-md border-b border-l border-[var(--input-border)] h-1/2",bottom:"rounded-br-md border-l border-[var(--input-border)] h-1/2"}},defaultVariants:{size:"default"}}),ot=classVarianceAuthority.cva(["block font-medium text-[var(--content-foreground)]","mb-1.5",'data-[required]:after:content-["*"] data-[required]:after:ml-0.5',"data-[required]:after:text-[var(--destructive-background)]"],{variants:{size:{sm:"text-sm",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}}),rt=classVarianceAuthority.cva(["text-[var(--menu-muted)]","mt-1"],{variants:{size:{sm:"text-xs",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}}),at=classVarianceAuthority.cva(["flex items-center gap-1","text-[var(--destructive-background)]","font-medium","mt-1"],{variants:{size:{sm:"text-xs",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}});var ne;function $t(){return ne!==void 0?Promise.resolve(ne):import('motion').then(r=>(ne=r.animate,ne)).catch(()=>(ne=null,null))}function Yt(r,e){if(e)try{let a={...e};return a.style==="currency"&&!a.currencyDisplay&&(a.currencyDisplay="narrowSymbol"),new Intl.NumberFormat(void 0,a).format(r)}catch{return String(Math.round(r))}return String(Math.round(r))}var fe=react.forwardRef(({label:r,description:e,errorMessage:a,size:t="default",stepperLayout:m="sides",allowNegative:n=false,incrementAriaLabel:i,decrementAriaLabel:l,animated:o,springConfig:c,onChange:v,value:f,defaultValue:T,formatOptions:h,minValue:R,maxValue:P,className:D,isInvalid:E,isRequired:b,isDisabled:s,isReadOnly:_,...A},p)=>{let d=R??(n?et:Je),x=P??Qe,N=m!=="hidden"&&!_,y=Ke(),O=qe(o,y)&&N,U=react.useRef(null),C=react.useRef(f??T??0),g=react.useRef(void 0),L=react.useRef(null);react.useEffect(()=>{O&&$t().then(w=>{g.current=w??null;});},[O]),react.useEffect(()=>()=>{L.current?.stop();},[]);let V=w=>{let F=C.current;if(O&&g.current&&U.current&&F!==w){L.current?.stop();let W=w,Z=U.current,j=Z.parentElement?.querySelector("input");Z.style.display="",j&&(j.style.color="transparent"),L.current=g.current(F,W,{type:"spring",stiffness:c?.stiffness??500,damping:c?.damping??30,onUpdate:Ie=>{C.current=Ie,Z.textContent=Yt(Ie,h);},onComplete:()=>{Z.style.display="none",j&&(j.style.color=""),L.current=null,C.current=W;}});}else C.current=w;v?.(w);},I=m==="stacked";return jsxRuntime.jsxs(reactAriaComponents.NumberField,{ref:p,className:z("group flex flex-col",D),minValue:d,maxValue:x,isInvalid:E,isRequired:b,isDisabled:s,isReadOnly:_,value:f,defaultValue:T,formatOptions:h,onChange:V,...A,children:[jsxRuntime.jsx(reactAriaComponents.Label,{className:z(ot({size:t})),"data-required":b||void 0,children:r}),jsxRuntime.jsxs(reactAriaComponents.Group,{className:z(_e,tt({size:t,isInvalid:E??false}),I&&"pr-0"),children:[N&&!I&&jsxRuntime.jsx(G,{slot:"decrement",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"left"})),"aria-label":l??"Decrease value",children:jsxRuntime.jsx(lucideReact.Minus,{className:"h-4 w-4","aria-hidden":"true"})}),jsxRuntime.jsxs("div",{className:"relative flex flex-1",children:[jsxRuntime.jsx(reactAriaComponents.Input,{className:z(nt({size:t}),"w-full")}),O&&jsxRuntime.jsx("span",{ref:U,className:z("absolute inset-0 flex items-center justify-center","pointer-events-none bg-[var(--content-background)] tabular-nums",t==="sm"&&"px-2 text-sm",t==="default"&&"px-3 text-base",t==="lg"&&"px-4 text-lg"),style:{display:"none"},"aria-hidden":"true"})]}),N&&I&&jsxRuntime.jsxs("div",{className:"flex flex-col h-full",children:[jsxRuntime.jsx(G,{slot:"increment",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"top"})),"aria-label":i??"Increase value",children:jsxRuntime.jsx(lucideReact.Plus,{className:"h-3 w-3","aria-hidden":"true"})}),jsxRuntime.jsx(G,{slot:"decrement",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"bottom"})),"aria-label":l??"Decrease value",children:jsxRuntime.jsx(lucideReact.Minus,{className:"h-3 w-3","aria-hidden":"true"})})]}),N&&!I&&jsxRuntime.jsx(G,{slot:"increment",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"right"})),"aria-label":i??"Increase value",children:jsxRuntime.jsx(lucideReact.Plus,{className:"h-4 w-4","aria-hidden":"true"})})]}),e&&jsxRuntime.jsx(reactAriaComponents.Text,{slot:"description",className:z(rt({size:t})),children:e}),jsxRuntime.jsx(reactAriaComponents.FieldError,{className:z(at({size:t})),children:a})]})});fe.displayName="NumberField";var Ne=react.forwardRef(function({isOpen:e,onOpenChange:a,groupLabel:t,leftPanel:m,rightPanel:n,leftSize:i,rightSize:l,onSizesChange:o,presets:c,triggerRef:v,direction:f},T){let[h,R]=react.useState({left:i,right:l}),P=react.useRef(false);react.useEffect(()=>{e&&!P.current&&R({left:i,right:l}),P.current=e;},[e,i,l]);let D=react.useCallback(p=>{if(p===null)return;let d=Math.max(m.collapsible?0:m.minSize,Math.min(m.maxSize,p)),x=100-d,N=n.collapsible?0:n.minSize,y=n.maxSize;x<N||x>y||o(d,x);},[m,n,o]),E=react.useCallback(p=>{if(p===null)return;let d=Math.max(n.collapsible?0:n.minSize,Math.min(n.maxSize,p)),x=100-d,N=m.collapsible?0:m.minSize,y=m.maxSize;x<N||x>y||o(x,d);},[m,n,o]),b=react.useCallback(p=>{let d=p.sizes[0],x=p.sizes[1];d!==void 0&&x!==void 0&&o(d,x);},[o]),s=react.useCallback(()=>{o(h.left,h.right),a(false);},[o,a,h]),_=react.useCallback(()=>{a(false);},[a]);return e?jsxRuntime.jsxs(reactAriaComponents.DialogTrigger,{isOpen:e,onOpenChange:a,children:[jsxRuntime.jsx(reactAriaComponents.Button,{className:"sr-only",children:"Open resize controls"}),jsxRuntime.jsx(reactAriaComponents.Popover,{triggerRef:v,placement:f==="horizontal"?"bottom":"right",offset:8,className:z("w-72","rounded-lg border border-[var(--border)]","bg-[var(--content-background)] text-[var(--content-foreground)]","outline-none","motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95","data-[exiting]:motion-safe:animate-out data-[exiting]:motion-safe:fade-out-0 data-[exiting]:motion-safe:zoom-out-95"),children:jsxRuntime.jsxs(reactAriaComponents.Dialog,{className:"outline-none",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between border-b border-[var(--border)] px-4 py-3",children:[jsxRuntime.jsxs("h3",{className:"text-sm font-medium",children:["Resize: ",t]}),jsxRuntime.jsx(reactAriaComponents.Button,{onPress:_,className:z("inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"),"aria-label":"Close",children:jsxRuntime.jsx(lucideReact.X,{className:"h-4 w-4"})})]}),jsxRuntime.jsxs("div",{className:"space-y-4 px-4 py-4",children:[jsxRuntime.jsx("div",{children:jsxRuntime.jsx(fe,{label:`${m.name} (%)`,value:Math.round(i),onChange:D,minValue:m.collapsible?0:m.minSize,maxValue:m.maxSize,step:1,stepperLayout:"sides"})}),jsxRuntime.jsx("div",{children:jsxRuntime.jsx(fe,{label:`${n.name} (%)`,value:Math.round(l),onChange:E,minValue:n.collapsible?0:n.minSize,maxValue:n.maxSize,step:1,stepperLayout:"sides"})}),c&&c.length>0&&jsxRuntime.jsxs("div",{className:"border-t border-[var(--border)] pt-4",children:[jsxRuntime.jsx("div",{className:"mb-2 text-xs font-medium text-[var(--menu-muted)]",children:"Presets"}),jsxRuntime.jsx("div",{className:"flex flex-wrap gap-2",children:c.map((p,d)=>jsxRuntime.jsx(G,{variant:"outline",size:"sm",onPress:()=>b(p),children:p.label},d))})]})]}),jsxRuntime.jsx("div",{className:"flex justify-end border-t border-[var(--border)] px-4 py-3",children:jsxRuntime.jsx(G,{variant:"ghost",size:"sm",onPress:s,children:"Cancel"})})]})})]}):null});Ne.displayName="ResizablePopover";var dt=react.forwardRef(function({withHandle:e=true,presets:a,disabled:t=false,className:m},n){let{direction:i,groupLabel:l,sizes:o,setSizes:c,panels:v,announce:f,containerRef:T}=K(),h=react.useRef(null),R=n||h,[P,D]=react.useState(0);react.useEffect(()=>{let I=R.current,w=T.current;if(!I||!w)return;let F=w.querySelectorAll('[role="slider"]'),W=0;F.forEach((Z,j)=>{Z===I&&(W=j);}),D(W);},[T,R]);let E=P,b=P+1,s=v[E],_=v[b],A=o[E]??50,p=o[b]??50,[d,x]=react.useState(false),N=react.useCallback((I,w)=>{let F=[...o];F[E]=I,F[b]=w,c(F);},[o,c,E,b]),{isDragging:y,handlePointerDown:O,handleKeyDown:U}=Fe({direction:i,sizes:o,setSizes:c,panels:v,containerRef:T,leftPanelIndex:E,rightPanelIndex:b,disabled:t,announce:f,groupLabel:l,onOpenPopover:()=>x(true)}),C=s&&_?`Resize handle between ${s.name} and ${_.name} in ${l}`:`Resize handle in ${l}`,g=i==="horizontal"?lucideReact.GripVertical:lucideReact.GripHorizontal,L=s??{name:"Panel 1",minSize:$,maxSize:Y,collapsible:false},V=_??{name:"Panel 2",minSize:$,maxSize:Y,collapsible:false};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:R,role:"slider",tabIndex:t?-1:0,"aria-label":C,"aria-valuenow":Math.round(A),"aria-valuemin":s?.collapsible?0:s?.minSize??0,"aria-valuemax":s?.maxSize??100,"aria-orientation":i,"aria-disabled":t,"data-direction":i,"data-dragging":y,"data-disabled":t,onPointerDown:O,onKeyDown:U,className:z(xe({direction:i,disabled:t,isDragging:y}),m),children:e&&jsxRuntime.jsx("div",{className:z(ve({direction:i})),"aria-hidden":"true",children:jsxRuntime.jsx(g,{className:"h-4 w-4"})})}),jsxRuntime.jsx(Ne,{isOpen:d,onOpenChange:x,groupLabel:l,leftPanel:L,rightPanel:V,leftSize:A,rightSize:p,onSizesChange:N,presets:a,triggerRef:R,direction:i})]})});dt.displayName="ResizableHandle";exports.DEFAULT_MAX_SIZE=Y;exports.DEFAULT_MIN_SIZE=$;exports.LONG_PRESS_THRESHOLD=se;exports.ResizableHandle=dt;exports.ResizableHandlePropsSchema=Rt;exports.ResizablePanel=Ce;exports.ResizablePanelGroup=De;exports.ResizablePanelGroupPropsSchema=gt;exports.ResizablePanelPropsSchema=St;exports.ResizePresetSchema=Ve;exports.resizableGripVariants=ve;exports.resizableHandleVariants=xe;exports.useResizableContext=K;//# sourceMappingURL=index.js.map
2
+ 'use strict';var react=require('react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod'),classVarianceAuthority=require('class-variance-authority'),lucideReact=require('lucide-react'),reactAriaComponents=require('react-aria-components');function z(...o){return tailwindMerge.twMerge(clsx.clsx(o))}var ie=react.createContext(null);ie.displayName="ResizableContext";function K(){let o=react.useContext(ie);if(!o)throw new Error("useResizableContext must be used within a ResizablePanelGroup. Make sure ResizablePanel and ResizableHandle are children of ResizablePanelGroup.");return o}function Pe({direction:o,groupLabel:e,sizes:r,onSizesChange:t}){let[u,n]=react.useState([]),[a,l]=react.useState([]),i=react.useRef(null),d=react.useRef(null),v=react.useRef(null),f=react.useRef(false),T=r!==void 0,R=T?r:u,S=react.useCallback(b=>{T?t?.(b):n(b);},[T,t]),P=react.useCallback((b,s)=>{l(_=>{let A=[..._];return A[b]=s,A});},[]),D=react.useCallback(b=>{l(s=>{let _=[...s];return delete _[b],_.filter(Boolean)});},[]);react.useEffect(()=>{if(T||f.current)return;let s=a.filter(Boolean).length;if(s<2)return;if(R.length<s||R.some(A=>A===void 0)){let A=[],p=100/s;for(let m=0;m<s;m++)A[m]=p;f.current=true,n(A);}},[a,R,T]),react.useEffect(()=>()=>{v.current&&clearTimeout(v.current),d.current&&(document.body.removeChild(d.current),d.current=null);},[]);let h=react.useCallback(b=>{if(!d.current){let s=document.createElement("div");s.setAttribute("aria-live","polite"),s.setAttribute("aria-atomic","true"),s.className="sr-only",s.style.cssText="position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;",document.body.appendChild(s),d.current=s;}d.current.textContent=b,v.current&&clearTimeout(v.current),v.current=setTimeout(()=>{d.current&&(d.current.textContent="");},1e3);},[]);return {direction:o,groupLabel:e,sizes:R,setSizes:S,panels:a,registerPanel:P,unregisterPanel:D,announce:h,containerRef:i}}var De=react.forwardRef(function({direction:e,groupLabel:r,sizes:t,onSizesChange:u,className:n,children:a},l){let i=Pe({direction:e,groupLabel:r,sizes:t,onSizesChange:u});return react.useImperativeHandle(l,()=>i.containerRef.current,[i.containerRef]),jsxRuntime.jsx(ie.Provider,{value:i,children:jsxRuntime.jsx("div",{ref:i.containerRef,role:"group","aria-label":`${r}, ${e}`,"data-direction":e,className:z("flex h-full w-full",e==="horizontal"?"flex-row":"flex-col",n),children:a})})});De.displayName="ResizablePanelGroup";var $=10,Y=90,se=300,Oe=zod.z.object({label:zod.z.string().min(1),sizes:zod.z.array(zod.z.number().min(0).max(100))}),Et=zod.z.object({direction:zod.z.enum(["horizontal","vertical"]),groupLabel:zod.z.string().min(1),sizes:zod.z.array(zod.z.number().min(0).max(100)).optional(),onSizesChange:zod.z.function().optional(),className:zod.z.string().optional(),children:zod.z.custom()}),St=zod.z.object({name:zod.z.string().min(1),defaultSize:zod.z.number().min(0).max(100).optional(),minSize:zod.z.number().min(0).max(100).optional().default($),maxSize:zod.z.number().min(0).max(100).optional().default(Y),collapsible:zod.z.boolean().optional().default(false),onCollapse:zod.z.function().optional(),onExpand:zod.z.function().optional(),onResize:zod.z.function().optional(),className:zod.z.string().optional(),children:zod.z.custom()}),Rt=zod.z.object({withHandle:zod.z.boolean().optional().default(true),presets:zod.z.array(Oe).optional(),disabled:zod.z.boolean().optional().default(false),className:zod.z.string().optional()}),xe=classVarianceAuthority.cva(["relative flex items-center justify-center","shrink-0","bg-transparent","transition-colors duration-150","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2","touch-none select-none"],{variants:{direction:{horizontal:["w-3 min-w-[12px]","cursor-col-resize","hover:bg-[var(--accent)]/50","before:absolute before:inset-y-0 before:-inset-x-4","before:min-w-[44px]"],vertical:["h-3 min-h-[12px]","cursor-row-resize","hover:bg-[var(--accent)]/50","before:absolute before:inset-x-0 before:-inset-y-4","before:min-h-[44px]"]},disabled:{true:"cursor-not-allowed opacity-50 pointer-events-none",false:""},isDragging:{true:"bg-[var(--accent)]",false:""}},defaultVariants:{direction:"horizontal",disabled:false,isDragging:false}}),ve=classVarianceAuthority.cva(["flex items-center justify-center","rounded-full","bg-[var(--border)]","text-[var(--menu-muted)]"],{variants:{direction:{horizontal:"h-8 w-1",vertical:"h-1 w-8"}},defaultVariants:{direction:"horizontal"}});var Ve=react.forwardRef(function({name:e,defaultSize:r,minSize:t=$,maxSize:u=Y,collapsible:n=false,onCollapse:a,onExpand:l,onResize:i,className:d,children:v},f){let{sizes:T,registerPanel:R,unregisterPanel:S,containerRef:P}=K(),D=react.useRef(null),[h,b]=react.useState(-1),s=react.useRef(null),_=react.useRef(false),A=react.useRef(-1);react.useEffect(()=>{let m=D.current,x=P.current;if(!m||!x)return;let N=x.querySelectorAll("[data-resizable-panel]"),y=-1;for(let C=0;C<N.length;C++)if(N[C]===m){y=C;break}if(y!==-1)return h!==y&&b(y),_.current||(_.current=true,A.current=y,R(y,{name:e,minSize:t,maxSize:u,collapsible:n})),()=>{_.current&&(S(A.current),_.current=false);}},[P,R,S,e,t,u,n,h]);let p=h>=0?T[h]??50:50;return react.useEffect(()=>{if(s.current===null){s.current=p;return}let m=s.current===0,x=p===0;!m&&x&&a?a():m&&!x&&l&&l(),i&&s.current!==p&&i(p),s.current=p;},[p,a,l,i]),jsxRuntime.jsx("div",{ref:m=>{D.current=m,typeof f=="function"?f(m):f&&(f.current=m);},role:"region","aria-label":e,"data-resizable-panel":"","data-panel-name":e,"data-panel-index":h,"data-collapsed":p===0,style:{flexBasis:`${p}%`,flexGrow:0,flexShrink:0,overflow:"hidden"},className:z("relative",d),children:v})});Ve.displayName="ResizablePanel";function Me(o,e,r){return Math.max(e,Math.min(r,o))}function He(o,e,r,t,u){let n=[...o],a=e[r],l=e[t];if(!a||!l)return o;let i=o[r]??50,d=o[t]??50,v=i+u,f,T=a.collapsible?0:a.minSize,R=a.maxSize,S=l.collapsible?0:l.minSize,P=l.maxSize;return v=Me(v,T,R),f=i+d-v,f=Me(f,S,P),v=i+d-f,n[r]=v,n[t]=f,n}function Fe({direction:o,sizes:e,setSizes:r,panels:t,containerRef:u,leftPanelIndex:n,rightPanelIndex:a,disabled:l=false,announce:i,groupLabel:d,onOpenPopover:v}){let[f,T]=react.useState(false),R=react.useRef(null),S=react.useRef(null),P=react.useRef(0),D=react.useRef(false),h=react.useRef(t),b=react.useRef(e),s=react.useRef(r),_=react.useRef(()=>{}),A=react.useRef(()=>{});react.useEffect(()=>{h.current=t,b.current=e,s.current=r;},[t,e,r]);let p=react.useCallback(()=>{let g=u.current;return g?o==="horizontal"?g.offsetWidth:g.offsetHeight:0},[u,o]),m=react.useCallback(g=>{let L=p();return L===0?0:g/L*100},[p]),x=react.useCallback(g=>{_.current(g);},[]),N=react.useCallback(()=>{A.current();},[]),y=react.useCallback(g=>{if(!R.current||l)return;let O=(o==="horizontal"?g.clientX:g.clientY)-R.current.position,I=m(O),w=He(R.current.sizes,h.current,n,a,I);s.current(w);},[o,l,n,m,a]),C=react.useCallback(()=>{if(S.current&&(clearTimeout(S.current),S.current=null),Date.now()-P.current<se&&!D.current&&v&&!l&&v(),f){T(false);let O=h.current[n],I=Math.round(b.current[n]??50);i&&O&&d&&i(`${O.name} in ${d} resized to ${I} percent`);}R.current=null,D.current=false,document.removeEventListener("pointermove",x),document.removeEventListener("pointerup",N),document.removeEventListener("pointercancel",N),document.body.style.cursor="",document.body.style.userSelect="";},[i,l,d,f,n,v,x,N]);react.useEffect(()=>{_.current=y,A.current=C;});let U=react.useCallback(g=>{if(l)return;g.preventDefault();let L=o==="horizontal"?g.clientX:g.clientY;P.current=Date.now(),D.current=false,R.current={position:L,sizes:[...e],containerSize:p()},S.current=setTimeout(()=>{D.current=true,T(true),document.body.style.cursor=o==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none";},se),document.addEventListener("pointermove",x),document.addEventListener("pointerup",N),document.addEventListener("pointercancel",N),g.pointerType==="mouse"&&(S.current&&(clearTimeout(S.current),S.current=null),D.current=true,T(true),document.body.style.cursor=o==="horizontal"?"col-resize":"row-resize",document.body.style.userSelect="none");},[o,l,p,x,N,e]),V=react.useCallback(g=>{if(l)return;let L=g.shiftKey?10:1,O=0;switch(g.key){case "ArrowLeft":case "ArrowUp":O=-L;break;case "ArrowRight":case "ArrowDown":O=L;break;case "Home":{let I=t[n];I&&(O=(I.collapsible?0:I.minSize)-(e[n]??50));break}case "End":{let I=t[n];I&&(O=I.maxSize-(e[n]??50));break}case "Enter":case " ":g.preventDefault(),v?.();return;default:return}if(O!==0){g.preventDefault();let I=He(e,t,n,a,O);r(I);let w=t[n],F=Math.round(I[n]??50);i&&w&&d&&i(`${w.name} in ${d} resized to ${F} percent`);}},[i,l,d,n,v,t,a,r,e]);return react.useEffect(()=>{let g=x,L=N;return ()=>{S.current&&clearTimeout(S.current),document.removeEventListener("pointermove",g),document.removeEventListener("pointerup",L),document.removeEventListener("pointercancel",L);}},[x,N]),{isDragging:f,handlePointerDown:U,handleKeyDown:V}}function Nt(o){if(!(o instanceof Element))return false;let e=o;for(let u=0;e&&u<100;u++){let n=e.tagName?.toLowerCase()??"";if(n.startsWith("grammarly-")||n.startsWith("lt-")||e.hasAttribute("data-grammarly-shadow-root"))return true;if(e.parentElement)e=e.parentElement;else {let a=e.getRootNode();e=a instanceof ShadowRoot?a.host:null;}}let r=o;for(;r&&!r.tagName.includes("-");)r=r.parentElement;if(!r)return false;let t=r.parentElement;return t===document.body||t===document.documentElement}function Ge(o){return e=>!Nt(e)&&(o?.(e)??true)}var Ee=classVarianceAuthority.cva("inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",{variants:{fullWidth:{true:"w-full",false:""},inVerticalGroup:{true:"items-stretch",false:"items-center"}},defaultVariants:{fullWidth:false,inVerticalGroup:false}}),Se=classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",{variants:{variant:{default:"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1",destructive:"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake",outline:"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)]",secondary:"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]",ghost:"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]",link:"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]"},fullWidth:{true:"w-full",false:""},visualSize:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3 text-xs",lg:"h-11 rounded-md px-6 text-base",icon:"h-10 w-10",dot:"h-5 w-5 rounded-full p-0 min-h-0 min-w-0"},paywall:{true:"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",false:""}},defaultVariants:{variant:"default",visualSize:"default",paywall:false}});var Re="data-[pressed]:scale-[0.97]";var ue="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",ce="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";var Ye=react.createContext(null);Ye.displayName="ButtonGroupContext";function Ze(){return react.useContext(Ye)}var je=react.createContext(null);je.displayName="ButtonGroupItemContext";function Xe(){return react.useContext(je)}classVarianceAuthority.cva("inline-flex items-center gap-0",{variants:{orientation:{horizontal:"flex-row",vertical:"flex-col w-full"}},defaultVariants:{orientation:"horizontal"}});var We=classVarianceAuthority.cva("",{variants:{orientation:{horizontal:"min-w-[44px]",vertical:"flex min-h-[44px]"},position:{first:"",middle:"",last:"",only:""}},compoundVariants:[{orientation:"horizontal",position:"first",className:"rounded-r-none border-r-0"},{orientation:"horizontal",position:"middle",className:"rounded-none border-r-0"},{orientation:"horizontal",position:"last",className:"rounded-l-none"},{orientation:"vertical",position:"first",className:"rounded-b-none border-b-0"},{orientation:"vertical",position:"middle",className:"rounded-none border-b-0"},{orientation:"vertical",position:"last",className:"rounded-t-none"}],defaultVariants:{orientation:"horizontal",position:"only"}});classVarianceAuthority.cva("bg-[var(--border)]",{variants:{orientation:{horizontal:"w-px h-6 mx-1",vertical:"h-px w-full my-1"}},defaultVariants:{orientation:"horizontal"}});var G=react.memo(react.forwardRef(({className:o,buttonVisualClassName:e,variant:r,size:t,visualSize:u,fullWidth:n,loading:a=false,loadingText:l="Loading...",shortcut:i,children:d,isDisabled:v,paywall:f=false,paywallRedirect:T,paywallDescription:R,onPress:S,...P},D)=>{let h=react.useId(),b=Ze(),s=Xe(),_=r??b?.variant??"default",A=t??b?.size,p=v??b?.isDisabled??false,m=b?.orientation==="vertical",x=n||m,N=s?We({orientation:b?.orientation??"horizontal",position:s.position}):"",y=u??A??"default";return process.env.NODE_ENV!=="production"&&(y==="dot"||y==="icon")&&!P["aria-label"]&&!d&&console.warn('[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'),jsxRuntime.jsx(reactAriaComponents.Button,{ref:D,isDisabled:p||a||void 0,"aria-disabled":f?true:void 0,"aria-describedby":f?h:void 0,onPress:V=>{if(f){T&&window.open(T,"_blank","noopener,noreferrer");return}S?.(V);},className:z(Ee({fullWidth:x,inVerticalGroup:m}),o),...P,children:V=>jsxRuntime.jsxs("span",{className:z(Se({variant:_,visualSize:y,paywall:f,fullWidth:x}),N,e,Re,"",ue,ce),"data-pressed":V.isPressed||void 0,children:[a&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(lucideReact.Loader2,{className:"motion-safe:animate-spin","aria-hidden":"true"}),jsxRuntime.jsx("span",{className:"sr-only","aria-live":"polite",children:l})]}),!a&&d,f&&jsxRuntime.jsx(lucideReact.Zap,{"data-testid":"zap-icon","aria-hidden":"true",className:"ml-1"}),f&&jsxRuntime.jsxs("span",{id:h,className:"sr-only",children:["Premium feature: ",R||"Upgrade required to access this feature"]}),V.isFocusVisible&&i&&jsxRuntime.jsx("kbd",{className:"ml-auto hidden text-xs opacity-60 lg:inline",children:i})]})})}));G.displayName="Button";var J={sm:"text-xs",default:"text-sm",lg:"text-base"};var de={sm:"h-9",default:"h-10",lg:"h-11"},ee={sm:`${de.sm} px-2 text-xs`,default:`${de.default} px-3 text-sm`,lg:`${de.lg} px-4 text-base`},_e="min-h-[44px] flex items-center";function qe(o,e){return !(o===false||e)}var Ke="(prefers-reduced-motion: reduce)";function Ht(){return typeof window>"u"?false:window.matchMedia(Ke).matches}function Qe(){let[o,e]=react.useState(Ht);return react.useEffect(()=>{let r=window.matchMedia(Ke);e(r.matches);let t=u=>{e(u.matches);};return r.addEventListener("change",t),()=>r.removeEventListener("change",t)},[]),o}var Je=4294967295,et=0,tt=-2147483647;zod.z.object({value:zod.z.number().nullable().optional(),defaultValue:zod.z.number().optional(),minValue:zod.z.number().optional(),maxValue:zod.z.number().optional(),allowNegative:zod.z.boolean().optional(),step:zod.z.number().positive().optional(),formatOptions:zod.z.custom().optional(),isDisabled:zod.z.boolean().optional(),isReadOnly:zod.z.boolean().optional(),isRequired:zod.z.boolean().optional(),isInvalid:zod.z.boolean().optional(),isWheelDisabled:zod.z.boolean().optional(),validate:zod.z.function().optional(),validationBehavior:zod.z.enum(["native","aria"]).default("native"),label:zod.z.string(),description:zod.z.string().optional(),errorMessage:zod.z.union([zod.z.string(),zod.z.function()]).optional(),stepperLayout:zod.z.enum(["sides","stacked","hidden"]).default("sides"),incrementAriaLabel:zod.z.string().optional(),decrementAriaLabel:zod.z.string().optional(),name:zod.z.string().optional(),size:zod.z.enum(["sm","default","lg"]).default("default"),onChange:zod.z.function().optional(),onFocus:zod.z.function().optional(),onBlur:zod.z.function().optional(),onFocusChange:zod.z.function().optional(),animated:zod.z.boolean().optional().default(true),springConfig:zod.z.object({stiffness:zod.z.number(),damping:zod.z.number()}).optional(),className:zod.z.string().optional(),autoFocus:zod.z.boolean().optional()});var nt=classVarianceAuthority.cva(["inline-flex items-center rounded-md border","bg-[var(--content-background)] text-[var(--content-foreground)]","transition-colors duration-200","focus-within:ring-2 focus-within:ring-[var(--ring)] focus-within:ring-offset-2","data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50"],{variants:{size:{sm:`${ee.sm}`,default:`${ee.default}`,lg:`${ee.lg}`},isInvalid:{true:"border-[var(--destructive-background)] focus-within:ring-[var(--destructive-background)]",false:"border-[var(--input-border)] hover:border-[var(--input-border)]/80"}},defaultVariants:{size:"default",isInvalid:false}}),ot=classVarianceAuthority.cva(["flex-1 bg-transparent text-center tabular-nums","min-w-0","focus:outline-none","[appearance:textfield]","[&::-webkit-outer-spin-button]:appearance-none","[&::-webkit-inner-spin-button]:appearance-none"],{variants:{size:{sm:`px-2 ${J.sm}`,default:`px-3 ${J.default}`,lg:`px-4 ${J.lg}`}},defaultVariants:{size:"default"}}),te=classVarianceAuthority.cva(["flex items-center justify-center","transition-colors duration-150","select-none","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)]","focus-visible:ring-inset","active:bg-[var(--accent)]/80","disabled:pointer-events-none disabled:opacity-50"],{variants:{size:{sm:"min-w-8 min-h-8 text-sm",default:"min-w-10 min-h-10 text-base",lg:"min-w-12 min-h-12 text-lg"},position:{left:"rounded-l-md border-r border-[var(--input-border)]",right:"rounded-r-md border-l border-[var(--input-border)]",top:"rounded-tr-md border-b border-l border-[var(--input-border)] h-1/2",bottom:"rounded-br-md border-l border-[var(--input-border)] h-1/2"}},defaultVariants:{size:"default"}}),rt=classVarianceAuthority.cva(["block font-medium text-[var(--content-foreground)]","mb-1.5",'data-[required]:after:content-["*"] data-[required]:after:ml-0.5',"data-[required]:after:text-[var(--destructive-background)]"],{variants:{size:{sm:"text-sm",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}}),at=classVarianceAuthority.cva(["text-[var(--menu-muted)]","mt-1"],{variants:{size:{sm:"text-xs",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}}),it=classVarianceAuthority.cva(["flex items-center gap-1","text-[var(--destructive-background)]","font-medium","mt-1"],{variants:{size:{sm:"text-xs",default:"text-sm",lg:"text-base"}},defaultVariants:{size:"default"}});var ne;function Zt(){return ne!==void 0?Promise.resolve(ne):import('motion').then(o=>(ne=o.animate,ne)).catch(()=>(ne=null,null))}function jt(o,e){if(e)try{let r={...e};return r.style==="currency"&&!r.currencyDisplay&&(r.currencyDisplay="narrowSymbol"),new Intl.NumberFormat(void 0,r).format(o)}catch{return String(Math.round(o))}return String(Math.round(o))}var fe=react.forwardRef(({label:o,description:e,errorMessage:r,size:t="default",stepperLayout:u="sides",allowNegative:n=false,incrementAriaLabel:a,decrementAriaLabel:l,animated:i,springConfig:d,onChange:v,value:f,defaultValue:T,formatOptions:R,minValue:S,maxValue:P,className:D,isInvalid:h,isRequired:b,isDisabled:s,isReadOnly:_,...A},p)=>{let m=S??(n?tt:et),x=P??Je,N=u!=="hidden"&&!_,y=Qe(),C=qe(i,y)&&N,U=react.useRef(null),V=react.useRef(f??T??0),g=react.useRef(void 0),L=react.useRef(null);react.useEffect(()=>{C&&Zt().then(w=>{g.current=w??null;});},[C]),react.useEffect(()=>()=>{L.current?.stop();},[]);let O=w=>{let F=V.current;if(C&&g.current&&U.current&&F!==w){L.current?.stop();let q=w,Z=U.current,j=Z.parentElement?.querySelector("input");Z.style.display="",j&&(j.style.color="transparent"),L.current=g.current(F,q,{type:"spring",stiffness:d?.stiffness??500,damping:d?.damping??30,onUpdate:Ie=>{V.current=Ie,Z.textContent=jt(Ie,R);},onComplete:()=>{Z.style.display="none",j&&(j.style.color=""),L.current=null,V.current=q;}});}else V.current=w;v?.(w);},I=u==="stacked";return jsxRuntime.jsxs(reactAriaComponents.NumberField,{ref:p,className:z("group flex flex-col",D),minValue:m,maxValue:x,isInvalid:h,isRequired:b,isDisabled:s,isReadOnly:_,value:f,defaultValue:T,formatOptions:R,onChange:O,...A,children:[jsxRuntime.jsx(reactAriaComponents.Label,{className:z(rt({size:t})),"data-required":b||void 0,children:o}),jsxRuntime.jsxs(reactAriaComponents.Group,{className:z(_e,nt({size:t,isInvalid:h??false}),I&&"pr-0"),children:[N&&!I&&jsxRuntime.jsx(G,{slot:"decrement",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"left"})),"aria-label":l??"Decrease value",children:jsxRuntime.jsx(lucideReact.Minus,{className:"h-4 w-4","aria-hidden":"true"})}),jsxRuntime.jsxs("div",{className:"relative flex flex-1",children:[jsxRuntime.jsx(reactAriaComponents.Input,{className:z(ot({size:t}),"w-full")}),C&&jsxRuntime.jsx("span",{ref:U,className:z("absolute inset-0 flex items-center justify-center","pointer-events-none bg-[var(--content-background)] tabular-nums",t==="sm"&&"px-2 text-sm",t==="default"&&"px-3 text-base",t==="lg"&&"px-4 text-lg"),style:{display:"none"},"aria-hidden":"true"})]}),N&&I&&jsxRuntime.jsxs("div",{className:"flex flex-col h-full",children:[jsxRuntime.jsx(G,{slot:"increment",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"top"})),"aria-label":a??"Increase value",children:jsxRuntime.jsx(lucideReact.Plus,{className:"h-3 w-3","aria-hidden":"true"})}),jsxRuntime.jsx(G,{slot:"decrement",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"bottom"})),"aria-label":l??"Decrease value",children:jsxRuntime.jsx(lucideReact.Minus,{className:"h-3 w-3","aria-hidden":"true"})})]}),N&&!I&&jsxRuntime.jsx(G,{slot:"increment",variant:"ghost",className:"!min-h-0 !min-w-0",buttonVisualClassName:z(te({size:t,position:"right"})),"aria-label":a??"Increase value",children:jsxRuntime.jsx(lucideReact.Plus,{className:"h-4 w-4","aria-hidden":"true"})})]}),e&&jsxRuntime.jsx(reactAriaComponents.Text,{slot:"description",className:z(at({size:t})),children:e}),jsxRuntime.jsx(reactAriaComponents.FieldError,{className:z(it({size:t})),children:r})]})});fe.displayName="NumberField";var Ne=react.forwardRef(function({isOpen:e,onOpenChange:r,groupLabel:t,leftPanel:u,rightPanel:n,leftSize:a,rightSize:l,onSizesChange:i,presets:d,triggerRef:v,direction:f},T){let[R,S]=react.useState({left:a,right:l}),P=react.useRef(false);react.useEffect(()=>{e&&!P.current&&S({left:a,right:l}),P.current=e;},[e,a,l]);let D=react.useCallback(p=>{if(p===null)return;let m=Math.max(u.collapsible?0:u.minSize,Math.min(u.maxSize,p)),x=100-m,N=n.collapsible?0:n.minSize,y=n.maxSize;x<N||x>y||i(m,x);},[u,n,i]),h=react.useCallback(p=>{if(p===null)return;let m=Math.max(n.collapsible?0:n.minSize,Math.min(n.maxSize,p)),x=100-m,N=u.collapsible?0:u.minSize,y=u.maxSize;x<N||x>y||i(x,m);},[u,n,i]),b=react.useCallback(p=>{let m=p.sizes[0],x=p.sizes[1];m!==void 0&&x!==void 0&&i(m,x);},[i]),s=react.useCallback(()=>{i(R.left,R.right),r(false);},[i,r,R]),_=react.useCallback(()=>{r(false);},[r]);if(!e)return null;let A=f==="horizontal"?"bottom":"right";return jsxRuntime.jsxs(reactAriaComponents.DialogTrigger,{isOpen:e,onOpenChange:r,children:[jsxRuntime.jsx(reactAriaComponents.Button,{className:"sr-only",children:"Open resize controls"}),jsxRuntime.jsx(reactAriaComponents.Popover,{triggerRef:v,shouldCloseOnInteractOutside:Ge(),placement:A,offset:8,className:z("w-72","rounded-lg border border-[var(--border)]","bg-[var(--content-background)] text-[var(--content-foreground)]","outline-none","motion-safe:animate-in motion-safe:fade-in-0 motion-safe:zoom-in-95","data-[exiting]:motion-safe:animate-out data-[exiting]:motion-safe:fade-out-0 data-[exiting]:motion-safe:zoom-out-95"),children:jsxRuntime.jsxs(reactAriaComponents.Dialog,{className:"outline-none",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between border-b border-[var(--border)] px-4 py-3",children:[jsxRuntime.jsxs("h3",{className:"text-sm font-medium",children:["Resize: ",t]}),jsxRuntime.jsx(reactAriaComponents.Button,{onPress:_,className:z("inline-flex items-center justify-center rounded-md","min-h-[44px] min-w-[44px]","text-[var(--menu-muted)]","hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"),"aria-label":"Close",children:jsxRuntime.jsx(lucideReact.X,{className:"h-4 w-4"})})]}),jsxRuntime.jsxs("div",{className:"space-y-4 px-4 py-4",children:[jsxRuntime.jsx("div",{children:jsxRuntime.jsx(fe,{label:`${u.name} (%)`,value:Math.round(a),onChange:D,minValue:u.collapsible?0:u.minSize,maxValue:u.maxSize,step:1,stepperLayout:"sides"})}),jsxRuntime.jsx("div",{children:jsxRuntime.jsx(fe,{label:`${n.name} (%)`,value:Math.round(l),onChange:h,minValue:n.collapsible?0:n.minSize,maxValue:n.maxSize,step:1,stepperLayout:"sides"})}),d&&d.length>0&&jsxRuntime.jsxs("div",{className:"border-t border-[var(--border)] pt-4",children:[jsxRuntime.jsx("div",{className:"mb-2 text-xs font-medium text-[var(--menu-muted)]",children:"Presets"}),jsxRuntime.jsx("div",{className:"flex flex-wrap gap-2",children:d.map((p,m)=>jsxRuntime.jsx(G,{variant:"outline",size:"sm",onPress:()=>b(p),children:p.label},m))})]})]}),jsxRuntime.jsx("div",{className:"flex justify-end border-t border-[var(--border)] px-4 py-3",children:jsxRuntime.jsx(G,{variant:"ghost",size:"sm",onPress:s,children:"Cancel"})})]})})]})});Ne.displayName="ResizablePopover";var mt=react.forwardRef(function({withHandle:e=true,presets:r,disabled:t=false,className:u},n){let{direction:a,groupLabel:l,sizes:i,setSizes:d,panels:v,announce:f,containerRef:T}=K(),R=react.useRef(null),S=n||R,[P,D]=react.useState(0);react.useEffect(()=>{let I=S.current,w=T.current;if(!I||!w)return;let F=w.querySelectorAll('[role="slider"]'),q=0;F.forEach((Z,j)=>{Z===I&&(q=j);}),D(q);},[T,S]);let h=P,b=P+1,s=v[h],_=v[b],A=i[h]??50,p=i[b]??50,[m,x]=react.useState(false),N=react.useCallback((I,w)=>{let F=[...i];F[h]=I,F[b]=w,d(F);},[i,d,h,b]),{isDragging:y,handlePointerDown:C,handleKeyDown:U}=Fe({direction:a,sizes:i,setSizes:d,panels:v,containerRef:T,leftPanelIndex:h,rightPanelIndex:b,disabled:t,announce:f,groupLabel:l,onOpenPopover:()=>x(true)}),V=s&&_?`Resize handle between ${s.name} and ${_.name} in ${l}`:`Resize handle in ${l}`,g=a==="horizontal"?lucideReact.GripVertical:lucideReact.GripHorizontal,L=s??{name:"Panel 1",minSize:$,maxSize:Y,collapsible:false},O=_??{name:"Panel 2",minSize:$,maxSize:Y,collapsible:false};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:S,role:"slider",tabIndex:t?-1:0,"aria-label":V,"aria-valuenow":Math.round(A),"aria-valuemin":s?.collapsible?0:s?.minSize??0,"aria-valuemax":s?.maxSize??100,"aria-orientation":a,"aria-disabled":t,"data-direction":a,"data-dragging":y,"data-disabled":t,onPointerDown:C,onKeyDown:U,className:z(xe({direction:a,disabled:t,isDragging:y}),u),children:e&&jsxRuntime.jsx("div",{className:z(ve({direction:a})),"aria-hidden":"true",children:jsxRuntime.jsx(g,{className:"h-4 w-4"})})}),jsxRuntime.jsx(Ne,{isOpen:m,onOpenChange:x,groupLabel:l,leftPanel:L,rightPanel:O,leftSize:A,rightSize:p,onSizesChange:N,presets:r,triggerRef:S,direction:a})]})});mt.displayName="ResizableHandle";exports.DEFAULT_MAX_SIZE=Y;exports.DEFAULT_MIN_SIZE=$;exports.LONG_PRESS_THRESHOLD=se;exports.ResizableHandle=mt;exports.ResizableHandlePropsSchema=Rt;exports.ResizablePanel=Ve;exports.ResizablePanelGroup=De;exports.ResizablePanelGroupPropsSchema=Et;exports.ResizablePanelPropsSchema=St;exports.ResizePresetSchema=Oe;exports.resizableGripVariants=ve;exports.resizableHandleVariants=xe;exports.useResizableContext=K;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map