@ahrowe/ui 0.32.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/dist/esm/common/actionIcon/actionIcon.module.mjs.map +1 -1
  2. package/dist/esm/common/breadcrumb/breadcrumb.mjs +1 -1
  3. package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -1
  4. package/dist/esm/common/breadcrumb/breadcrumb.module.mjs +1 -1
  5. package/dist/esm/common/breadcrumb/breadcrumb.module.mjs.map +1 -1
  6. package/dist/esm/common/card/Card.mjs +1 -1
  7. package/dist/esm/common/card/Card.mjs.map +1 -1
  8. package/dist/esm/common/card/card.types.mjs.map +1 -1
  9. package/dist/esm/common/chip/chip.mjs +1 -1
  10. package/dist/esm/common/chip/chip.mjs.map +1 -1
  11. package/dist/esm/common/chip/chip.types.mjs.map +1 -1
  12. package/dist/esm/common/colorPicker/colorPicker.mjs +1 -1
  13. package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
  14. package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
  15. package/dist/esm/common/configProvider/configProvider.mjs.map +1 -1
  16. package/dist/esm/common/configProvider/presentation.types.mjs +2 -0
  17. package/dist/esm/common/configProvider/presentation.types.mjs.map +1 -0
  18. package/dist/esm/common/configProvider/usePresentationDefault.mjs.map +1 -1
  19. package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
  20. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  21. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
  22. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs.map +1 -1
  23. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.module.mjs.map +1 -1
  24. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  25. package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
  26. package/dist/esm/common/drawer/drawer.mjs +1 -1
  27. package/dist/esm/common/drawer/drawer.mjs.map +1 -1
  28. package/dist/esm/common/dropdown/dropdown.mjs +1 -1
  29. package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
  30. package/dist/esm/common/dropdown/dropdown.module.mjs +1 -1
  31. package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
  32. package/dist/esm/common/emptyState/emptyState.mjs +1 -1
  33. package/dist/esm/common/emptyState/emptyState.mjs.map +1 -1
  34. package/dist/esm/common/fab/components/fabBase/fabBase.mjs +1 -1
  35. package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
  36. package/dist/esm/common/fab/fab.mjs +1 -1
  37. package/dist/esm/common/fab/fab.mjs.map +1 -1
  38. package/dist/esm/common/hooks/useAnchorTracking.mjs.map +1 -1
  39. package/dist/esm/common/hooks/useFocusBoundary.mjs +1 -1
  40. package/dist/esm/common/hooks/useFocusBoundary.mjs.map +1 -1
  41. package/dist/esm/common/hooks/useSheet.mjs +1 -1
  42. package/dist/esm/common/hooks/useSheet.mjs.map +1 -1
  43. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs +1 -1
  44. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs.map +1 -1
  45. package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
  46. package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
  47. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs +1 -1
  48. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs.map +1 -1
  49. package/dist/esm/common/interactableDiv/interactableDiv.mjs +1 -1
  50. package/dist/esm/common/interactableDiv/interactableDiv.mjs.map +1 -1
  51. package/dist/esm/common/klipyPicker/klipyPicker.mjs +1 -1
  52. package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
  53. package/dist/esm/common/menu/menu.mjs +2 -0
  54. package/dist/esm/common/menu/menu.mjs.map +1 -0
  55. package/dist/esm/common/menu/menu.module.mjs +2 -0
  56. package/dist/esm/common/menu/menu.module.mjs.map +1 -0
  57. package/dist/esm/common/menu/menu.types.mjs +2 -0
  58. package/dist/esm/common/menu/menu.types.mjs.map +1 -0
  59. package/dist/esm/common/multiSelect/multiSelect.mjs +1 -1
  60. package/dist/esm/common/multiSelect/multiSelect.mjs.map +1 -1
  61. package/dist/esm/common/multiSelect/multiSelect.module.mjs +1 -1
  62. package/dist/esm/common/multiSelect/multiSelect.module.mjs.map +1 -1
  63. package/dist/esm/common/numberInput/numberInput.mjs +1 -1
  64. package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
  65. package/dist/esm/common/popover/popover.mjs +1 -1
  66. package/dist/esm/common/popover/popover.mjs.map +1 -1
  67. package/dist/esm/common/popover/popover.module.mjs +1 -1
  68. package/dist/esm/common/popover/popover.module.mjs.map +1 -1
  69. package/dist/esm/common/popover/popover.types.mjs.map +1 -1
  70. package/dist/esm/common/popover/usePopoverPosition.mjs +1 -1
  71. package/dist/esm/common/popover/usePopoverPosition.mjs.map +1 -1
  72. package/dist/esm/common/progressBar/progressBar.mjs +1 -1
  73. package/dist/esm/common/progressBar/progressBar.mjs.map +1 -1
  74. package/dist/esm/common/searchInput/searchInput.mjs +1 -1
  75. package/dist/esm/common/searchInput/searchInput.mjs.map +1 -1
  76. package/dist/esm/common/splitButton/splitButton.mjs +1 -1
  77. package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
  78. package/dist/esm/common/splitButton/splitButton.module.mjs +1 -1
  79. package/dist/esm/common/splitButton/splitButton.module.mjs.map +1 -1
  80. package/dist/esm/common/timeInput/timeInput.mjs +1 -1
  81. package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
  82. package/dist/esm/common/toast/toast.module.mjs.map +1 -1
  83. package/dist/esm/common/tooltip/tooltip.mjs +1 -1
  84. package/dist/esm/common/tooltip/tooltip.mjs.map +1 -1
  85. package/dist/esm/common/tooltip/tooltip.module.mjs +1 -1
  86. package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
  87. package/dist/esm/common/virtualList/virtualList.module.mjs +1 -1
  88. package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
  89. package/dist/esm/common/virtualList/virtualListHeader.mjs +1 -1
  90. package/dist/esm/common/virtualList/virtualListHeader.mjs.map +1 -1
  91. package/dist/esm/index.mjs +1 -1
  92. package/dist/index.cjs +3 -3
  93. package/dist/index.cjs.map +1 -1
  94. package/dist/style.css +1 -1
  95. package/dist/types/common/card/card.types.d.ts +6 -1
  96. package/dist/types/common/chip/chip.types.d.ts +6 -1
  97. package/dist/types/common/colorPicker/colorPicker.d.ts +1 -1
  98. package/dist/types/common/colorPicker/colorPicker.types.d.ts +6 -1
  99. package/dist/types/common/configProvider/configProvider.d.ts +1 -1
  100. package/dist/types/common/configProvider/configProvider.types.d.ts +6 -3
  101. package/dist/types/common/configProvider/index.d.ts +1 -0
  102. package/dist/types/common/configProvider/presentation.types.d.ts +14 -0
  103. package/dist/types/common/configProvider/usePresentationDefault.d.ts +1 -1
  104. package/dist/types/common/confirmModal/confirmModal.types.d.ts +4 -2
  105. package/dist/types/common/datePicker/components/datePickerMonth/datePickerMonth.d.ts +1 -1
  106. package/dist/types/common/datePicker/components/datePickerMonth/datePickerMonth.types.d.ts +3 -0
  107. package/dist/types/common/datePicker/datePicker.types.d.ts +11 -2
  108. package/dist/types/common/drawer/drawer.d.ts +1 -1
  109. package/dist/types/common/drawer/drawer.types.d.ts +7 -1
  110. package/dist/types/common/dropdown/dropdown.types.d.ts +7 -7
  111. package/dist/types/common/emptyState/emptyState.d.ts +1 -1
  112. package/dist/types/common/emptyState/emptyState.types.d.ts +6 -1
  113. package/dist/types/common/fab/components/fabBase/fabBase.d.ts +1 -1
  114. package/dist/types/common/fab/components/fabBase/fabBase.types.d.ts +3 -1
  115. package/dist/types/common/fab/fab.d.ts +1 -1
  116. package/dist/types/common/fab/fab.types.d.ts +6 -1
  117. package/dist/types/common/hooks/useAnchorTracking.d.ts +1 -1
  118. package/dist/types/common/hooks/useFocusBoundary.d.ts +3 -3
  119. package/dist/types/common/hooks/useSheet.d.ts +1 -1
  120. package/dist/types/common/infiniteBlock/infiniteBlock.d.ts +1 -1
  121. package/dist/types/common/infiniteBlock/infiniteBlock.types.d.ts +2 -0
  122. package/dist/types/common/menu/index.d.ts +2 -0
  123. package/dist/types/common/menu/menu.d.ts +14 -0
  124. package/dist/types/common/menu/menu.types.d.ts +55 -0
  125. package/dist/types/common/modal/modal.types.d.ts +1 -1
  126. package/dist/types/common/multiSelect/multiSelect.types.d.ts +1 -1
  127. package/dist/types/common/numberInput/numberInput.types.d.ts +6 -0
  128. package/dist/types/common/popover/popover.types.d.ts +34 -3
  129. package/dist/types/common/popover/usePopoverPosition.d.ts +20 -1
  130. package/dist/types/common/progressBar/progressBar.d.ts +1 -1
  131. package/dist/types/common/progressBar/progressBar.types.d.ts +6 -1
  132. package/dist/types/common/searchInput/searchInput.d.ts +1 -1
  133. package/dist/types/common/searchInput/searchInput.types.d.ts +13 -1
  134. package/dist/types/common/splitButton/splitButton.types.d.ts +3 -3
  135. package/dist/types/index.d.ts +2 -2
  136. package/docs/Breadcrumb.md +2 -2
  137. package/docs/ButtonGroup.md +1 -1
  138. package/docs/CLAUDE.md +1 -1
  139. package/docs/Card.md +3 -1
  140. package/docs/Chip.md +2 -0
  141. package/docs/ColorPicker.md +4 -0
  142. package/docs/ConfigProvider.md +2 -2
  143. package/docs/DatePicker.md +4 -0
  144. package/docs/Drawer.md +2 -0
  145. package/docs/Dropdown.md +3 -1
  146. package/docs/EmptyState.md +2 -0
  147. package/docs/Fab.md +2 -0
  148. package/docs/InputDropdown.md +1 -1
  149. package/docs/InteractableDiv.md +2 -0
  150. package/docs/Menu.md +107 -0
  151. package/docs/Modal.md +1 -1
  152. package/docs/NumberInput.md +4 -0
  153. package/docs/Popover.md +11 -5
  154. package/docs/ProgressBar.md +2 -0
  155. package/docs/SearchInput.md +4 -0
  156. package/docs/SplitButton.md +8 -4
  157. package/docs/ThemeProvider.md +1 -1
  158. package/docs/VirtualList.md +2 -2
  159. package/package.json +1 -1
  160. package/dist/esm/common/floatingMenu/floatingMenu.mjs +0 -2
  161. package/dist/esm/common/floatingMenu/floatingMenu.mjs.map +0 -1
  162. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs +0 -2
  163. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs.map +0 -1
  164. package/dist/esm/common/floatingMenu/floatingMenu.types.mjs +0 -2
  165. package/dist/esm/common/floatingMenu/floatingMenu.types.mjs.map +0 -1
  166. package/dist/esm/common/floatingMenu/useFloatingPosition.mjs +0 -2
  167. package/dist/esm/common/floatingMenu/useFloatingPosition.mjs.map +0 -1
  168. package/dist/types/common/floatingMenu/floatingMenu.d.ts +0 -3
  169. package/dist/types/common/floatingMenu/floatingMenu.types.d.ts +0 -32
  170. package/dist/types/common/floatingMenu/index.d.ts +0 -2
  171. package/dist/types/common/floatingMenu/useFloatingPosition.d.ts +0 -27
  172. package/docs/FloatingMenu.md +0 -90
@@ -1,2 +1,2 @@
1
- import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n}from"../button/button.types.mjs";import r from"../button/button.mjs";import i from"../hooks/useCoarsePointer.mjs";import ee from"../buttonGroup/buttonGroup.mjs";import te from"../input/input.mjs";import a from"./numberInput.module.mjs";import ne from"./useStepRepeat.mjs";import o from"react";import s from"classnames";import{FontAwesomeIcon as c}from"@fortawesome/react-fontawesome";import{faChevronDown as l,faChevronUp as re,faMinus as u,faPlus as ie}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";import{NumericFormat as ae}from"react-number-format";var oe={increase:`Increase`,decrease:`Decrease`};function p({label:e,disabled:t,direction:n,onStart:r,onStop:i}){return{tabIndex:-1,disabled:t,"aria-label":e,onPointerDown:e=>{(e.button===0||e.pointerType!==`mouse`)&&(e.preventDefault(),r(n,e.shiftKey?10:1))},onPointerUp:i,onPointerCancel:i,onContextMenu:e=>e.preventDefault()}}function m(e){return d(`button`,{type:`button`,...p(e),className:a.arrowBtn,children:d(c,{icon:e.icon,"aria-hidden":`true`})})}function h(e){let{disabled:t,...i}=p(e);return d(r,{...i,className:a.splitBtn,size:n.Icon,disabled:t,icon:e.icon})}function g(n){let r=o.useRef(void 0),{value:c,onChange:p,formValidator:g,label:se,error:_,className:v,style:y,allowNegative:b=!1,decimalSeparator:x,thousandSeparator:ce,prefix:le,suffix:S,decimalScale:C,fixedDecimalScale:w=!0,placeholder:ue,sign:T,showArrows:de=!1,step:E=1,min:D,max:O,arrowsLayout:k=`auto`,labels:fe,readOnly:A=!1,disabled:j=!1,isRequired:pe=!1,onKeyDown:M,...N}=e(`NumberInput`,n),P=t(`NumberInput`,fe,oe),[,F]=o.useState(0);o.useEffect(()=>{if(r.current=g,!g)return;let e=()=>F(e=>e+1);return g.registerOnUpdateListener(e),()=>{g.removeOnUpdateListener(e)}},[g]);let I=pe||!!g?.validators.find(e=>e.validatorId===`required`),L=g==null?c:g.value,R=T!=null&&L!=null?Math.abs(Number(L)):L,z=R==null?``:String(R);function B(e){let t=e;t!==void 0&&(T===`-`&&(t=-Math.abs(t)),T===`+`&&(t=Math.abs(t))),g?.set(t??null),p?.(t)}function V(e){let t=e;return!b&&T!==`-`&&(t=Math.max(0,t)),T===`-`&&(t=Math.min(0,t)),D!==void 0&&(t=Math.max(D,t)),O!==void 0&&(t=Math.min(O,t)),t}let H=L!=null&&L!==``?Number(L):0;function U(){if(A||j||L==null||L===``)return;let e=Number(L);if(!Number.isFinite(e))return;let t=V(e);t!==e&&B(t)}function W(e){if(A||j)return!1;let t=V(H+e);return t!==H&&(B(t),!0)}let{start:me,stop:he}=ne(e=>W(e*E));function ge(e){if(e.key===`Enter`){U(),M?.(e);return}if(!G){M?.(e);return}if(e.key===`ArrowUp`){e.preventDefault(),W(e.shiftKey?E*10:E);return}if(e.key===`ArrowDown`){e.preventDefault(),W(e.shiftKey?-E*10:-E);return}M?.(e)}let _e=T===`-`?`-`:T===`+`?`+`:le,ve=i(),G=de&&!A&&!j,K=k===`split`||k===`auto`&&ve,q=V(H+E)!==H,J=V(H-E)!==H,Y={onStart:me,onStop:he},X=G&&!K?f(`div`,{className:a.arrows,children:[d(m,{label:P.increase,icon:re,disabled:!q,direction:1,...Y}),d(m,{label:P.decrease,icon:l,disabled:!J,direction:-1,...Y})]}):null,ye=G?{role:`spinbutton`,"aria-valuenow":Number.isFinite(H)?H:void 0,"aria-valuemin":D,"aria-valuemax":O,"aria-valuetext":z||void 0}:{},Z=g?!g.touched||!g.hasError():!_,Q=G&&K,$=d(te,{label:se,className:s(a.numberInput,{[a.numberInputSplit]:Q},Q?void 0:v),style:Q?void 0:y,value:z,onChange:()=>{},formValidator:null,isRequired:I,onBlur:()=>{U(),r.current&&(r.current.touched=!0)},isValid:Z,errorMessage:g?g.touched?g.getCurrentErrorMessage()??``:``:_??``,placeholder:ue,readOnly:A,disabled:j,suffix:X,classNames:X?{suffix:a.arrowSuffix}:void 0,inputMode:C===0?`numeric`:`decimal`,customInput:d(ae,{onValueChange:e=>B(e.floatValue),allowNegative:T==null&&b,decimalSeparator:x,thousandSeparator:ce,decimalScale:C,fixedDecimalScale:w,prefix:_e,suffix:S,onKeyDown:ge,...ye,...N})});return Q?f(ee,{className:s(a.split,{[a.splitInvalid]:!Z},v),style:y,children:[d(h,{label:P.decrease,icon:u,disabled:!J,direction:-1,...Y}),$,d(h,{label:P.increase,icon:ie,disabled:!q,direction:1,...Y})]}):$}export{g as default};
1
+ import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n}from"../button/button.types.mjs";import r from"../button/button.mjs";import i from"../hooks/useCoarsePointer.mjs";import ee from"../buttonGroup/buttonGroup.mjs";import a from"../input/input.mjs";import o from"./numberInput.module.mjs";import te from"./useStepRepeat.mjs";import s from"react";import c from"classnames";import{FontAwesomeIcon as l}from"@fortawesome/react-fontawesome";import{faChevronDown as ne,faChevronUp as re,faMinus as ie,faPlus as ae}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";import{NumericFormat as oe}from"react-number-format";var se={increase:`Increase`,decrease:`Decrease`};function f({label:e,disabled:t,direction:n,onStart:r,onStop:i}){return{tabIndex:-1,disabled:t,"aria-label":e,onPointerDown:e=>{(e.button===0||e.pointerType!==`mouse`)&&(e.preventDefault(),r(n,e.shiftKey?10:1))},onPointerUp:i,onPointerCancel:i,onContextMenu:e=>e.preventDefault()}}function p(e){return u(`button`,{type:`button`,...f(e),className:c(o.arrowBtn,e.className),style:e.style,children:u(l,{icon:e.icon,"aria-hidden":`true`})})}function m(e){let{disabled:t,...i}=f(e);return u(r,{...i,className:c(o.splitBtn,e.className),style:e.style,size:n.Icon,disabled:t,icon:e.icon})}function h(n){let r=s.useRef(void 0),{value:l,onChange:f,formValidator:h,label:ce,error:g,className:_,style:v,classNames:y,styles:b,allowNegative:x=!1,decimalSeparator:S,thousandSeparator:C,prefix:le,suffix:ue,decimalScale:w,fixedDecimalScale:de=!0,placeholder:fe,sign:T,showArrows:pe=!1,step:E=1,min:D,max:O,arrowsLayout:k=`auto`,labels:me,readOnly:A=!1,disabled:j=!1,isRequired:he=!1,onKeyDown:M,...ge}=e(`NumberInput`,n),N=t(`NumberInput`,me,se),[,P]=s.useState(0);s.useEffect(()=>{if(r.current=h,!h)return;let e=()=>P(e=>e+1);return h.registerOnUpdateListener(e),()=>{h.removeOnUpdateListener(e)}},[h]);let F=he||!!h?.validators.find(e=>e.validatorId===`required`),I=h==null?l:h.value,L=T!=null&&I!=null?Math.abs(Number(I)):I,R=L==null?``:String(L);function z(e){let t=e;t!==void 0&&(T===`-`&&(t=-Math.abs(t)),T===`+`&&(t=Math.abs(t))),h?.set(t??null),f?.(t)}function B(e){let t=e;return!x&&T!==`-`&&(t=Math.max(0,t)),T===`-`&&(t=Math.min(0,t)),D!==void 0&&(t=Math.max(D,t)),O!==void 0&&(t=Math.min(O,t)),t}let V=I!=null&&I!==``?Number(I):0;function H(){if(A||j||I==null||I===``)return;let e=Number(I);if(!Number.isFinite(e))return;let t=B(e);t!==e&&z(t)}function U(e){if(A||j)return!1;let t=B(V+e);return t!==V&&(z(t),!0)}let{start:_e,stop:ve}=te(e=>U(e*E));function ye(e){if(e.key===`Enter`){H(),M?.(e);return}if(!G){M?.(e);return}if(e.key===`ArrowUp`){e.preventDefault(),U(e.shiftKey?E*10:E);return}if(e.key===`ArrowDown`){e.preventDefault(),U(e.shiftKey?-E*10:-E);return}M?.(e)}let be=T===`-`?`-`:T===`+`?`+`:le,W=i(),G=pe&&!A&&!j,K=k===`split`||k===`auto`&&W,q=B(V+E)!==V,J=B(V-E)!==V,Y={onStart:_e,onStop:ve},X=G&&!K?d(`div`,{className:c(o.arrows,y?.arrows),style:b?.arrows,children:[u(p,{className:y?.increaseButton,style:b?.increaseButton,label:N.increase,icon:re,disabled:!q,direction:1,...Y}),u(p,{className:y?.decreaseButton,style:b?.decreaseButton,label:N.decrease,icon:ne,disabled:!J,direction:-1,...Y})]}):null,xe=G?{role:`spinbutton`,"aria-valuenow":Number.isFinite(V)?V:void 0,"aria-valuemin":D,"aria-valuemax":O,"aria-valuetext":R||void 0}:{},Z=h?!h.touched||!h.hasError():!g,Q=G&&K,$=u(a,{label:ce,className:c(o.numberInput,{[o.numberInputSplit]:Q},Q?void 0:_,Q?void 0:y?.root,y?.input),style:{...Q?void 0:v,...Q?void 0:b?.root,...b?.input},value:R,onChange:()=>{},formValidator:null,isRequired:F,onBlur:()=>{H(),r.current&&(r.current.touched=!0)},isValid:Z,errorMessage:h?h.touched?h.getCurrentErrorMessage()??``:``:g??``,placeholder:fe,readOnly:A,disabled:j,suffix:X,classNames:X?{suffix:o.arrowSuffix}:void 0,inputMode:w===0?`numeric`:`decimal`,customInput:u(oe,{onValueChange:e=>z(e.floatValue),allowNegative:T==null&&x,decimalSeparator:S,thousandSeparator:C,decimalScale:w,fixedDecimalScale:de,prefix:be,suffix:ue,onKeyDown:ye,...xe,...ge})});return Q?d(ee,{className:c(o.split,{[o.splitInvalid]:!Z},_,y?.root),style:{...v,...b?.root},children:[u(m,{className:y?.decreaseButton,style:b?.decreaseButton,label:N.decrease,icon:ie,disabled:!J,direction:-1,...Y}),$,u(m,{className:y?.increaseButton,style:b?.increaseButton,label:N.increase,icon:ae,disabled:!q,direction:1,...Y})]}):$}export{h as default};
2
2
  //# sourceMappingURL=numberInput.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"numberInput.mjs","names":[],"sources":["../../../../package/common/numberInput/numberInput.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React from 'react';\nimport cx from 'classnames';\nimport { NumericFormat } from 'react-number-format';\nimport type { FormValidator } from 'services/formValidation';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronUp, faChevronDown, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './numberInput.module.pcss';\nimport Input from '../input';\nimport Button from '../button';\nimport ButtonGroup from '../buttonGroup';\nimport { ButtonSize } from '../button/button.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { useCoarsePointer } from '../hooks/useCoarsePointer';\nimport { useStepRepeat } from './useStepRepeat';\nimport type { NumberInputLabels, NumberInputProps } from './numberInput.types';\n\nexport type { NumberInputProps, NumberInputArrowsLayout } from './numberInput.types';\n\ninterface StepButtonProps {\n label: string;\n icon: typeof faPlus;\n disabled: boolean;\n direction: 1 | -1;\n onStart: (direction: 1 | -1, multiplier: number) => void;\n onStop: () => void;\n}\n\n/** Press-and-hold behaviour shared by both stepper layouts. */\nconst DEFAULT_LABELS: Required<NumberInputLabels> = {\n increase: 'Increase',\n decrease: 'Decrease',\n};\n\nfunction stepButtonProps({ label, disabled, direction, onStart, onStop }: StepButtonProps) {\n return {\n // The input keeps the tab stop — it carries role=\"spinbutton\", which announces the value\n // and the arrow-key affordance, so two more tab stops per field would be noise.\n tabIndex: -1,\n disabled,\n 'aria-label': label,\n // pointerdown (not click) keeps focus in the field and responds immediately on touch.\n // Deliberately no setPointerCapture: capturing retargets the following click to the captured\n // element, past the node Button's ripple listens on. useStepRepeat watches the window for\n // the release instead.\n onPointerDown: (e: React.PointerEvent<HTMLElement>) => {\n if (e.button !== 0 && e.pointerType === 'mouse') return;\n e.preventDefault();\n onStart(direction, e.shiftKey ? 10 : 1);\n },\n onPointerUp: onStop,\n onPointerCancel: onStop,\n onContextMenu: (e: React.SyntheticEvent) => e.preventDefault(),\n };\n}\n\n/** Stacked-layout chevron: borderless, sits inside the field's border. */\nfunction ChevronStepButton(props: StepButtonProps): ReactElement {\n return (\n <button type='button' {...stepButtonProps(props)} className={styles.arrowBtn}>\n <FontAwesomeIcon icon={props.icon} aria-hidden='true' />\n </button>\n );\n}\n\n/** Split-layout stepper: a standalone control, so a real Button. */\nfunction SplitStepButton(props: StepButtonProps): ReactElement {\n const { disabled, ...handlers } = stepButtonProps(props);\n return (\n <Button {...handlers} className={styles.splitBtn} size={ButtonSize.Icon} disabled={disabled} icon={props.icon} />\n );\n}\n\nfunction NumberInput(props: NumberInputProps): ReactElement {\n const fvRef = React.useRef<FormValidator | null | undefined>(undefined);\n const {\n value,\n onChange,\n formValidator,\n label,\n error,\n className,\n style,\n allowNegative = false,\n decimalSeparator,\n thousandSeparator,\n prefix,\n suffix,\n decimalScale,\n fixedDecimalScale = true,\n placeholder,\n sign,\n showArrows = false,\n step = 1,\n min,\n max,\n arrowsLayout = 'auto',\n labels,\n readOnly = false,\n disabled = false,\n isRequired = false,\n onKeyDown: onKeyDownProp,\n ...rest\n } = useComponentDefaults('NumberInput', props);\n const text = useLabels('NumberInput', labels, DEFAULT_LABELS);\n const [, forceUpdate] = React.useState(0);\n React.useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => {\n formValidator.removeOnUpdateListener(listener);\n };\n }, [formValidator]);\n const computedIsRequired =\n isRequired || !!formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required');\n const rawValue = formValidator != null ? (formValidator.value as number | string) : value;\n // When a sign is forced, display the absolute value — the prefix character carries the sign visually.\n const displayValue = sign != null && rawValue != null ? Math.abs(Number(rawValue)) : rawValue;\n const controlledValue = displayValue != null ? String(displayValue) : '';\n\n function handleValueChange(floatValue: number | undefined) {\n let out = floatValue;\n if (out !== undefined) {\n if (sign === '-') out = -Math.abs(out);\n if (sign === '+') out = Math.abs(out);\n }\n if (formValidator != null) formValidator.set(out ?? null);\n onChange?.(out);\n }\n\n function clamp(next: number): number {\n let out = next;\n if (!allowNegative && sign !== '-') out = Math.max(0, out);\n if (sign === '-') out = Math.min(0, out);\n if (min !== undefined) out = Math.max(min, out);\n if (max !== undefined) out = Math.min(max, out);\n return out;\n }\n\n const currentNumber = rawValue != null && rawValue !== '' ? Number(rawValue) : 0;\n\n /**\n * Called on blur and Enter, never per keystroke: rejecting an out-of-bounds edit as it is\n * typed swallows keystrokes on their way somewhere valid (with `max: 10`, typing `1` in front\n * of `8` to reach `18`). An empty field is skipped so a `min` is never typed in for the user.\n */\n function clampToBounds() {\n if (readOnly || disabled) return;\n if (rawValue == null || rawValue === '') return;\n const n = Number(rawValue);\n if (!Number.isFinite(n)) return;\n const next = clamp(n);\n if (next !== n) handleValueChange(next);\n }\n\n /** Returns whether the value moved, which is how useStepRepeat knows to end a hold at a bound. */\n function handleStep(delta: number): boolean {\n if (readOnly || disabled) return false;\n const next = clamp(currentNumber + delta);\n if (next === currentNumber) return false;\n handleValueChange(next);\n return true;\n }\n\n const { start: startRepeat, stop: stopRepeat } = useStepRepeat((delta) => handleStep(delta * step));\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n // Enter submits the surrounding form without ever blurring, so the blur clamp would not run.\n // Before the stepper guard, since the bounds apply with or without steppers.\n if (e.key === 'Enter') {\n clampToBounds();\n onKeyDownProp?.(e);\n return;\n }\n if (!showStepper) {\n onKeyDownProp?.(e);\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleStep(e.shiftKey ? step * 10 : step);\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleStep(e.shiftKey ? -step * 10 : -step);\n return;\n }\n onKeyDownProp?.(e);\n }\n\n const resolvedPrefix = sign === '-' ? '-' : sign === '+' ? '+' : prefix;\n\n const isCoarsePointer = useCoarsePointer();\n const showStepper = showArrows && !readOnly && !disabled;\n const isSplit = arrowsLayout === 'split' || (arrowsLayout === 'auto' && isCoarsePointer);\n\n const canIncrease = clamp(currentNumber + step) !== currentNumber;\n const canDecrease = clamp(currentNumber - step) !== currentNumber;\n\n const stepperProps = { onStart: startRepeat, onStop: stopRepeat };\n\n const stackedArrows =\n showStepper && !isSplit ? (\n <div className={styles.arrows}>\n <ChevronStepButton\n label={text.increase}\n icon={faChevronUp}\n disabled={!canIncrease}\n direction={1}\n {...stepperProps}\n />\n <ChevronStepButton\n label={text.decrease}\n icon={faChevronDown}\n disabled={!canDecrease}\n direction={-1}\n {...stepperProps}\n />\n </div>\n ) : null;\n\n // aria-* is spread onto NumericFormat, which forwards unknown props to the DOM input.\n // Input's own cloneElement doesn't set these keys, so they survive the clone.\n const spinButtonProps = showStepper\n ? {\n role: 'spinbutton',\n 'aria-valuenow': Number.isFinite(currentNumber) ? currentNumber : undefined,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n 'aria-valuetext': controlledValue || undefined,\n }\n : {};\n\n // Shared with the split group, whose buttons have to mirror the field's invalid state — they\n // form one continuous border.\n const isValid = formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error;\n\n // In the split layout the ButtonGroup is the root, so the consumer's className and style\n // belong there rather than on the Input.\n const isSplitGroup = showStepper && isSplit;\n\n const input = (\n <Input\n label={label}\n className={cx(\n styles.numberInput,\n { [styles.numberInputSplit]: isSplitGroup },\n isSplitGroup ? undefined : className,\n )}\n style={isSplitGroup ? undefined : style}\n value={controlledValue}\n onChange={() => {}}\n formValidator={null}\n isRequired={computedIsRequired}\n onBlur={() => {\n clampToBounds();\n if (fvRef.current) fvRef.current.touched = true;\n }}\n isValid={isValid}\n errorMessage={\n formValidator ? (formValidator.touched ? (formValidator.getCurrentErrorMessage() ?? '') : '') : (error ?? '')\n }\n placeholder={placeholder}\n readOnly={readOnly}\n disabled={disabled}\n suffix={stackedArrows}\n // Input centres its suffix wrapper; this lets the chevrons claim the field's full height.\n classNames={stackedArrows ? { suffix: styles.arrowSuffix } : undefined}\n inputMode={decimalScale === 0 ? 'numeric' : 'decimal'}\n customInput={\n <NumericFormat\n onValueChange={(vals) => handleValueChange(vals.floatValue)}\n allowNegative={sign != null ? false : allowNegative}\n decimalSeparator={decimalSeparator}\n thousandSeparator={thousandSeparator}\n decimalScale={decimalScale}\n fixedDecimalScale={fixedDecimalScale}\n prefix={resolvedPrefix}\n suffix={suffix}\n onKeyDown={handleKeyDown}\n {...spinButtonProps}\n {...rest}\n />\n }\n />\n );\n\n if (!isSplitGroup) return input;\n\n return (\n // ButtonGroup collapses the doubled borders and flattens the inner corners, so the three\n // read as one control.\n <ButtonGroup className={cx(styles.split, { [styles.splitInvalid]: !isValid }, className)} style={style}>\n <SplitStepButton label={text.decrease} icon={faMinus} disabled={!canDecrease} direction={-1} {...stepperProps} />\n {input}\n <SplitStepButton label={text.increase} icon={faPlus} disabled={!canIncrease} direction={1} {...stepperProps} />\n </ButtonGroup>\n );\n}\n\nexport default NumberInput;\n"],"mappings":"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"}
1
+ {"version":3,"file":"numberInput.mjs","names":[],"sources":["../../../../package/common/numberInput/numberInput.tsx"],"sourcesContent":["import type { CSSProperties, ReactElement } from 'react';\nimport React from 'react';\nimport cx from 'classnames';\nimport { NumericFormat } from 'react-number-format';\nimport type { FormValidator } from 'services/formValidation';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronUp, faChevronDown, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './numberInput.module.pcss';\nimport Input from '../input';\nimport Button from '../button';\nimport ButtonGroup from '../buttonGroup';\nimport { ButtonSize } from '../button/button.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { useCoarsePointer } from '../hooks/useCoarsePointer';\nimport { useStepRepeat } from './useStepRepeat';\nimport type { NumberInputLabels, NumberInputProps } from './numberInput.types';\n\nexport type { NumberInputProps, NumberInputArrowsLayout } from './numberInput.types';\n\ninterface StepButtonProps {\n label: string;\n className?: string;\n style?: CSSProperties;\n icon: typeof faPlus;\n disabled: boolean;\n direction: 1 | -1;\n onStart: (direction: 1 | -1, multiplier: number) => void;\n onStop: () => void;\n}\n\n/** Press-and-hold behaviour shared by both stepper layouts. */\nconst DEFAULT_LABELS: Required<NumberInputLabels> = {\n increase: 'Increase',\n decrease: 'Decrease',\n};\n\nfunction stepButtonProps({ label, disabled, direction, onStart, onStop }: StepButtonProps) {\n return {\n // The input keeps the tab stop — it carries role=\"spinbutton\", which announces the value\n // and the arrow-key affordance, so two more tab stops per field would be noise.\n tabIndex: -1,\n disabled,\n 'aria-label': label,\n // pointerdown (not click) keeps focus in the field and responds immediately on touch.\n // Deliberately no setPointerCapture: capturing retargets the following click to the captured\n // element, past the node Button's ripple listens on. useStepRepeat watches the window for\n // the release instead.\n onPointerDown: (e: React.PointerEvent<HTMLElement>) => {\n if (e.button !== 0 && e.pointerType === 'mouse') return;\n e.preventDefault();\n onStart(direction, e.shiftKey ? 10 : 1);\n },\n onPointerUp: onStop,\n onPointerCancel: onStop,\n onContextMenu: (e: React.SyntheticEvent) => e.preventDefault(),\n };\n}\n\n/** Stacked-layout chevron: borderless, sits inside the field's border. */\nfunction ChevronStepButton(props: StepButtonProps): ReactElement {\n return (\n <button\n type='button'\n {...stepButtonProps(props)}\n className={cx(styles.arrowBtn, props.className)}\n style={props.style}\n >\n <FontAwesomeIcon icon={props.icon} aria-hidden='true' />\n </button>\n );\n}\n\n/** Split-layout stepper: a standalone control, so a real Button. */\nfunction SplitStepButton(props: StepButtonProps): ReactElement {\n const { disabled, ...handlers } = stepButtonProps(props);\n return (\n <Button\n {...handlers}\n className={cx(styles.splitBtn, props.className)}\n style={props.style}\n size={ButtonSize.Icon}\n disabled={disabled}\n icon={props.icon}\n />\n );\n}\n\nfunction NumberInput(props: NumberInputProps): ReactElement {\n const fvRef = React.useRef<FormValidator | null | undefined>(undefined);\n const {\n value,\n onChange,\n formValidator,\n label,\n error,\n className,\n style,\n classNames,\n styles: slotStyles,\n allowNegative = false,\n decimalSeparator,\n thousandSeparator,\n prefix,\n suffix,\n decimalScale,\n fixedDecimalScale = true,\n placeholder,\n sign,\n showArrows = false,\n step = 1,\n min,\n max,\n arrowsLayout = 'auto',\n labels,\n readOnly = false,\n disabled = false,\n isRequired = false,\n onKeyDown: onKeyDownProp,\n ...rest\n } = useComponentDefaults('NumberInput', props);\n const text = useLabels('NumberInput', labels, DEFAULT_LABELS);\n const [, forceUpdate] = React.useState(0);\n React.useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => {\n formValidator.removeOnUpdateListener(listener);\n };\n }, [formValidator]);\n const computedIsRequired =\n isRequired || !!formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required');\n const rawValue = formValidator != null ? (formValidator.value as number | string) : value;\n // When a sign is forced, display the absolute value — the prefix character carries the sign visually.\n const displayValue = sign != null && rawValue != null ? Math.abs(Number(rawValue)) : rawValue;\n const controlledValue = displayValue != null ? String(displayValue) : '';\n\n function handleValueChange(floatValue: number | undefined) {\n let out = floatValue;\n if (out !== undefined) {\n if (sign === '-') out = -Math.abs(out);\n if (sign === '+') out = Math.abs(out);\n }\n if (formValidator != null) formValidator.set(out ?? null);\n onChange?.(out);\n }\n\n function clamp(next: number): number {\n let out = next;\n if (!allowNegative && sign !== '-') out = Math.max(0, out);\n if (sign === '-') out = Math.min(0, out);\n if (min !== undefined) out = Math.max(min, out);\n if (max !== undefined) out = Math.min(max, out);\n return out;\n }\n\n const currentNumber = rawValue != null && rawValue !== '' ? Number(rawValue) : 0;\n\n /**\n * Called on blur and Enter, never per keystroke: rejecting an out-of-bounds edit as it is\n * typed swallows keystrokes on their way somewhere valid (with `max: 10`, typing `1` in front\n * of `8` to reach `18`). An empty field is skipped so a `min` is never typed in for the user.\n */\n function clampToBounds() {\n if (readOnly || disabled) return;\n if (rawValue == null || rawValue === '') return;\n const n = Number(rawValue);\n if (!Number.isFinite(n)) return;\n const next = clamp(n);\n if (next !== n) handleValueChange(next);\n }\n\n /** Returns whether the value moved, which is how useStepRepeat knows to end a hold at a bound. */\n function handleStep(delta: number): boolean {\n if (readOnly || disabled) return false;\n const next = clamp(currentNumber + delta);\n if (next === currentNumber) return false;\n handleValueChange(next);\n return true;\n }\n\n const { start: startRepeat, stop: stopRepeat } = useStepRepeat((delta) => handleStep(delta * step));\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n // Enter submits the surrounding form without ever blurring, so the blur clamp would not run.\n // Before the stepper guard, since the bounds apply with or without steppers.\n if (e.key === 'Enter') {\n clampToBounds();\n onKeyDownProp?.(e);\n return;\n }\n if (!showStepper) {\n onKeyDownProp?.(e);\n return;\n }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleStep(e.shiftKey ? step * 10 : step);\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleStep(e.shiftKey ? -step * 10 : -step);\n return;\n }\n onKeyDownProp?.(e);\n }\n\n const resolvedPrefix = sign === '-' ? '-' : sign === '+' ? '+' : prefix;\n\n const isCoarsePointer = useCoarsePointer();\n const showStepper = showArrows && !readOnly && !disabled;\n const isSplit = arrowsLayout === 'split' || (arrowsLayout === 'auto' && isCoarsePointer);\n\n const canIncrease = clamp(currentNumber + step) !== currentNumber;\n const canDecrease = clamp(currentNumber - step) !== currentNumber;\n\n const stepperProps = { onStart: startRepeat, onStop: stopRepeat };\n\n const stackedArrows =\n showStepper && !isSplit ? (\n <div className={cx(styles.arrows, classNames?.arrows)} style={slotStyles?.arrows}>\n <ChevronStepButton\n className={classNames?.increaseButton}\n style={slotStyles?.increaseButton}\n label={text.increase}\n icon={faChevronUp}\n disabled={!canIncrease}\n direction={1}\n {...stepperProps}\n />\n <ChevronStepButton\n className={classNames?.decreaseButton}\n style={slotStyles?.decreaseButton}\n label={text.decrease}\n icon={faChevronDown}\n disabled={!canDecrease}\n direction={-1}\n {...stepperProps}\n />\n </div>\n ) : null;\n\n // aria-* is spread onto NumericFormat, which forwards unknown props to the DOM input.\n // Input's own cloneElement doesn't set these keys, so they survive the clone.\n const spinButtonProps = showStepper\n ? {\n role: 'spinbutton',\n 'aria-valuenow': Number.isFinite(currentNumber) ? currentNumber : undefined,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n 'aria-valuetext': controlledValue || undefined,\n }\n : {};\n\n // Shared with the split group, whose buttons have to mirror the field's invalid state — they\n // form one continuous border.\n const isValid = formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error;\n\n // In the split layout the ButtonGroup is the root, so the consumer's className and style\n // belong there rather than on the Input.\n const isSplitGroup = showStepper && isSplit;\n\n const input = (\n <Input\n label={label}\n className={cx(\n styles.numberInput,\n { [styles.numberInputSplit]: isSplitGroup },\n // In split mode the ButtonGroup around all three is the root, so the\n // consumer's root class belongs there rather than on the field.\n isSplitGroup ? undefined : className,\n isSplitGroup ? undefined : classNames?.root,\n classNames?.input,\n )}\n style={{\n ...(isSplitGroup ? undefined : style),\n ...(isSplitGroup ? undefined : slotStyles?.root),\n ...slotStyles?.input,\n }}\n value={controlledValue}\n onChange={() => {}}\n formValidator={null}\n isRequired={computedIsRequired}\n onBlur={() => {\n clampToBounds();\n if (fvRef.current) fvRef.current.touched = true;\n }}\n isValid={isValid}\n errorMessage={\n formValidator ? (formValidator.touched ? (formValidator.getCurrentErrorMessage() ?? '') : '') : (error ?? '')\n }\n placeholder={placeholder}\n readOnly={readOnly}\n disabled={disabled}\n suffix={stackedArrows}\n // Input centres its suffix wrapper; this lets the chevrons claim the field's full height.\n classNames={stackedArrows ? { suffix: styles.arrowSuffix } : undefined}\n inputMode={decimalScale === 0 ? 'numeric' : 'decimal'}\n customInput={\n <NumericFormat\n onValueChange={(vals) => handleValueChange(vals.floatValue)}\n allowNegative={sign != null ? false : allowNegative}\n decimalSeparator={decimalSeparator}\n thousandSeparator={thousandSeparator}\n decimalScale={decimalScale}\n fixedDecimalScale={fixedDecimalScale}\n prefix={resolvedPrefix}\n suffix={suffix}\n onKeyDown={handleKeyDown}\n {...spinButtonProps}\n {...rest}\n />\n }\n />\n );\n\n if (!isSplitGroup) return input;\n\n return (\n // ButtonGroup collapses the doubled borders and flattens the inner corners, so the three\n // read as one control.\n <ButtonGroup\n className={cx(styles.split, { [styles.splitInvalid]: !isValid }, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <SplitStepButton\n className={classNames?.decreaseButton}\n style={slotStyles?.decreaseButton}\n label={text.decrease}\n icon={faMinus}\n disabled={!canDecrease}\n direction={-1}\n {...stepperProps}\n />\n {input}\n <SplitStepButton\n className={classNames?.increaseButton}\n style={slotStyles?.increaseButton}\n label={text.increase}\n icon={faPlus}\n disabled={!canIncrease}\n direction={1}\n {...stepperProps}\n />\n </ButtonGroup>\n );\n}\n\nexport default NumberInput;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{usePresentationDefault as t}from"../configProvider/usePresentationDefault.mjs";import n from"../bodyEnd/bodyEnd.mjs";import r from"../styles/sheet.module.mjs";import i from"../sheetBackdrop/sheetBackdrop.mjs";import{tabbablesIn as a,useFocusBoundary as o}from"../hooks/useFocusBoundary.mjs";import{Presentation as s}from"../floatingMenu/floatingMenu.types.mjs";import ee from"../hooks/useSheet.mjs";import{useOverlay as c}from"../hooks/useOverlay.mjs";import l from"./popover.module.mjs";import{PopoverAlign as u,PopoverPlacement as d,PopoverTrigger as f}from"./popover.types.mjs";import{usePopoverPosition as p}from"./usePopoverPosition.mjs";import{useCallback as m,useEffect as h,useRef as g,useState as te}from"react";import _ from"classnames";import{jsx as v,jsxs as y}from"react/jsx-runtime";function b(b){let{children:x=null,content:S=null,placement:C=d.Bottom,align:w=u.Center,trigger:T=f.Click,isOpen:E,defaultOpen:D=!1,onOpenChange:O=()=>{},offset:ne=10,withArrow:k=!0,closeOnOutsideClick:A=!0,closeOnEscape:j=!0,openDelay:M=100,closeDelay:N=120,disabled:P=!1,presentation:F,className:I,style:L,classNames:R,styles:z,...B}=e(`Popover`,b),V=g(null),H=g(null),U=g(null),W=g(null),G=g(void 0),K=E!==void 0,[q,J]=te(D),Y=K?E:q,X=g(O);h(()=>{X.current=O});let Z=m(e=>{P&&e||(K||J(e),X.current(e))},[P,K]),re=t(),ie=F??re??s.Default,{isSheet:ae,sheetStyle:oe}=ee(ie),Q=ae&&T===f.Click;p({isOpen:!!Y&&!Q,placement:C,align:w,offset:ne,triggerRef:V,floatingRef:H,panelRef:U,arrowRef:k?W:{current:null}}),c({isActive:!!Y,containerRef:U,onEscape:j?()=>{H.current?.contains(document.activeElement)&&(a(V.current)[0]??V.current)?.focus(),Z(!1)}:void 0,trapFocus:!1,lockScroll:Q});let{restoreFocusToTrigger:se,focusAfterTrigger:ce}=o({triggerRef:V,contentRef:H});h(()=>{if(!Y||T!==f.Click)return;let e=a(U.current);e.length!==0&&(H.current?.setAttribute(`role`,`dialog`),e[0].focus())},[Y,T]);function le(e){if(e.key!==`Tab`||T!==f.Click)return;let t=a(U.current);if(t.length===0)return;let n=document.activeElement;!e.shiftKey&&n===t[t.length-1]?(e.preventDefault(),ce(),Z(!1)):e.shiftKey&&n===t[0]&&(e.preventDefault(),se(),Z(!1))}h(()=>{if(!Y)return;function e(e){let t=e.target,n=H.current?.contains(t),r=V.current?.contains(t);!n&&!r&&Z(!1)}function t(e){let t=e.target,n=H.current?.contains(t),r=V.current?.contains(t);!n&&!r&&Z(!1)}return A&&T!==f.Hover&&(window.addEventListener(`mouseup`,e),document.addEventListener(`focusin`,t)),()=>{window.removeEventListener(`mouseup`,e),document.removeEventListener(`focusin`,t)}},[Y,A,T,Z]),h(()=>()=>clearTimeout(G.current),[]);function $(e){clearTimeout(G.current),G.current=setTimeout(()=>Z(e),e?M:N)}let ue=T===f.Click?{onClick:()=>Z(!Y)}:T===f.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{onFocus:()=>Z(!0),onBlur:()=>Z(!1)},de=T===f.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{};return y(`div`,{...B,className:_(l.popover,I,R?.root),style:{...L,...z?.root},children:[v(`div`,{ref:V,className:_(l.popoverTrigger,R?.trigger),style:z?.trigger,...ue,children:x}),Y&&y(n,{children:[Q&&v(i,{onClose:()=>{A&&Z(!1)},className:R?.backdrop,style:z?.backdrop}),y(`div`,{ref:H,className:_(Q?r.sheet:l.popoverFloating,R?.floating),style:{...Q?oe:void 0,...z?.floating},"data-placement":C,onKeyDown:le,...de,children:[v(`div`,{ref:U,className:_(l.popoverPanel,Q&&r.sheetPanel,R?.panel),style:z?.panel,children:S}),k&&!Q&&v(`div`,{ref:W,className:_(l.popoverArrow,R?.arrow),style:z?.arrow})]})]})]})}export{b as default};
1
+ import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{usePresentationDefault as t}from"../configProvider/usePresentationDefault.mjs";import{Presentation as n}from"../configProvider/presentation.types.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"./popover.module.mjs";import a from"../styles/sheet.module.mjs";import o from"../sheetBackdrop/sheetBackdrop.mjs";import{PopoverAlign as ee,PopoverPlacement as s,PopoverTrigger as c}from"./popover.types.mjs";import{usePopoverPosition as te}from"./usePopoverPosition.mjs";import{tabbablesIn as l,useFocusBoundary as ne}from"../hooks/useFocusBoundary.mjs";import u from"../hooks/useSheet.mjs";import{useOverlay as d}from"../hooks/useOverlay.mjs";import{useCallback as f,useEffect as p,useRef as m,useState as re}from"react";import h from"classnames";import{jsx as g,jsxs as _}from"react/jsx-runtime";function v(v){let{children:y=null,content:b=null,placement:x=s.Bottom,align:S=ee.Center,trigger:C=c.Click,isOpen:w,defaultOpen:T=!1,onOpenChange:E=()=>{},offset:ie=10,withArrow:D=!0,closeOnOutsideClick:O=!0,closeOnEscape:ae=!0,openDelay:oe=100,closeDelay:se=120,disabled:k=!1,focusOnOpen:A=`keyboard`,closeOnTriggerClick:ce=!0,width:j=`auto`,constrainWidth:M=!0,presentation:N,className:P,style:F,classNames:I,styles:L,...R}=e(`Popover`,v),z=m(null),B=m(null),V=m(null),H=m(null),U=m(void 0),W=m(!1),G=m(!1);function K(){W.current=!0}let q=w!==void 0,[le,ue]=re(T),J=q?w:le,Y=m(E);p(()=>{Y.current=E});let X=f((e,t=!1)=>{k&&e||(e&&(G.current=t),q||ue(e),Y.current(e,{fromKeyboard:t}))},[k,q]),de=t(),fe=N??de??n.Default,{isSheet:pe,sheetStyle:me}=u(fe),Z=pe&&C===c.Click;te({isOpen:!!J&&!Z,placement:x,align:S,offset:ie,triggerRef:z,floatingRef:B,panelRef:V,arrowRef:D?H:{current:null},matchTriggerWidth:j===`trigger`}),d({isActive:!!J,containerRef:V,onEscape:ae?()=>{B.current?.contains(document.activeElement)&&(l(z.current)[0]??z.current)?.focus(),X(!1,!0)}:void 0,trapFocus:!1,lockScroll:Z});let{restoreFocusToTrigger:Q,focusAfterTrigger:he}=ne({triggerRef:z,contentRef:B});p(()=>{if(!J){G.current=!1;return}if(!(A===!0||A===`keyboard`&&G.current)||C!==c.Click)return;let e=l(V.current);e.length!==0&&(B.current?.setAttribute(`role`,`dialog`),e[0].focus())},[J,C,A]);function ge(e){if(e.key!==`Tab`||C!==c.Click)return;let t=l(V.current);if(t.length===0)return;let n=document.activeElement;!e.shiftKey&&n===t[t.length-1]?(e.preventDefault(),he(),X(!1,!0)):e.shiftKey&&n===t[0]&&(e.preventDefault(),Q(),X(!1,!0))}p(()=>{if(!J)return;function e(e){let t=W.current;W.current=!1;let n=e.target,r=B.current?.contains(n),i=z.current?.contains(n);!t&&!r&&!i&&X(!1)}function t(e){let t=W.current;W.current=!1;let n=e.target,r=B.current?.contains(n),i=z.current?.contains(n);!t&&!r&&!i&&X(!1,!0)}return O&&C!==c.Hover&&(window.addEventListener(`mouseup`,e),document.addEventListener(`focusin`,t)),()=>{window.removeEventListener(`mouseup`,e),document.removeEventListener(`focusin`,t)}},[J,O,C,X]),p(()=>()=>clearTimeout(U.current),[]);function $(e){clearTimeout(U.current),U.current=setTimeout(()=>X(e),e?oe:se)}function _e(e){J||e.key!==`ArrowDown`&&e.key!==`ArrowUp`||(e.preventDefault(),X(!0,!0))}let ve=C===c.Click?{onClick:e=>{(!J||ce)&&X(!J,e.detail===0)},onKeyDown:_e}:C===c.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{onFocus:()=>X(!0),onBlur:()=>X(!1)},ye=C===c.Hover?{onMouseEnter:()=>$(!0),onMouseLeave:()=>$(!1)}:{};return _(`div`,{...R,className:h(i.popover,P,I?.root),style:{...F,...L?.root},children:[g(`div`,{ref:z,className:h(i.popoverTrigger,I?.trigger),style:L?.trigger,...ve,children:y}),J&&_(r,{children:[Z&&g(o,{onClose:()=>{O&&X(!1)},className:I?.backdrop,style:L?.backdrop}),_(`div`,{ref:B,className:h(Z?a.sheet:i.popoverFloating,I?.floating),style:{...Z?me:void 0,...L?.floating},"data-placement":x,onKeyDown:ge,onMouseUpCapture:K,onFocusCapture:K,...ye,children:[g(`div`,{ref:V,className:h(i.popoverPanel,M&&i.popoverPanelConstrained,Z&&a.sheetPanel,I?.panel),style:L?.panel,children:b}),D&&!Z&&g(`div`,{ref:H,className:h(i.popoverArrow,I?.arrow),style:L?.arrow})]})]})]})}export{v as default};
2
2
  //# sourceMappingURL=popover.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.mjs","names":[],"sources":["../../../../package/common/popover/popover.tsx"],"sourcesContent":["import { useRef, useEffect, useState, useCallback } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './popover.module.pcss';\nimport sheetStyles from '../styles/sheet.module.pcss';\nimport SheetBackdrop from '../sheetBackdrop';\nimport { usePopoverPosition } from './usePopoverPosition';\nimport { useFocusBoundary, tabbablesIn } from '../hooks/useFocusBoundary';\nimport { useSheet } from '../hooks/useSheet';\nimport { useOverlay } from '../hooks/useOverlay';\nimport { useComponentDefaults, usePresentationDefault } from '../configProvider';\nimport { Presentation } from '../floatingMenu/floatingMenu.types';\nimport { PopoverPlacement, PopoverAlign, PopoverTrigger, type PopoverProps } from './popover.types';\n\nfunction Popover(props: PopoverProps) {\n const {\n children = null,\n content = null,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Center,\n trigger = PopoverTrigger.Click,\n isOpen,\n defaultOpen = false,\n onOpenChange = () => {},\n offset = 10,\n withArrow = true,\n closeOnOutsideClick = true,\n closeOnEscape = true,\n openDelay = 100,\n closeDelay = 120,\n disabled = false,\n presentation: presentationProp,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Popover', props);\n const triggerRef = useRef<HTMLDivElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const hoverTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n const isControlled = isOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const open = isControlled ? isOpen : internalOpen;\n\n // Keep the outside-click/Escape listeners pointed at the latest setter without re-subscribing.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n });\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (disabled && next) return;\n if (!isControlled) setInternalOpen(next);\n onOpenChangeRef.current(next);\n },\n [disabled, isControlled],\n );\n\n // Explicit prop → this component's global default → the app-wide one → anchored.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation ?? Presentation.Default;\n const { isSheet: sheetPresentation, sheetStyle } = useSheet(presentation);\n // Hover and focus are pointer affordances that open something small next to what caused them;\n // a sheet is a deliberate, screen-owning open. Only a click asks for one.\n const isSheet = sheetPresentation && trigger === PopoverTrigger.Click;\n\n // A sheet isn't anchored to anything, so there's nothing to track, flip or clamp.\n usePopoverPosition({\n isOpen: !!open && !isSheet,\n placement,\n align,\n offset,\n triggerRef,\n floatingRef,\n panelRef,\n arrowRef: withArrow ? arrowRef : { current: null },\n });\n\n // Registered for as long as it's open, not just as a sheet: this is what puts the popover on\n // the overlay stack, so an enclosing Modal knows something sits above it and neither drags\n // focus out of this (portaled, so outside the modal's panel) panel nor closes itself on the\n // Escape meant for this. Focus isn't trapped: a Popover is deliberately non-modal, and it\n // already moves focus into the panel on open by itself.\n useOverlay({\n isActive: !!open,\n containerRef: panelRef,\n onEscape: closeOnEscape\n ? () => {\n // Hand focus back to the trigger when it currently sits inside the panel.\n if (floatingRef.current?.contains(document.activeElement)) {\n (tabbablesIn(triggerRef.current)[0] ?? triggerRef.current)?.focus();\n }\n setOpen(false);\n }\n : undefined,\n trapFocus: false,\n lockScroll: isSheet,\n });\n\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({\n triggerRef,\n contentRef: floatingRef,\n });\n\n // The panel is portaled to the end of the DOM, so Tab never flows into it naturally. When we\n // manage focus (click trigger + focusable content), move focus in on open and, on Tab out of\n // either end, close and continue focus as if the panel sat right after the trigger.\n useEffect(() => {\n if (!open || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n // Only claim the dialog role when we're actually managing focus for real content.\n floatingRef.current?.setAttribute('role', 'dialog');\n focusables[0].focus();\n }, [open, trigger]);\n\n function handleFloatingKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'Tab' || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n const active = document.activeElement;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusAfterTrigger();\n setOpen(false);\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n restoreFocusToTrigger();\n setOpen(false);\n }\n }\n\n // Outside click. Registered only while open and only for the relevant trigger mode; Escape is\n // handled by `useOverlay` above, which scopes it to the innermost open layer.\n useEffect(() => {\n if (!open) return;\n\n function onMouseUp(event: MouseEvent) {\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n const inTrigger = triggerRef.current?.contains(target);\n if (!inPanel && !inTrigger) setOpen(false);\n }\n // Keyboard counterpart to the outside click: once focus leaves both the trigger\n // and the (portaled) panel — e.g. tabbing on to the next element — close.\n function onFocusIn(event: FocusEvent) {\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n const inTrigger = triggerRef.current?.contains(target);\n if (!inPanel && !inTrigger) setOpen(false);\n }\n\n if (closeOnOutsideClick && trigger !== PopoverTrigger.Hover) {\n window.addEventListener('mouseup', onMouseUp);\n document.addEventListener('focusin', onFocusIn);\n }\n return () => {\n window.removeEventListener('mouseup', onMouseUp);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [open, closeOnOutsideClick, trigger, setOpen]);\n\n useEffect(() => () => clearTimeout(hoverTimer.current), []);\n\n function scheduleHover(next: boolean) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = setTimeout(() => setOpen(next), next ? openDelay : closeDelay);\n }\n\n const triggerHandlers =\n trigger === PopoverTrigger.Click\n ? { onClick: () => setOpen(!open) }\n : trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : { onFocus: () => setOpen(true), onBlur: () => setOpen(false) };\n\n const floatingHoverHandlers =\n trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : {};\n\n return (\n <div\n {...rest}\n className={cx(styles.popover, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <div\n ref={triggerRef}\n className={cx(styles.popoverTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n {...triggerHandlers}\n >\n {children}\n </div>\n {open && (\n <BodyEnd>\n {isSheet && (\n <SheetBackdrop\n onClose={() => {\n if (closeOnOutsideClick) setOpen(false);\n }}\n className={classNames?.backdrop}\n style={slotStyles?.backdrop}\n />\n )}\n <div\n ref={floatingRef}\n className={cx(isSheet ? sheetStyles.sheet : styles.popoverFloating, classNames?.floating)}\n style={{ ...(isSheet ? sheetStyle : undefined), ...slotStyles?.floating }}\n data-placement={placement}\n onKeyDown={handleFloatingKeyDown}\n {...floatingHoverHandlers}\n >\n <div\n ref={panelRef}\n className={cx(styles.popoverPanel, isSheet && sheetStyles.sheetPanel, classNames?.panel)}\n style={slotStyles?.panel}\n >\n {content}\n </div>\n {withArrow && !isSheet && (\n <div ref={arrowRef} className={cx(styles.popoverArrow, classNames?.arrow)} style={slotStyles?.arrow} />\n )}\n </div>\n </BodyEnd>\n )}\n </div>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
1
+ {"version":3,"file":"popover.mjs","names":[],"sources":["../../../../package/common/popover/popover.tsx"],"sourcesContent":["import { useRef, useEffect, useState, useCallback } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './popover.module.pcss';\nimport sheetStyles from '../styles/sheet.module.pcss';\nimport SheetBackdrop from '../sheetBackdrop';\nimport { usePopoverPosition } from './usePopoverPosition';\nimport { useFocusBoundary, tabbablesIn } from '../hooks/useFocusBoundary';\nimport { useSheet } from '../hooks/useSheet';\nimport { useOverlay } from '../hooks/useOverlay';\nimport { useComponentDefaults, usePresentationDefault } from '../configProvider';\nimport { Presentation } from '../configProvider/presentation.types';\nimport { PopoverPlacement, PopoverAlign, PopoverTrigger, type PopoverProps } from './popover.types';\n\nfunction Popover(props: PopoverProps) {\n const {\n children = null,\n content = null,\n placement = PopoverPlacement.Bottom,\n align = PopoverAlign.Center,\n trigger = PopoverTrigger.Click,\n isOpen,\n defaultOpen = false,\n onOpenChange = () => {},\n offset = 10,\n withArrow = true,\n closeOnOutsideClick = true,\n closeOnEscape = true,\n openDelay = 100,\n closeDelay = 120,\n disabled = false,\n focusOnOpen = 'keyboard',\n closeOnTriggerClick = true,\n width = 'auto',\n constrainWidth = true,\n presentation: presentationProp,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Popover', props);\n const triggerRef = useRef<HTMLDivElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n const arrowRef = useRef<HTMLDivElement>(null);\n const hoverTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n // Set from a capture handler on the panel, which React fires for its whole\n // React subtree — including children that portal elsewhere in the DOM, such as\n // a Dropdown's list inside a DatePicker's calendar. A DOM `contains` check\n // cannot see those, and without this the panel closes when one is used.\n const panelInteractedRef = useRef(false);\n // Whether the open that is running came from the keyboard, which is what the\n // default `focusOnOpen` follows and what `onOpenChange` reports. A click raised\n // by Enter or Space reports `detail === 0`, where a pointer press counts the\n // clicks; an open with no trigger event at all, such as a panel that appears\n // while the user types, leaves this false.\n const openedByKeyboardRef = useRef(false);\n function markPanelInteraction() {\n panelInteractedRef.current = true;\n }\n\n const isControlled = isOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const open = isControlled ? isOpen : internalOpen;\n\n // Keep the outside-click/Escape listeners pointed at the latest setter without re-subscribing.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n });\n\n const setOpen = useCallback(\n (next: boolean, fromKeyboard = false) => {\n if (disabled && next) return;\n if (next) openedByKeyboardRef.current = fromKeyboard;\n if (!isControlled) setInternalOpen(next);\n onOpenChangeRef.current(next, { fromKeyboard });\n },\n [disabled, isControlled],\n );\n\n // Explicit prop → this component's global default → the app-wide one → anchored.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation ?? Presentation.Default;\n const { isSheet: sheetPresentation, sheetStyle } = useSheet(presentation);\n // Hover and focus are pointer affordances that open something small next to what caused them;\n // a sheet is a deliberate, screen-owning open. Only a click asks for one.\n const isSheet = sheetPresentation && trigger === PopoverTrigger.Click;\n\n // A sheet isn't anchored to anything, so there's nothing to track, flip or clamp.\n usePopoverPosition({\n isOpen: !!open && !isSheet,\n placement,\n align,\n offset,\n triggerRef,\n floatingRef,\n panelRef,\n arrowRef: withArrow ? arrowRef : { current: null },\n matchTriggerWidth: width === 'trigger',\n });\n\n // Registered for as long as it's open, not just as a sheet: this is what puts the popover on\n // the overlay stack, so an enclosing Modal knows something sits above it and neither drags\n // focus out of this (portaled, so outside the modal's panel) panel nor closes itself on the\n // Escape meant for this. Focus isn't trapped: a Popover is deliberately non-modal, and it\n // already moves focus into the panel on open by itself.\n useOverlay({\n isActive: !!open,\n containerRef: panelRef,\n onEscape: closeOnEscape\n ? () => {\n // Hand focus back to the trigger when it currently sits inside the panel.\n if (floatingRef.current?.contains(document.activeElement)) {\n (tabbablesIn(triggerRef.current)[0] ?? triggerRef.current)?.focus();\n }\n setOpen(false, true);\n }\n : undefined,\n trapFocus: false,\n lockScroll: isSheet,\n });\n\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({\n triggerRef,\n contentRef: floatingRef,\n });\n\n // The panel is portaled to the end of the DOM, so Tab never flows into it naturally. When we\n // manage focus (click trigger + focusable content), move focus in on open and, on Tab out of\n // either end, close and continue focus as if the panel sat right after the trigger.\n useEffect(() => {\n if (!open) {\n openedByKeyboardRef.current = false;\n return;\n }\n const takeFocus = focusOnOpen === true || (focusOnOpen === 'keyboard' && openedByKeyboardRef.current);\n if (!takeFocus || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n // Only claim the dialog role when we're actually managing focus for real content.\n floatingRef.current?.setAttribute('role', 'dialog');\n focusables[0].focus();\n }, [open, trigger, focusOnOpen]);\n\n function handleFloatingKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'Tab' || trigger !== PopoverTrigger.Click) return;\n const focusables = tabbablesIn(panelRef.current);\n if (focusables.length === 0) return;\n const active = document.activeElement;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusAfterTrigger();\n setOpen(false, true);\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n restoreFocusToTrigger();\n setOpen(false, true);\n }\n }\n\n // Outside click. Registered only while open and only for the relevant trigger mode; Escape is\n // handled by `useOverlay` above, which scopes it to the innermost open layer.\n useEffect(() => {\n if (!open) return;\n\n function onMouseUp(event: MouseEvent) {\n // Read and clear: the flag describes this one event, and the panel's React\n // handler has already run by the time this does.\n const inPanelSubtree = panelInteractedRef.current;\n panelInteractedRef.current = false;\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n const inTrigger = triggerRef.current?.contains(target);\n if (!inPanelSubtree && !inPanel && !inTrigger) setOpen(false);\n }\n // Keyboard counterpart to the outside click: once focus leaves both the trigger\n // and the (portaled) panel — e.g. tabbing on to the next element — close.\n function onFocusIn(event: FocusEvent) {\n const inPanelSubtree = panelInteractedRef.current;\n panelInteractedRef.current = false;\n const target = event.target as Node;\n const inPanel = floatingRef.current?.contains(target);\n const inTrigger = triggerRef.current?.contains(target);\n if (!inPanelSubtree && !inPanel && !inTrigger) setOpen(false, true);\n }\n\n if (closeOnOutsideClick && trigger !== PopoverTrigger.Hover) {\n window.addEventListener('mouseup', onMouseUp);\n document.addEventListener('focusin', onFocusIn);\n }\n return () => {\n window.removeEventListener('mouseup', onMouseUp);\n document.removeEventListener('focusin', onFocusIn);\n };\n }, [open, closeOnOutsideClick, trigger, setOpen]);\n\n useEffect(() => () => clearTimeout(hoverTimer.current), []);\n\n function scheduleHover(next: boolean) {\n clearTimeout(hoverTimer.current);\n hoverTimer.current = setTimeout(() => setOpen(next), next ? openDelay : closeDelay);\n }\n\n // Opening from the keyboard without the trigger having to be a button that\n // happens to toggle on Enter: the arrow keys are what the menu-button pattern\n // asks for, and what a consumer reaches for first.\n function handleTriggerKeyDown(event: React.KeyboardEvent) {\n if (open || (event.key !== 'ArrowDown' && event.key !== 'ArrowUp')) return;\n event.preventDefault();\n setOpen(true, true);\n }\n\n const triggerHandlers =\n trigger === PopoverTrigger.Click\n ? {\n onClick: (event: React.MouseEvent) => {\n // A field that opens a picker keeps it open when clicked again, so\n // that placing the caret in the field does not close the panel.\n if (open && !closeOnTriggerClick) return;\n setOpen(!open, event.detail === 0);\n },\n onKeyDown: handleTriggerKeyDown,\n }\n : trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : { onFocus: () => setOpen(true), onBlur: () => setOpen(false) };\n\n const floatingHoverHandlers =\n trigger === PopoverTrigger.Hover\n ? { onMouseEnter: () => scheduleHover(true), onMouseLeave: () => scheduleHover(false) }\n : {};\n\n return (\n <div\n {...rest}\n className={cx(styles.popover, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <div\n ref={triggerRef}\n className={cx(styles.popoverTrigger, classNames?.trigger)}\n style={slotStyles?.trigger}\n {...triggerHandlers}\n >\n {children}\n </div>\n {open && (\n <BodyEnd>\n {isSheet && (\n <SheetBackdrop\n onClose={() => {\n if (closeOnOutsideClick) setOpen(false);\n }}\n className={classNames?.backdrop}\n style={slotStyles?.backdrop}\n />\n )}\n <div\n ref={floatingRef}\n className={cx(isSheet ? sheetStyles.sheet : styles.popoverFloating, classNames?.floating)}\n style={{ ...(isSheet ? sheetStyle : undefined), ...slotStyles?.floating }}\n data-placement={placement}\n onKeyDown={handleFloatingKeyDown}\n onMouseUpCapture={markPanelInteraction}\n onFocusCapture={markPanelInteraction}\n {...floatingHoverHandlers}\n >\n <div\n ref={panelRef}\n className={cx(\n styles.popoverPanel,\n constrainWidth && styles.popoverPanelConstrained,\n isSheet && sheetStyles.sheetPanel,\n classNames?.panel,\n )}\n style={slotStyles?.panel}\n >\n {content}\n </div>\n {withArrow && !isSheet && (\n <div ref={arrowRef} className={cx(styles.popoverArrow, classNames?.arrow)} style={slotStyles?.arrow} />\n )}\n </div>\n </BodyEnd>\n )}\n </div>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var e=`popover_hhmvN`,t=`popover-trigger_R4ckf`,n=`popover-floating_mhXrQ`,r=`popover-panel_tVB2k`,i=`popoverIn_nKOqX`,a=`popover-arrow_B8kB-`,o={popover:e,"popover-trigger":`popover-trigger_R4ckf`,popoverTrigger:t,"popover-floating":`popover-floating_mhXrQ`,popoverFloating:n,"popover-panel":`popover-panel_tVB2k`,popoverPanel:r,popoverIn:i,"popover-arrow":`popover-arrow_B8kB-`,popoverArrow:a};export{o as default,e as popover,a as popoverArrow,n as popoverFloating,i as popoverIn,r as popoverPanel,t as popoverTrigger};
1
+ var e=`popover_hhmvN`,t=`popover-trigger_R4ckf`,n=`popover-floating_mhXrQ`,r=`popover-panel_tVB2k`,i=`popover-panel-constrained_DFXWP`,a=`popoverIn_nKOqX`,o=`popover-arrow_B8kB-`,s={popover:e,"popover-trigger":`popover-trigger_R4ckf`,popoverTrigger:t,"popover-floating":`popover-floating_mhXrQ`,popoverFloating:n,"popover-panel":`popover-panel_tVB2k`,popoverPanel:r,"popover-panel-constrained":`popover-panel-constrained_DFXWP`,popoverPanelConstrained:i,popoverIn:a,"popover-arrow":`popover-arrow_B8kB-`,popoverArrow:o};export{s as default,e as popover,o as popoverArrow,n as popoverFloating,a as popoverIn,r as popoverPanel,i as popoverPanelConstrained,t as popoverTrigger};
2
2
  //# sourceMappingURL=popover.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.module.mjs","names":[],"sources":["../../../../package/common/popover/popover.module.pcss"],"sourcesContent":[".popover {\n position: relative;\n display: inline-flex;\n\n &-trigger {\n display: inline-flex;\n }\n\n &-floating {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1000;\n\n /* Hidden until usePopoverPosition writes the first coordinates, to avoid a top-left flash. */\n visibility: hidden;\n }\n\n &-panel {\n position: relative;\n\n /* Above the arrow so the panel background hides the arrow's inner half — only the\n tip pokes out past the panel edge. */\n z-index: 1;\n color: var(--text-color);\n font-family: var(--default-font);\n font-size: var(--default-font-size);\n background: var(--background-modal);\n box-shadow: var(--card-shadow);\n border-radius: calc(var(--default-border-radius) + 4px);\n padding: 12px 14px;\n max-width: min(320px, calc(100vw - 24px));\n animation: popoverIn 0.12s ease forwards;\n }\n\n &-arrow {\n position: absolute;\n width: 10px;\n height: 10px;\n background: var(--background-modal);\n box-shadow: var(--card-shadow);\n transform: rotate(45deg);\n }\n\n /* Arrow sits on the panel edge facing the trigger; --arrow-x / --arrow-y centre it on the trigger. */\n &-floating[data-placement='bottom'] &-arrow {\n top: -5px;\n left: var(--arrow-x, 50%);\n margin-left: -5px;\n }\n\n &-floating[data-placement='top'] &-arrow {\n bottom: -5px;\n left: var(--arrow-x, 50%);\n margin-left: -5px;\n }\n\n &-floating[data-placement='right'] &-arrow {\n left: -5px;\n top: var(--arrow-y, 50%);\n margin-top: -5px;\n }\n\n &-floating[data-placement='left'] &-arrow {\n right: -5px;\n top: var(--arrow-y, 50%);\n margin-top: -5px;\n }\n\n /* Grow from the edge nearest the trigger. */\n &-floating[data-placement='bottom'] &-panel {\n transform-origin: top center;\n }\n\n &-floating[data-placement='top'] &-panel {\n transform-origin: bottom center;\n }\n\n &-floating[data-placement='right'] &-panel {\n transform-origin: center left;\n }\n\n &-floating[data-placement='left'] &-panel {\n transform-origin: center right;\n }\n\n @keyframes popoverIn {\n from {\n opacity: 0;\n transform: scale(0.94);\n }\n\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"popover.module.mjs","names":[],"sources":["../../../../package/common/popover/popover.module.pcss"],"sourcesContent":["/* Neither of these two generates a box, so the trigger lands in the consumer's\n layout exactly as if Popover were not around it: it is the flex item, the grid\n item, the block-level child. A field that fills its column still fills it, a\n short button is still only as wide as itself, and a row that stretches its\n children reaches the trigger instead of stopping at a wrapper around it. They\n stay in the event path, so the handlers on them still fire, and\n `usePopoverPosition` already looks past boxless wrappers for its anchor.\n\n Every box we tried here was wrong in one direction or the other. A wrapper that\n spans its container opens the panel from the empty space beside a short button.\n `width: fit-content` collapses a field whose own width is a percentage of its\n parent. A flex root stretches the trigger's height but sizes its width by\n content, which collapsed KlipyPicker's search field.\n\n The cost is that `className`, `style` and `classNames.root` cannot paint\n anything on these two, because there is nothing to paint on. */\n.popover {\n display: contents;\n\n &-trigger {\n display: contents;\n }\n\n &-floating {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1;\n\n /* Hidden until usePopoverPosition writes the first coordinates, to avoid a top-left flash. */\n visibility: hidden;\n }\n\n &-panel {\n position: relative;\n\n /* Above the arrow so the panel background hides the arrow's inner half — only the\n tip pokes out past the panel edge. */\n z-index: 1;\n color: var(--text-color);\n font-family: var(--default-font);\n font-size: var(--default-font-size);\n background: var(--background-modal);\n box-shadow: var(--card-shadow);\n border-radius: calc(var(--default-border-radius) + 4px);\n padding: 12px 14px;\n\n /* A readable measure for a popover of text. A panel that brings its own\n width — a calendar, a media grid — turns it off with `constrainWidth`.\n `.sheet-panel` overrides this by name for the sheet path; check there\n before touching the cap. */\n &-constrained {\n max-width: min(320px, calc(100vw - 24px));\n }\n\n animation: popoverIn 0.12s ease-out forwards;\n }\n\n &-arrow {\n position: absolute;\n width: 10px;\n height: 10px;\n background: var(--background-modal);\n box-shadow: var(--card-shadow);\n transform: rotate(45deg);\n }\n\n /* Arrow sits on the panel edge facing the trigger; --arrow-x / --arrow-y centre it on the trigger. */\n &-floating[data-placement='bottom'] &-arrow {\n top: -5px;\n left: var(--arrow-x, 50%);\n margin-left: -5px;\n }\n\n &-floating[data-placement='top'] &-arrow {\n bottom: -5px;\n left: var(--arrow-x, 50%);\n margin-left: -5px;\n }\n\n &-floating[data-placement='right'] &-arrow {\n left: -5px;\n top: var(--arrow-y, 50%);\n margin-top: -5px;\n }\n\n &-floating[data-placement='left'] &-arrow {\n right: -5px;\n top: var(--arrow-y, 50%);\n margin-top: -5px;\n }\n\n /* Grow from the edge nearest the trigger. */\n &-floating[data-placement='bottom'] &-panel {\n transform-origin: top center;\n }\n\n &-floating[data-placement='top'] &-panel {\n transform-origin: bottom center;\n }\n\n &-floating[data-placement='right'] &-panel {\n transform-origin: center left;\n }\n\n &-floating[data-placement='left'] &-panel {\n transform-origin: center right;\n }\n\n @keyframes popoverIn {\n from {\n opacity: 0.4;\n transform: scale(0.7);\n }\n\n to {\n opacity: 1;\n transform: scale(1);\n }\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .popover-panel {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"popover.types.mjs","names":[],"sources":["../../../../package/common/popover/popover.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\nimport type { Presentation } from '../floatingMenu/floatingMenu.types';\n\n/** Preferred side of the trigger the panel opens on. Flips to the opposite side when there's no room. */\nexport enum PopoverPlacement {\n Top = 'top',\n Bottom = 'bottom',\n Left = 'left',\n Right = 'right',\n}\n\n/** Alignment along the trigger's cross axis (horizontal for top/bottom, vertical for left/right). */\nexport enum PopoverAlign {\n Start = 'start',\n Center = 'center',\n End = 'end',\n}\n\n/** What opens the popover. */\nexport enum PopoverTrigger {\n Click = 'click',\n Hover = 'hover',\n Focus = 'focus',\n}\n\nexport type PopoverSlots = 'root' | 'trigger' | 'floating' | 'panel' | 'arrow' | 'backdrop';\n\nexport interface PopoverProps extends Omit<HtmlProps, 'content'> {\n /** The trigger element. */\n children?: ReactNode;\n /** The popover body. */\n content?: ReactNode;\n /** Preferred side (default `Bottom`). */\n placement?: PopoverPlacement;\n /** Cross-axis alignment (default `Center`). */\n align?: PopoverAlign;\n /** What opens the popover (default `Click`). */\n trigger?: PopoverTrigger;\n /** Controlled open state. Omit for uncontrolled. */\n isOpen?: boolean;\n /** Initial open state when uncontrolled (default `false`). */\n defaultOpen?: boolean;\n /** Fires whenever the popover wants to open or close. */\n onOpenChange?: (isOpen: boolean) => void;\n /** Gap in px between trigger and panel (default `10`). */\n offset?: number;\n /** Render the arrow pointing at the trigger (default `true`). */\n withArrow?: boolean;\n /** Close when clicking outside the panel (default `true`). */\n closeOnOutsideClick?: boolean;\n /** Close when pressing Escape (default `true`). */\n closeOnEscape?: boolean;\n /** Delay in ms before a hover-triggered popover opens (default `100`). */\n openDelay?: number;\n /** Delay in ms before a hover-triggered popover closes (default `120`). */\n closeDelay?: number;\n /** Prevent the popover from opening. */\n disabled?: boolean;\n /** Where the panel opens: anchored to the trigger (`Default`), pinned to the bottom of the\n * screen, or the latter only on a small touch screen. Only a `Click` trigger presents as a\n * sheet. */\n presentation?: Presentation;\n\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<PopoverSlots>;\n styles?: SlotStyles<PopoverSlots>;\n}\n"],"mappings":"AAKA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,IAAA,MACA,EAAA,OAAA,SACA,EAAA,KAAA,OACA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA,EAGY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QACA,EAAA,OAAA,SACA,EAAA,IAAA,OACF,EAAA,CAAA,CAAA,EAGY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QACA,EAAA,MAAA,QACA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"popover.types.mjs","names":[],"sources":["../../../../package/common/popover/popover.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\nimport type { Presentation } from '../configProvider/presentation.types';\n\n/** Preferred side of the trigger the panel opens on. Flips to the opposite side when there's no room. */\nexport enum PopoverPlacement {\n Top = 'top',\n Bottom = 'bottom',\n Left = 'left',\n Right = 'right',\n}\n\n/** Alignment along the trigger's cross axis (horizontal for top/bottom, vertical for left/right). */\nexport enum PopoverAlign {\n Start = 'start',\n Center = 'center',\n End = 'end',\n}\n\n/** What opens the popover. */\nexport enum PopoverTrigger {\n Click = 'click',\n Hover = 'hover',\n Focus = 'focus',\n}\n\nexport type PopoverSlots = 'root' | 'trigger' | 'floating' | 'panel' | 'arrow' | 'backdrop';\n\nexport interface PopoverProps extends Omit<HtmlProps, 'content'> {\n /** The trigger element. */\n children?: ReactNode;\n /** The popover body. */\n content?: ReactNode;\n /** Preferred side (default `Bottom`). */\n placement?: PopoverPlacement;\n /** Cross-axis alignment (default `Center`). */\n align?: PopoverAlign;\n /** What opens the popover (default `Click`). */\n trigger?: PopoverTrigger;\n /** Controlled open state. Omit for uncontrolled. */\n isOpen?: boolean;\n /** Initial open state when uncontrolled (default `false`). */\n defaultOpen?: boolean;\n /**\n * Fires whenever the popover wants to open or close. `fromKeyboard` says\n * whether a key caused it, which is what a menu needs in order to put the\n * focus on an entry only when the pointer was not what opened it.\n */\n onOpenChange?: (isOpen: boolean, meta: { fromKeyboard: boolean }) => void;\n /** Gap in px between trigger and panel (default `10`). */\n offset?: number;\n /** Render the arrow pointing at the trigger (default `true`). */\n withArrow?: boolean;\n /** Close when clicking outside the panel (default `true`). */\n closeOnOutsideClick?: boolean;\n /** Close when pressing Escape (default `true`). */\n closeOnEscape?: boolean;\n /** Delay in ms before a hover-triggered popover opens (default `100`). */\n openDelay?: number;\n /** Delay in ms before a hover-triggered popover closes (default `120`). */\n closeDelay?: number;\n /** Prevent the popover from opening. */\n disabled?: boolean;\n /**\n * Move focus into the panel when it opens, and claim `role=\"dialog\"` with it.\n * `'keyboard'` (the default) does it only when the open came from the\n * keyboard: the panel is portaled to the end of the document, so Tab never\n * reaches it on its own, while a click leaves the focus where the pointer\n * already put it. `true` always, `false` never.\n */\n focusOnOpen?: boolean | 'keyboard';\n /**\n * Whether clicking the trigger while the panel is open closes it (default\n * `true`). A menu button should toggle; a text field that opens a picker\n * should not, or clicking into it to place the caret would close the panel.\n */\n closeOnTriggerClick?: boolean;\n /**\n * `'trigger'` gives the panel at least the trigger's width, for a list that\n * should line up with the field it belongs to. `'auto'` (the default) lets it\n * size to its own content.\n */\n width?: 'auto' | 'trigger';\n /**\n * Cap the panel at a readable measure (default `true`). Off for a panel with\n * its own width, a calendar or a media grid.\n */\n constrainWidth?: boolean;\n /** Where the panel opens: anchored to the trigger (`Default`), pinned to the bottom of the\n * screen, or the latter only on a small touch screen. Only a `Click` trigger presents as a\n * sheet. */\n presentation?: Presentation;\n\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<PopoverSlots>;\n styles?: SlotStyles<PopoverSlots>;\n}\n"],"mappings":"AAKA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,IAAA,MACA,EAAA,OAAA,SACA,EAAA,KAAA,OACA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA,EAGY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QACA,EAAA,OAAA,SACA,EAAA,IAAA,OACF,EAAA,CAAA,CAAA,EAGY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QACA,EAAA,MAAA,QACA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA"}
@@ -1,2 +1,2 @@
1
- import{isHiddenByAnyAncestor as e}from"../utils/scrollAncestors.mjs";import{getVisualViewportRect as t}from"../utils/visualViewport.mjs";import{useAnchorTracking as n}from"../hooks/useAnchorTracking.mjs";import{PopoverAlign as r,PopoverPlacement as i}from"./popover.types.mjs";var a={[i.Top]:`bottom`,[i.Bottom]:`top`,[i.Left]:`right`,[i.Right]:`left`},o=8;function s({isOpen:s,placement:c,align:l,offset:u,triggerRef:d,floatingRef:f,panelRef:p,arrowRef:m}){n({isOpen:s,triggerRef:d,elementRefs:[f,p],resizeRefs:[p],deps:[c,l,u,f,p,m],update:(n,s)=>{let d=f.current,h=p.current;if(!d||!h)return;let g=n.getBoundingClientRect(),_=h.offsetWidth,v=h.offsetHeight,y=t(),b={top:g.top-y.top,bottom:y.top+y.height-g.bottom,left:g.left-y.left,right:y.left+y.width-g.right},x=c===i.Top||c===i.Bottom?v:_,S=c,C=a[c];b[S]<x+u&&b[C]>b[S]&&(S=C);let w=S===`top`||S===`bottom`,T,E;S===`bottom`?T=g.bottom+u:S===`top`?T=g.top-u-v:E=S===`right`?g.right+u:g.left-u-_,w?(E=l===r.Start?g.left:l===r.End?g.right-_:g.left+g.width/2-_/2,E=Math.max(y.left+o,Math.min(E,y.left+y.width-_-o))):(T=l===r.Start?g.top:l===r.End?g.bottom-v:g.top+g.height/2-v/2,T=Math.max(y.top+o,Math.min(T,y.top+y.height-v-o))),d.style.top=`${T}px`,d.style.left=`${E}px`,d.style.visibility=e(g,s)?`hidden`:`visible`,d.dataset.placement=S;let D=m.current;if(D){let e=D.offsetWidth/2||5;if(w){let t=g.left+g.width/2-E;D.style.setProperty(`--arrow-x`,`${Math.max(e+2,Math.min(t,_-e-2))}px`),D.style.removeProperty(`--arrow-y`)}else{let t=g.top+g.height/2-T;D.style.setProperty(`--arrow-y`,`${Math.max(e+2,Math.min(t,v-e-2))}px`),D.style.removeProperty(`--arrow-x`)}}},teardown:()=>{let e=f.current;e&&(e.style.top=``,e.style.left=``,e.style.visibility=``)}})}export{s as usePopoverPosition};
1
+ import{isHiddenByAnyAncestor as e}from"../utils/scrollAncestors.mjs";import{getVisualViewportRect as t}from"../utils/visualViewport.mjs";import{useAnchorTracking as n}from"../hooks/useAnchorTracking.mjs";import{PopoverAlign as r,PopoverPlacement as i}from"./popover.types.mjs";var a={[i.Top]:`bottom`,[i.Bottom]:`top`,[i.Left]:`right`,[i.Right]:`left`},o=8,s=160,c=3;function l(e){let t=e;for(let e=0;e<=c;e++){let e=t.getBoundingClientRect();if(e.width>0||e.height>0)return e;let n=t.firstElementChild;if(!n)break;t=n}return e.getBoundingClientRect()}function u({isOpen:c,placement:u,align:d,offset:f,triggerRef:p,floatingRef:m,panelRef:h,arrowRef:g,matchTriggerWidth:_=!1,shrinkToFit:v=!1}){n({isOpen:c,triggerRef:p,elementRefs:[m,h],resizeRefs:[h],deps:[u,d,f,m,h,g,_,v],update:(n,c)=>{let p=m.current,y=h.current;if(!p||!y)return;let b=l(n);_?y.style.minWidth=`${b.width}px`:y.style.removeProperty(`min-width`),v&&y.style.removeProperty(`max-width`);let{width:x,height:S}=p.getBoundingClientRect(),C=t(),w=u===i.Top||u===i.Bottom;if(v&&w){let e=d===r.End?b.right-(C.left+o):d===r.Start?C.left+C.width-o-b.left:C.width-16,t=Math.min(e,C.width-16);x>t&&t>=s&&(y.style.maxWidth=`${t}px`,{width:x,height:S}=p.getBoundingClientRect())}let T={top:b.top-C.top,bottom:C.top+C.height-b.bottom,left:b.left-C.left,right:C.left+C.width-b.right},E=u===i.Top||u===i.Bottom?S:x,D=u,O=a[u];T[D]<E+f&&T[O]>T[D]&&(D=O);let k=D===`top`||D===`bottom`,A,j;D===`bottom`?A=b.bottom+f:D===`top`?A=b.top-f-S:j=D===`right`?b.right+f:b.left-f-x,k?(j=d===r.Start?b.left:d===r.End?b.right-x:b.left+b.width/2-x/2,j=Math.max(C.left+o,Math.min(j,C.left+C.width-x-o))):(A=d===r.Start?b.top:d===r.End?b.bottom-S:b.top+b.height/2-S/2,A=Math.max(C.top+o,Math.min(A,C.top+C.height-S-o))),p.style.top=`${A}px`,p.style.left=`${j}px`,p.style.visibility=e(b,c)?`hidden`:`visible`,p.dataset.placement=D;let M=g.current;if(M){let e=M.offsetWidth/2||5;if(k){let t=b.left+b.width/2-j;M.style.setProperty(`--arrow-x`,`${Math.max(e+2,Math.min(t,x-e-2))}px`),M.style.removeProperty(`--arrow-y`)}else{let t=b.top+b.height/2-A;M.style.setProperty(`--arrow-y`,`${Math.max(e+2,Math.min(t,S-e-2))}px`),M.style.removeProperty(`--arrow-x`)}}},teardown:()=>{let e=m.current;if(!e)return;e.style.top=``,e.style.left=``,e.style.visibility=``;let t=h.current;t?.style.removeProperty(`min-width`),t?.style.removeProperty(`max-width`)}})}export{u as usePopoverPosition};
2
2
  //# sourceMappingURL=usePopoverPosition.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePopoverPosition.mjs","names":[],"sources":["../../../../package/common/popover/usePopoverPosition.ts"],"sourcesContent":["import { type RefObject } from 'react';\nimport { isHiddenByAnyAncestor } from 'components/common/utils/scrollAncestors';\nimport { getVisualViewportRect } from 'components/common/utils/visualViewport';\nimport { useAnchorTracking } from '../hooks/useAnchorTracking';\nimport { PopoverPlacement, PopoverAlign } from './popover.types';\n\ntype Axis = 'top' | 'bottom' | 'left' | 'right';\nconst OPPOSITE: Record<PopoverPlacement, Axis> = {\n [PopoverPlacement.Top]: 'bottom',\n [PopoverPlacement.Bottom]: 'top',\n [PopoverPlacement.Left]: 'right',\n [PopoverPlacement.Right]: 'left',\n};\n\nconst MARGIN = 8; // viewport gutter kept clear when shifting a panel back on-screen\n\nexport interface UsePopoverPositionArgs {\n isOpen: boolean;\n placement: PopoverPlacement;\n align: PopoverAlign;\n offset: number;\n triggerRef: RefObject<HTMLElement | null>;\n /** `position: fixed` wrapper that receives top/left/visibility and the resolved-placement data attribute. */\n floatingRef: RefObject<HTMLElement | null>;\n /** Visible panel, measured to decide flip and shift. */\n panelRef: RefObject<HTMLElement | null>;\n /** Arrow element; gets `--arrow-x` / `--arrow-y` written to it. Pass a null ref when `withArrow` is false. */\n arrowRef: RefObject<HTMLElement | null>;\n}\n\n/**\n * Positions a portaled, `position: fixed` popover on any of the four sides of its trigger with\n * start/center/end cross-axis alignment. Flips to the opposite side when the preferred one has no\n * room, shifts back on-screen along the cross axis, points the arrow at the trigger centre, and\n * hides (not closes) the panel once the trigger scrolls behind a clipping ancestor.\n *\n * `useAnchorTracking` supplies the lifecycle around this: mount wait, ancestor resolution, and\n * re-running on scroll, viewport resize and panel size changes.\n */\nexport function usePopoverPosition({\n isOpen,\n placement,\n align,\n offset,\n triggerRef,\n floatingRef,\n panelRef,\n arrowRef,\n}: UsePopoverPositionArgs) {\n useAnchorTracking({\n isOpen,\n triggerRef,\n elementRefs: [floatingRef, panelRef],\n // The panel's own size feeds the flip decision and, on the `top`/`left` sides, the coordinate\n // itself — so content that resizes while open has to be re-measured.\n resizeRefs: [panelRef],\n deps: [placement, align, offset, floatingRef, panelRef, arrowRef],\n\n update: (trigger, ancestors) => {\n const floating = floatingRef.current;\n const panel = panelRef.current;\n if (!floating || !panel) return;\n\n const t = trigger.getBoundingClientRect();\n const pw = panel.offsetWidth;\n const ph = panel.offsetHeight;\n // The visible area, not the full layout viewport — shrinks on mobile when a keyboard is\n // open, so the panel flips/clamps against what's actually on screen instead of ending up\n // hidden behind the keyboard.\n const vv = getVisualViewportRect();\n\n // Resolve the main-axis side, flipping when the preferred side lacks room and the\n // opposite side has more.\n const room: Record<Axis, number> = {\n top: t.top - vv.top,\n bottom: vv.top + vv.height - t.bottom,\n left: t.left - vv.left,\n right: vv.left + vv.width - t.right,\n };\n const need = placement === PopoverPlacement.Top || placement === PopoverPlacement.Bottom ? ph : pw;\n let side: Axis = placement as unknown as Axis;\n const opp = OPPOSITE[placement];\n if (room[side] < need + offset && room[opp] > room[side]) side = opp;\n\n const vertical = side === 'top' || side === 'bottom';\n\n // Main axis: place the panel just outside the trigger on the resolved side.\n let top: number;\n let left: number;\n if (side === 'bottom') {\n top = t.bottom + offset;\n } else if (side === 'top') {\n top = t.top - offset - ph;\n } else if (side === 'right') {\n left = t.right + offset;\n } else {\n left = t.left - offset - pw;\n }\n\n // Cross axis: align start/center/end against the trigger, then shift on-screen.\n if (vertical) {\n if (align === PopoverAlign.Start) left = t.left;\n else if (align === PopoverAlign.End) left = t.right - pw;\n else left = t.left + t.width / 2 - pw / 2;\n left = Math.max(vv.left + MARGIN, Math.min(left!, vv.left + vv.width - pw - MARGIN));\n } else {\n if (align === PopoverAlign.Start) top = t.top;\n else if (align === PopoverAlign.End) top = t.bottom - ph;\n else top = t.top + t.height / 2 - ph / 2;\n top = Math.max(vv.top + MARGIN, Math.min(top!, vv.top + vv.height - ph - MARGIN));\n }\n\n floating.style.top = `${top!}px`;\n floating.style.left = `${left!}px`;\n floating.style.visibility = isHiddenByAnyAncestor(t, ancestors) ? 'hidden' : 'visible';\n floating.dataset.placement = side;\n\n // Arrow: centre it on the trigger along the cross axis, clamped inside the panel edges.\n const arrow = arrowRef.current;\n if (arrow) {\n const half = arrow.offsetWidth / 2 || 5;\n if (vertical) {\n const x = t.left + t.width / 2 - left!;\n arrow.style.setProperty('--arrow-x', `${Math.max(half + 2, Math.min(x, pw - half - 2))}px`);\n arrow.style.removeProperty('--arrow-y');\n } else {\n const y = t.top + t.height / 2 - top!;\n arrow.style.setProperty('--arrow-y', `${Math.max(half + 2, Math.min(y, ph - half - 2))}px`);\n arrow.style.removeProperty('--arrow-x');\n }\n }\n },\n\n teardown: () => {\n // Positioning is written as inline styles, which outrank any class the panel might\n // switch to while it stays mounted — a popover turning into a bottom sheet (`useSheet`)\n // would keep the coordinates computed for its anchored self.\n const floating = floatingRef.current;\n if (!floating) return;\n floating.style.top = '';\n floating.style.left = '';\n floating.style.visibility = '';\n },\n });\n}\n"],"mappings":"qRAOA,IAAM,EAA2C,EAC9C,EAAiB,KAAM,UACvB,EAAiB,QAAS,OAC1B,EAAiB,MAAO,SACxB,EAAiB,OAAQ,MAC5B,EAEM,EAAS,EAyBf,SAAgB,EAAmB,CACjC,SACA,YACA,QACA,SACA,aACA,cACA,WACA,YACyB,CACzB,EAAkB,CAChB,SACA,aACA,YAAa,CAAC,EAAa,CAAQ,EAGnC,WAAY,CAAC,CAAQ,EACrB,KAAM,CAAC,EAAW,EAAO,EAAQ,EAAa,EAAU,CAAQ,EAEhE,QAAS,EAAS,IAAc,CAC9B,IAAM,EAAW,EAAY,QACvB,EAAQ,EAAS,QACvB,GAAI,CAAC,GAAY,CAAC,EAAO,OAEzB,IAAM,EAAI,EAAQ,sBAAsB,EAClC,EAAK,EAAM,YACX,EAAK,EAAM,aAIX,EAAK,EAAsB,EAI3B,EAA6B,CACjC,IAAK,EAAE,IAAM,EAAG,IAChB,OAAQ,EAAG,IAAM,EAAG,OAAS,EAAE,OAC/B,KAAM,EAAE,KAAO,EAAG,KAClB,MAAO,EAAG,KAAO,EAAG,MAAQ,EAAE,KAChC,EACM,EAAO,IAAc,EAAiB,KAAO,IAAc,EAAiB,OAAS,EAAK,EAC5F,EAAa,EACX,EAAM,EAAS,GACjB,EAAK,GAAQ,EAAO,GAAU,EAAK,GAAO,EAAK,KAAO,EAAO,GAEjE,IAAM,EAAW,IAAS,OAAS,IAAS,SAGxC,EACA,EACA,IAAS,SACX,EAAM,EAAE,OAAS,EACR,IAAS,MAClB,EAAM,EAAE,IAAM,EAAS,EAClB,AAGL,EAHS,IAAS,QACX,EAAE,MAAQ,EAEV,EAAE,KAAO,EAAS,EAIvB,GACF,AAEK,EAFD,IAAU,EAAa,MAAc,EAAE,KAClC,IAAU,EAAa,IAAY,EAAE,MAAQ,EAC1C,EAAE,KAAO,EAAE,MAAQ,EAAI,EAAK,EACxC,EAAO,KAAK,IAAI,EAAG,KAAO,EAAQ,KAAK,IAAI,EAAO,EAAG,KAAO,EAAG,MAAQ,EAAK,CAAM,CAAC,IAEnF,AAEK,EAFD,IAAU,EAAa,MAAa,EAAE,IACjC,IAAU,EAAa,IAAW,EAAE,OAAS,EAC3C,EAAE,IAAM,EAAE,OAAS,EAAI,EAAK,EACvC,EAAM,KAAK,IAAI,EAAG,IAAM,EAAQ,KAAK,IAAI,EAAM,EAAG,IAAM,EAAG,OAAS,EAAK,CAAM,CAAC,GAGlF,EAAS,MAAM,IAAM,GAAG,EAAK,IAC7B,EAAS,MAAM,KAAO,GAAG,EAAM,IAC/B,EAAS,MAAM,WAAa,EAAsB,EAAG,CAAS,EAAI,SAAW,UAC7E,EAAS,QAAQ,UAAY,EAG7B,IAAM,EAAQ,EAAS,QACvB,GAAI,EAAO,CACT,IAAM,EAAO,EAAM,YAAc,GAAK,EACtC,GAAI,EAAU,CACZ,IAAM,EAAI,EAAE,KAAO,EAAE,MAAQ,EAAI,EACjC,EAAM,MAAM,YAAY,YAAa,GAAG,KAAK,IAAI,EAAO,EAAG,KAAK,IAAI,EAAG,EAAK,EAAO,CAAC,CAAC,EAAE,GAAG,EAC1F,EAAM,MAAM,eAAe,WAAW,CACxC,KAAO,CACL,IAAM,EAAI,EAAE,IAAM,EAAE,OAAS,EAAI,EACjC,EAAM,MAAM,YAAY,YAAa,GAAG,KAAK,IAAI,EAAO,EAAG,KAAK,IAAI,EAAG,EAAK,EAAO,CAAC,CAAC,EAAE,GAAG,EAC1F,EAAM,MAAM,eAAe,WAAW,CACxC,CACF,CACF,EAEA,aAAgB,CAId,IAAM,EAAW,EAAY,QACxB,IACL,EAAS,MAAM,IAAM,GACrB,EAAS,MAAM,KAAO,GACtB,EAAS,MAAM,WAAa,GAC9B,CACF,CAAC,CACH"}
1
+ {"version":3,"file":"usePopoverPosition.mjs","names":[],"sources":["../../../../package/common/popover/usePopoverPosition.ts"],"sourcesContent":["import { type RefObject } from 'react';\nimport { isHiddenByAnyAncestor } from 'components/common/utils/scrollAncestors';\nimport { getVisualViewportRect } from 'components/common/utils/visualViewport';\nimport { useAnchorTracking } from '../hooks/useAnchorTracking';\nimport { PopoverPlacement, PopoverAlign } from './popover.types';\n\ntype Axis = 'top' | 'bottom' | 'left' | 'right';\nconst OPPOSITE: Record<PopoverPlacement, Axis> = {\n [PopoverPlacement.Top]: 'bottom',\n [PopoverPlacement.Bottom]: 'top',\n [PopoverPlacement.Left]: 'right',\n [PopoverPlacement.Right]: 'left',\n};\n\nconst MARGIN = 8; // viewport gutter kept clear when shifting a panel back on-screen\n\n/**\n * Narrower than this and `shrinkToFit` gives up: a panel this size reads worse than\n * one that overhangs. Around four words a line for an error bubble, which is the\n * narrowest caller. A constant rather than an option, because the one caller that\n * shrinks has no reason to want a different floor; give it one the day a second\n * caller disagrees, as `shrinkToFit: boolean | number`.\n */\nconst MIN_SHRINK_WIDTH = 160;\n\n/** How far down to look for a box when the wrappers in between have none. */\nconst MAX_ANCHOR_DEPTH = 3;\n\n/**\n * The rect to anchor to. A trigger with a box of its own is that box, which is the\n * case for a caller that hands over a real element (`Tooltip`).\n *\n * Popover's own trigger wrapper generates no box, deliberately, so that the\n * trigger keeps the place it would have had without Popover around it. Then the\n * real trigger is inside it, and this descends to find it, past any further\n * boxless element a consumer wrapped its trigger in: such an element has a zero\n * rect at the origin, which would otherwise send the panel to the top-left corner\n * of the screen.\n */\nfunction resolveAnchorRect(trigger: HTMLElement): DOMRect {\n let el: HTMLElement = trigger;\n for (let depth = 0; depth <= MAX_ANCHOR_DEPTH; depth++) {\n const rect = el.getBoundingClientRect();\n if (rect.width > 0 || rect.height > 0) return rect;\n const child = el.firstElementChild as HTMLElement | null;\n if (!child) break;\n el = child;\n }\n return trigger.getBoundingClientRect();\n}\n\nexport interface UsePopoverPositionArgs {\n isOpen: boolean;\n placement: PopoverPlacement;\n align: PopoverAlign;\n offset: number;\n triggerRef: RefObject<HTMLElement | null>;\n /** `position: fixed` wrapper that receives top/left/visibility and the resolved-placement data attribute. */\n floatingRef: RefObject<HTMLElement | null>;\n /** Visible panel, measured to decide flip and shift. */\n panelRef: RefObject<HTMLElement | null>;\n /** Arrow element; gets `--arrow-x` / `--arrow-y` written to it. Pass a null ref when `withArrow` is false. */\n arrowRef: RefObject<HTMLElement | null>;\n /**\n * Give the panel at least the trigger's width, for a list that lines up with\n * the field it belongs to. A minimum rather than a fixed width: a menu on a\n * narrow icon button still sizes to its own content.\n */\n matchTriggerWidth?: boolean;\n /**\n * When the panel does not fit on the side its alignment puts it, narrow it\n * rather than sliding it away from the trigger. Sliding keeps the panel\n * on-screen but detaches it: an end-aligned bubble stops ending where its\n * trigger ends, and its arrow stops pointing at anything. Off by default, since\n * a panel whose width is its content, a menu or a list, would rather overhang\n * its trigger than wrap.\n *\n * Only down to `MIN_SHRINK_WIDTH`. Past that the panel is narrower than it is\n * readable, and a trigger that close to the screen edge is better served by a\n * panel that overhangs it.\n */\n shrinkToFit?: boolean;\n}\n\n/**\n * Positions a portaled, `position: fixed` popover on any of the four sides of its trigger with\n * start/center/end cross-axis alignment. Flips to the opposite side when the preferred one has no\n * room, shifts back on-screen along the cross axis, points the arrow at the trigger centre, and\n * hides (not closes) the panel once the trigger scrolls behind a clipping ancestor.\n *\n * `useAnchorTracking` supplies the lifecycle around this: mount wait, ancestor resolution, and\n * re-running on scroll, viewport resize and panel size changes.\n */\nexport function usePopoverPosition({\n isOpen,\n placement,\n align,\n offset,\n triggerRef,\n floatingRef,\n panelRef,\n arrowRef,\n matchTriggerWidth = false,\n shrinkToFit = false,\n}: UsePopoverPositionArgs) {\n useAnchorTracking({\n isOpen,\n triggerRef,\n elementRefs: [floatingRef, panelRef],\n // The panel's own size feeds the flip decision and, on the `top`/`left` sides, the coordinate\n // itself — so content that resizes while open has to be re-measured.\n resizeRefs: [panelRef],\n deps: [placement, align, offset, floatingRef, panelRef, arrowRef, matchTriggerWidth, shrinkToFit],\n\n update: (trigger, ancestors) => {\n const floating = floatingRef.current;\n const panel = panelRef.current;\n if (!floating || !panel) return;\n\n const t = resolveAnchorRect(trigger);\n // Written before the panel is measured, so `pw` below already accounts for it,\n // and taken back off when it is no longer wanted: the panel outlives the\n // switch, and an inline width would outrank whatever it switched to.\n if (matchTriggerWidth) panel.style.minWidth = `${t.width}px`;\n else panel.style.removeProperty('min-width');\n // The wrapper's box, not the panel's: `offsetWidth` rounds to whole pixels, so\n // aligning a panel 165.4px wide against a trigger edge at 406.47 left it 0.4px\n // past that edge. The panel's own rect is fractional but carries the entrance\n // animation's scale; the wrapper is the same layout box without the transform.\n // Cleared before measuring, or a cap left over from a narrower screen would be\n // read back as the panel's own width and never widen again.\n if (shrinkToFit) panel.style.removeProperty('max-width');\n let { width: pw, height: ph } = floating.getBoundingClientRect();\n // The visible area, not the full layout viewport — shrinks on mobile when a keyboard is\n // open, so the panel flips/clamps against what's actually on screen instead of ending up\n // hidden behind the keyboard.\n const vv = getVisualViewportRect();\n\n // Flipping only swaps a side for its opposite, so which axis the alignment runs\n // along is decided by the preferred placement alone, before any of that.\n const alignsHorizontally = placement === PopoverPlacement.Top || placement === PopoverPlacement.Bottom;\n\n if (shrinkToFit && alignsHorizontally) {\n const alignedSide =\n align === PopoverAlign.End\n ? t.right - (vv.left + MARGIN)\n : align === PopoverAlign.Start\n ? vv.left + vv.width - MARGIN - t.left\n : vv.width - 2 * MARGIN;\n const room = Math.min(alignedSide, vv.width - 2 * MARGIN);\n if (pw > room && room >= MIN_SHRINK_WIDTH) {\n panel.style.maxWidth = `${room}px`;\n // Wrapping makes it taller, and the height is what the flip below is decided on.\n ({ width: pw, height: ph } = floating.getBoundingClientRect());\n }\n }\n\n // Resolve the main-axis side, flipping when the preferred side lacks room and the\n // opposite side has more.\n const room: Record<Axis, number> = {\n top: t.top - vv.top,\n bottom: vv.top + vv.height - t.bottom,\n left: t.left - vv.left,\n right: vv.left + vv.width - t.right,\n };\n const need = placement === PopoverPlacement.Top || placement === PopoverPlacement.Bottom ? ph : pw;\n let side: Axis = placement as unknown as Axis;\n const opp = OPPOSITE[placement];\n if (room[side] < need + offset && room[opp] > room[side]) side = opp;\n\n const vertical = side === 'top' || side === 'bottom';\n\n // Main axis: place the panel just outside the trigger on the resolved side.\n let top: number;\n let left: number;\n if (side === 'bottom') {\n top = t.bottom + offset;\n } else if (side === 'top') {\n top = t.top - offset - ph;\n } else if (side === 'right') {\n left = t.right + offset;\n } else {\n left = t.left - offset - pw;\n }\n\n // Cross axis: align start/center/end against the trigger, then shift on-screen.\n if (vertical) {\n if (align === PopoverAlign.Start) left = t.left;\n else if (align === PopoverAlign.End) left = t.right - pw;\n else left = t.left + t.width / 2 - pw / 2;\n left = Math.max(vv.left + MARGIN, Math.min(left!, vv.left + vv.width - pw - MARGIN));\n } else {\n if (align === PopoverAlign.Start) top = t.top;\n else if (align === PopoverAlign.End) top = t.bottom - ph;\n else top = t.top + t.height / 2 - ph / 2;\n top = Math.max(vv.top + MARGIN, Math.min(top!, vv.top + vv.height - ph - MARGIN));\n }\n\n floating.style.top = `${top!}px`;\n floating.style.left = `${left!}px`;\n floating.style.visibility = isHiddenByAnyAncestor(t, ancestors) ? 'hidden' : 'visible';\n floating.dataset.placement = side;\n\n // Arrow: centre it on the trigger along the cross axis, clamped inside the panel edges.\n const arrow = arrowRef.current;\n if (arrow) {\n const half = arrow.offsetWidth / 2 || 5;\n if (vertical) {\n const x = t.left + t.width / 2 - left!;\n arrow.style.setProperty('--arrow-x', `${Math.max(half + 2, Math.min(x, pw - half - 2))}px`);\n arrow.style.removeProperty('--arrow-y');\n } else {\n const y = t.top + t.height / 2 - top!;\n arrow.style.setProperty('--arrow-y', `${Math.max(half + 2, Math.min(y, ph - half - 2))}px`);\n arrow.style.removeProperty('--arrow-x');\n }\n }\n },\n\n teardown: () => {\n // Positioning is written as inline styles, which outrank any class the panel might\n // switch to while it stays mounted — a popover turning into a bottom sheet (`useSheet`)\n // would keep the coordinates computed for its anchored self.\n const floating = floatingRef.current;\n if (!floating) return;\n floating.style.top = '';\n floating.style.left = '';\n floating.style.visibility = '';\n const panel = panelRef.current;\n panel?.style.removeProperty('min-width');\n panel?.style.removeProperty('max-width');\n },\n });\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e from"./progressBar.module.mjs";import t from"classnames";import{jsx as n}from"react/jsx-runtime";function r(e){let t=e.replace(`#`,``),n=parseInt(t.substring(0,2),16),r=parseInt(t.substring(2,4),16),i=parseInt(t.substring(4,6),16);return(.299*n+.587*r+.114*i)/255>.5?`#000000`:`#ffffff`}function i({className:i=void 0,total:a=100,progress:o=0,style:s=void 0,...c}){function l(){let i=[];return Array.isArray(o)?i.push(...o):typeof o==`object`?i.push(o):i.push({amount:o}),i.map((o,c)=>{let l=a?o.amount/a*100:0;return n(`div`,{className:t(e.progressBarFill,c===i.length-1&&e.progressBarFillEnd,o.class),style:{width:`${l}%`,background:o.color||void 0,...s||{}},title:o.label?`${o.label}: ${o.amount}`:void 0,children:o.label&&n(`div`,{className:e.progressBarLabel,style:o.color?{color:r(o.color)}:{},children:o.label})},c)})}return n(`div`,{...c,className:t(e.progressBar,i),style:s,children:l()})}export{i as default,r as getContrastColor};
1
+ import e from"./progressBar.module.mjs";import t from"classnames";import{jsx as n}from"react/jsx-runtime";function r(e){let t=e.replace(`#`,``),n=parseInt(t.substring(0,2),16),r=parseInt(t.substring(2,4),16),i=parseInt(t.substring(4,6),16);return(.299*n+.587*r+.114*i)/255>.5?`#000000`:`#ffffff`}function i({className:i=void 0,total:a=100,progress:o=0,style:s=void 0,classNames:c,styles:l,...u}){function d(){let i=[];return Array.isArray(o)?i.push(...o):typeof o==`object`?i.push(o):i.push({amount:o}),i.map((o,s)=>{let u=a?o.amount/a*100:0;return n(`div`,{className:t(e.progressBarFill,s===i.length-1&&e.progressBarFillEnd,o.class,c?.fill),style:{width:`${u}%`,background:o.color||void 0,...l?.fill},title:o.label?`${o.label}: ${o.amount}`:void 0,children:o.label&&n(`div`,{className:t(e.progressBarLabel,c?.label),style:{...o.color?{color:r(o.color)}:{},...l?.label},children:o.label})},s)})}return n(`div`,{...u,className:t(e.progressBar,i,c?.root),style:{...s,...l?.root},children:d()})}export{i as default,r as getContrastColor};
2
2
  //# sourceMappingURL=progressBar.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"progressBar.mjs","names":[],"sources":["../../../../package/common/progressBar/progressBar.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport cx from 'classnames';\nimport { Progress, ProgressBarProps } from './progressBar.types';\n\nimport styles from './progressBar.module.pcss';\n\nexport function getContrastColor(hexColor: string): string {\n const hex = hexColor.replace('#', '');\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.5 ? '#000000' : '#ffffff';\n}\n\nfunction ProgressBar({\n className = undefined,\n total = 100,\n progress = 0,\n style = undefined,\n ...rest\n}: ProgressBarProps): ReactElement {\n function renderProgressBars() {\n const progressArray: Progress[] = [];\n\n if (Array.isArray(progress)) progressArray.push(...progress);\n else if (typeof progress === 'object') progressArray.push(progress);\n else progressArray.push({ amount: progress });\n\n return progressArray.map((prog, index) => {\n const widthPercentage = !total ? 0 : (prog.amount / total) * 100;\n\n return (\n <div\n key={index}\n className={cx(\n styles.progressBarFill,\n index === progressArray.length - 1 && styles.progressBarFillEnd,\n prog.class,\n )}\n style={{\n width: `${widthPercentage}%`,\n background: prog.color || undefined,\n ...(style || {}),\n }}\n title={prog.label ? `${prog.label}: ${prog.amount}` : undefined}\n >\n {prog.label && (\n <div className={styles.progressBarLabel} style={prog.color ? { color: getContrastColor(prog.color) } : {}}>\n {prog.label}\n </div>\n )}\n </div>\n );\n });\n }\n\n return (\n <div {...rest} className={cx(styles.progressBar, className)} style={style}>\n {renderProgressBars()}\n </div>\n );\n}\n\nexport default ProgressBar;\n"],"mappings":"0GAMA,SAAgB,EAAiB,EAA0B,CACzD,IAAM,EAAM,EAAS,QAAQ,IAAK,EAAE,EAC9B,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EACpC,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EACpC,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EAG1C,OADmB,KAAQ,EAAI,KAAQ,EAAI,KAAQ,GAAK,IACrC,GAAM,UAAY,SACvC,CAEA,SAAS,EAAY,CACnB,YAAY,IAAA,GACZ,QAAQ,IACR,WAAW,EACX,QAAQ,IAAA,GACR,GAAG,GAC8B,CACjC,SAAS,GAAqB,CAC5B,IAAM,EAA4B,CAAC,EAMnC,OAJI,MAAM,QAAQ,CAAQ,EAAG,EAAc,KAAK,GAAG,CAAQ,EAClD,OAAO,GAAa,SAAU,EAAc,KAAK,CAAQ,EAC7D,EAAc,KAAK,CAAE,OAAQ,CAAS,CAAC,EAErC,EAAc,KAAK,EAAM,IAAU,CACxC,IAAM,EAAmB,EAAa,EAAK,OAAS,EAAS,IAA5B,EAEjC,OACE,EAAC,MAAD,CAEE,UAAW,EACT,EAAO,gBACP,IAAU,EAAc,OAAS,GAAK,EAAO,mBAC7C,EAAK,KACP,EACA,MAAO,CACL,MAAO,GAAG,EAAgB,GAC1B,WAAY,EAAK,OAAS,IAAA,GAC1B,GAAI,GAAS,CAAC,CAChB,EACA,MAAO,EAAK,MAAQ,GAAG,EAAK,MAAM,IAAI,EAAK,SAAW,IAAA,GAErD,SAAA,EAAK,OACJ,EAAC,MAAD,CAAK,UAAW,EAAO,iBAAkB,MAAO,EAAK,MAAQ,CAAE,MAAO,EAAiB,EAAK,KAAK,CAAE,EAAI,CAAC,EACrG,SAAA,EAAK,KACH,CAAA,CAEJ,EAlBE,CAkBF,CAET,CAAC,CACH,CAEA,OACE,EAAC,MAAD,CAAK,GAAI,EAAM,UAAW,EAAG,EAAO,YAAa,CAAS,EAAU,QACjE,SAAA,EAAmB,CACjB,CAAA,CAET"}
1
+ {"version":3,"file":"progressBar.mjs","names":[],"sources":["../../../../package/common/progressBar/progressBar.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport cx from 'classnames';\nimport { Progress, ProgressBarProps } from './progressBar.types';\n\nimport styles from './progressBar.module.pcss';\n\nexport function getContrastColor(hexColor: string): string {\n const hex = hexColor.replace('#', '');\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n return luminance > 0.5 ? '#000000' : '#ffffff';\n}\n\nfunction ProgressBar({\n className = undefined,\n total = 100,\n progress = 0,\n style = undefined,\n classNames,\n styles: slotStyles,\n ...rest\n}: ProgressBarProps): ReactElement {\n function renderProgressBars() {\n const progressArray: Progress[] = [];\n\n if (Array.isArray(progress)) progressArray.push(...progress);\n else if (typeof progress === 'object') progressArray.push(progress);\n else progressArray.push({ amount: progress });\n\n return progressArray.map((prog, index) => {\n const widthPercentage = !total ? 0 : (prog.amount / total) * 100;\n\n return (\n <div\n key={index}\n className={cx(\n styles.progressBarFill,\n index === progressArray.length - 1 && styles.progressBarFillEnd,\n prog.class,\n classNames?.fill,\n )}\n style={{\n width: `${widthPercentage}%`,\n background: prog.color || undefined,\n ...slotStyles?.fill,\n }}\n title={prog.label ? `${prog.label}: ${prog.amount}` : undefined}\n >\n {prog.label && (\n <div\n className={cx(styles.progressBarLabel, classNames?.label)}\n style={{ ...(prog.color ? { color: getContrastColor(prog.color) } : {}), ...slotStyles?.label }}\n >\n {prog.label}\n </div>\n )}\n </div>\n );\n });\n }\n\n return (\n <div\n {...rest}\n className={cx(styles.progressBar, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n {renderProgressBars()}\n </div>\n );\n}\n\nexport default ProgressBar;\n"],"mappings":"0GAMA,SAAgB,EAAiB,EAA0B,CACzD,IAAM,EAAM,EAAS,QAAQ,IAAK,EAAE,EAC9B,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EACpC,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EACpC,EAAI,SAAS,EAAI,UAAU,EAAG,CAAC,EAAG,EAAE,EAG1C,OADmB,KAAQ,EAAI,KAAQ,EAAI,KAAQ,GAAK,IACrC,GAAM,UAAY,SACvC,CAEA,SAAS,EAAY,CACnB,YAAY,IAAA,GACZ,QAAQ,IACR,WAAW,EACX,QAAQ,IAAA,GACR,aACA,OAAQ,EACR,GAAG,GAC8B,CACjC,SAAS,GAAqB,CAC5B,IAAM,EAA4B,CAAC,EAMnC,OAJI,MAAM,QAAQ,CAAQ,EAAG,EAAc,KAAK,GAAG,CAAQ,EAClD,OAAO,GAAa,SAAU,EAAc,KAAK,CAAQ,EAC7D,EAAc,KAAK,CAAE,OAAQ,CAAS,CAAC,EAErC,EAAc,KAAK,EAAM,IAAU,CACxC,IAAM,EAAmB,EAAa,EAAK,OAAS,EAAS,IAA5B,EAEjC,OACE,EAAC,MAAD,CAEE,UAAW,EACT,EAAO,gBACP,IAAU,EAAc,OAAS,GAAK,EAAO,mBAC7C,EAAK,MACL,GAAY,IACd,EACA,MAAO,CACL,MAAO,GAAG,EAAgB,GAC1B,WAAY,EAAK,OAAS,IAAA,GAC1B,GAAG,GAAY,IACjB,EACA,MAAO,EAAK,MAAQ,GAAG,EAAK,MAAM,IAAI,EAAK,SAAW,IAAA,GAErD,SAAA,EAAK,OACJ,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,iBAAkB,GAAY,KAAK,EACxD,MAAO,CAAE,GAAI,EAAK,MAAQ,CAAE,MAAO,EAAiB,EAAK,KAAK,CAAE,EAAI,CAAC,EAAI,GAAG,GAAY,KAAM,EAE7F,SAAA,EAAK,KACH,CAAA,CAEJ,EAtBE,CAsBF,CAET,CAAC,CACH,CAEA,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAO,YAAa,EAAW,GAAY,IAAI,EAC7D,MAAO,CAAE,GAAG,EAAO,GAAG,GAAY,IAAK,EAEtC,SAAA,EAAmB,CACjB,CAAA,CAET"}
@@ -1,2 +1,2 @@
1
- import{InputType as e}from"../input/input.types.mjs";import t from"../input/input.mjs";import n from"./searchInput.module.mjs";import{useEffect as r,useRef as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s({value:s,onChange:c,onDebounce:l,placeholder:u,label:d,debounceMs:f=500,totalAmount:p,showAmount:m=!0,className:h,width:g,..._}){let v=i(null);r(()=>()=>{v.current!==null&&clearTimeout(v.current)},[]);function y(e){let t=e==null?``:String(e),n=t.trim()===``?``:t;c(n),v.current!==null&&clearTimeout(v.current),v.current=setTimeout(()=>{l?.(n)},f)}let b=m&&typeof p==`number`&&!Number.isNaN(p);return o(`div`,{..._,className:h,style:g==null?void 0:{width:g},children:[a(t,{autoComplete:`off`,type:e.Search,label:d,placeholder:u,value:s,onChange:y}),b&&o(`p`,{className:n.resultCount,children:[p,` `,p===1?`result`:`results`]})]})}export{s as default};
1
+ import{useLabels as e}from"../configProvider/useLabels.mjs";import{InputType as t}from"../input/input.types.mjs";import n from"../input/input.mjs";import r from"./searchInput.module.mjs";import{useEffect as i,useRef as a}from"react";import o from"classnames";import{jsx as s,jsxs as c}from"react/jsx-runtime";var l={results:e=>`${e} ${e===1?`result`:`results`}`};function u({value:u,onChange:d,onDebounce:f,placeholder:p,label:m,debounceMs:h=500,totalAmount:g,showAmount:_=!0,className:v,width:y,style:b,classNames:x,styles:S,labels:C,...w}){let T=e(`SearchInput`,C,l),E=a(null);i(()=>()=>{E.current!==null&&clearTimeout(E.current)},[]);function D(e){let t=e==null?``:String(e),n=t.trim()===``?``:t;d(n),E.current!==null&&clearTimeout(E.current),E.current=setTimeout(()=>{f?.(n)},h)}let O=_&&typeof g==`number`&&!Number.isNaN(g);return c(`div`,{...w,className:o(v,x?.root),style:{...y==null?void 0:{width:y},...b,...S?.root},children:[s(n,{autoComplete:`off`,className:x?.input,style:S?.input,type:t.Search,label:m,placeholder:p,value:u,onChange:D}),O&&s(`p`,{className:o(r.resultCount,x?.resultCount),style:S?.resultCount,children:T.results(g)})]})}export{u as default};
2
2
  //# sourceMappingURL=searchInput.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"searchInput.mjs","names":[],"sources":["../../../../package/common/searchInput/searchInput.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactElement } from 'react';\nimport Input from 'components/common/input';\nimport { InputType } from 'components/common/input/input.types';\nimport styles from './searchInput.module.pcss';\nimport type { SearchInputProps } from './searchInput.types';\n\nexport default function SearchInput({\n value,\n onChange,\n onDebounce,\n placeholder,\n label,\n debounceMs = 500,\n totalAmount,\n showAmount = true,\n className,\n width,\n ...rest\n}: SearchInputProps): ReactElement {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n },\n [],\n );\n\n function handleChange(val: unknown) {\n const str = val != null ? String(val) : '';\n const trimmed = str.trim() === '' ? '' : str;\n onChange(trimmed);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => {\n onDebounce?.(trimmed);\n }, debounceMs);\n }\n\n const showCount = showAmount && typeof totalAmount === 'number' && !Number.isNaN(totalAmount);\n\n return (\n <div {...rest} className={className} style={width != null ? { width } : undefined}>\n <Input\n autoComplete='off'\n type={InputType.Search}\n label={label}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n />\n {showCount && (\n <p className={styles.resultCount}>\n {totalAmount} {totalAmount === 1 ? 'result' : 'results'}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":"+NAMA,SAAwB,EAAY,CAClC,QACA,WACA,aACA,cACA,QACA,aAAa,IACb,cACA,aAAa,GACb,YACA,QACA,GAAG,GAC8B,CACjC,IAAM,EAAW,EAA6C,IAAI,EAElE,UACc,CACN,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,CAC9D,EACA,CAAC,CACH,EAEA,SAAS,EAAa,EAAc,CAClC,IAAM,EAAM,GAAO,KAAqB,GAAd,OAAO,CAAG,EAC9B,EAAU,EAAI,KAAK,IAAM,GAAK,GAAK,EACzC,EAAS,CAAO,EACZ,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,EAC5D,EAAS,QAAU,eAAiB,CAClC,IAAa,CAAO,CACtB,EAAG,CAAU,CACf,CAEA,IAAM,EAAY,GAAc,OAAO,GAAgB,UAAY,CAAC,OAAO,MAAM,CAAW,EAE5F,OACE,EAAC,MAAD,CAAK,GAAI,EAAiB,YAAW,MAAO,GAAS,KAAmB,IAAA,GAAZ,CAAE,OAAM,EAApE,SAAA,CACE,EAAC,EAAD,CACE,aAAa,MACb,KAAM,EAAU,OACT,QACM,cACN,QACP,SAAU,CACX,CAAA,EACA,GACC,EAAC,IAAD,CAAG,UAAW,EAAO,YAArB,SAAA,CACG,EAAY,IAAE,IAAgB,EAAI,SAAW,SAC7C,CAEF,CAAA,CAAA,GAET"}
1
+ {"version":3,"file":"searchInput.mjs","names":[],"sources":["../../../../package/common/searchInput/searchInput.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport Input from 'components/common/input';\nimport { InputType } from 'components/common/input/input.types';\nimport styles from './searchInput.module.pcss';\nimport { useLabels } from '../configProvider';\nimport type { SearchInputLabels, SearchInputProps } from './searchInput.types';\n\nconst DEFAULT_LABELS: Required<SearchInputLabels> = {\n results: (count) => `${count} ${count === 1 ? 'result' : 'results'}`,\n};\n\nexport default function SearchInput({\n value,\n onChange,\n onDebounce,\n placeholder,\n label,\n debounceMs = 500,\n totalAmount,\n showAmount = true,\n className,\n width,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n}: SearchInputProps): ReactElement {\n const text = useLabels('SearchInput', labels, DEFAULT_LABELS);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n },\n [],\n );\n\n function handleChange(val: unknown) {\n const str = val != null ? String(val) : '';\n const trimmed = str.trim() === '' ? '' : str;\n onChange(trimmed);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => {\n onDebounce?.(trimmed);\n }, debounceMs);\n }\n\n const showCount = showAmount && typeof totalAmount === 'number' && !Number.isNaN(totalAmount);\n\n return (\n <div\n {...rest}\n className={cx(className, classNames?.root)}\n style={{ ...(width != null ? { width } : undefined), ...style, ...slotStyles?.root }}\n >\n <Input\n autoComplete='off'\n className={classNames?.input}\n style={slotStyles?.input}\n type={InputType.Search}\n label={label}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n />\n {showCount && (\n <p className={cx(styles.resultCount, classNames?.resultCount)} style={slotStyles?.resultCount}>\n {text.results(totalAmount)}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":"qTAQA,IAAM,EAA8C,CAClD,QAAU,GAAU,GAAG,EAAM,GAAG,IAAU,EAAI,SAAW,WAC3D,EAEA,SAAwB,EAAY,CAClC,QACA,WACA,aACA,cACA,QACA,aAAa,IACb,cACA,aAAa,GACb,YACA,QACA,QACA,aACA,OAAQ,EACR,SACA,GAAG,GAC8B,CACjC,IAAM,EAAO,EAAU,cAAe,EAAQ,CAAc,EACtD,EAAW,EAA6C,IAAI,EAElE,UACc,CACN,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,CAC9D,EACA,CAAC,CACH,EAEA,SAAS,EAAa,EAAc,CAClC,IAAM,EAAM,GAAO,KAAqB,GAAd,OAAO,CAAG,EAC9B,EAAU,EAAI,KAAK,IAAM,GAAK,GAAK,EACzC,EAAS,CAAO,EACZ,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,EAC5D,EAAS,QAAU,eAAiB,CAClC,IAAa,CAAO,CACtB,EAAG,CAAU,CACf,CAEA,IAAM,EAAY,GAAc,OAAO,GAAgB,UAAY,CAAC,OAAO,MAAM,CAAW,EAE5F,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAW,GAAY,IAAI,EACzC,MAAO,CAAE,GAAI,GAAS,KAAmB,IAAA,GAAZ,CAAE,OAAM,EAAgB,GAAG,EAAO,GAAG,GAAY,IAAK,EAHrF,SAAA,CAKE,EAAC,EAAD,CACE,aAAa,MACb,UAAW,GAAY,MACvB,MAAO,GAAY,MACnB,KAAM,EAAU,OACT,QACM,cACN,QACP,SAAU,CACX,CAAA,EACA,GACC,EAAC,IAAD,CAAG,UAAW,EAAG,EAAO,YAAa,GAAY,WAAW,EAAG,MAAO,GAAY,YAC/E,SAAA,EAAK,QAAQ,CAAW,CACxB,CAAA,CAEF,GAET"}
@@ -1,2 +1,2 @@
1
- import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n,ButtonStyleType as r}from"../button/button.types.mjs";import{renderIcon as i}from"../utils/renderIcon.mjs";import a from"../button/button.mjs";import o from"../interactableDiv/index.mjs";import{Align as s}from"../floatingMenu/floatingMenu.types.mjs";import c from"../floatingMenu/floatingMenu.mjs";import l from"../buttonGroup/buttonGroup.mjs";import u from"./splitButton.module.mjs";import{useEffect as d,useRef as f,useState as p}from"react";import m from"classnames";import{faChevronDown as h}from"@fortawesome/free-solid-svg-icons";import{jsx as g,jsxs as _}from"react/jsx-runtime";var v={moreActions:`More actions`};function y(e,t){return(e%t+t)%t}function b(b){let{children:x,onClick:S=()=>{},actions:C=[],styleType:w=r.Primary,size:T=n.Default,disabled:E=!1,isLoading:D=!1,align:O=s.Right,className:k,style:A,classNames:j,styles:M,labels:N,...P}=e(`SplitButton`,b),F=t(`SplitButton`,N,v),[I,L]=p(!1),R=f([]),[z,B]=p(E);E!==z&&(B(E),E&&L(!1)),d(()=>{if(!I)return;let e=C.findIndex(e=>!e.disabled);e!==-1&&R.current[e]?.focus()},[I]);function V(e,t){let n=C.map((e,t)=>t).filter(e=>!C[e].disabled);if(n.length===0)return;let r=n.indexOf(e),i=r===-1?t===1?0:n.length-1:y(r+t,n.length);R.current[n[i]]?.focus()}function H(e){let t=R.current.findIndex(e=>e===document.activeElement);e.key===`ArrowDown`?(e.preventDefault(),V(t,1)):e.key===`ArrowUp`?(e.preventDefault(),V(t,-1)):e.key===`Home`?(e.preventDefault(),V(-1,1)):e.key===`End`&&(e.preventDefault(),V(-1,-1))}return _(l,{...P,className:m(u.splitButton,j?.root,k),style:{...A,...M?.root},children:[g(a,{styleType:w,size:T,disabled:E,isLoading:D,onClick:S,className:m(u.splitButtonPrimary,j?.primaryButton),style:M?.primaryButton,children:x}),g(c,{isOpen:I,onOpenChange:L,align:O,dontCloseOnChildClick:!0,content:g(`ul`,{className:m(u.splitButtonMenu,j?.menu),style:M?.menu,role:`menu`,onKeyDown:H,children:C.map((e,t)=>g(`li`,{role:`none`,children:_(o,{ref:e=>{R.current[t]=e},role:`menuitem`,tabIndex:e.disabled?-1:0,"aria-disabled":e.disabled,className:m(u.splitButtonMenuItem,{[u.splitButtonMenuItemDisabled]:e.disabled},j?.menuItem),style:M?.menuItem,onClick:()=>{E||e.disabled||(e.onClick(),L(!1))},children:[e.icon?i(e.icon,{className:u.splitButtonMenuItemIcon}):null,e.label]})},e.id))}),children:g(a,{styleType:w,size:T,disabled:E,icon:h,"aria-label":F.moreActions,className:m(u.splitButtonTrigger,j?.triggerButton),style:M?.triggerButton})})]})}export{b as default};
1
+ import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n,ButtonStyleType as r}from"../button/button.types.mjs";import i from"../button/button.mjs";import{PopoverAlign as a,PopoverPlacement as o}from"../popover/popover.types.mjs";import s from"../buttonGroup/buttonGroup.mjs";import c from"../menu/menu.mjs";import l from"./splitButton.module.mjs";import{useState as u}from"react";import d from"classnames";import{faChevronDown as f}from"@fortawesome/free-solid-svg-icons";import{jsx as p,jsxs as m}from"react/jsx-runtime";var h={moreActions:`More actions`};function g(g){let{children:_,onClick:v=()=>{},actions:y=[],styleType:b=r.Primary,size:x=n.Default,disabled:S=!1,isLoading:C=!1,align:w=a.End,className:T,style:E,classNames:D,styles:O,labels:k,...A}=e(`SplitButton`,g),j=t(`SplitButton`,k,h),[M,N]=u(!1),[P,F]=u(S);return S!==P&&(F(S),S&&N(!1)),m(s,{...A,className:d(l.splitButton,D?.root,T),style:{...E,...O?.root},children:[p(i,{styleType:b,size:x,disabled:S,isLoading:C,onClick:v,className:d(l.splitButtonPrimary,D?.primaryButton),style:O?.primaryButton,children:_}),p(c,{items:y,isOpen:M,onOpenChange:N,placement:o.Bottom,align:w,classNames:{menu:D?.menu,item:D?.menuItem},styles:{menu:O?.menu,item:O?.menuItem},children:p(i,{styleType:b,size:x,disabled:S,icon:f,"aria-label":j.moreActions,className:d(l.splitButtonTrigger,D?.triggerButton),style:O?.triggerButton})})]})}export{g as default};
2
2
  //# sourceMappingURL=splitButton.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"splitButton.mjs","names":[],"sources":["../../../../package/common/splitButton/splitButton.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\nimport cx from 'classnames';\nimport { faChevronDown } from '@fortawesome/free-solid-svg-icons';\n\nimport Button from '../button';\nimport { ButtonStyleType, ButtonSize } from '../button/button.types';\nimport ButtonGroup from '../buttonGroup';\nimport FloatingMenu from '../floatingMenu';\nimport { Align } from '../floatingMenu/floatingMenu.types';\nimport type { SplitButtonLabels } from './splitButton.types';\nimport InteractableDiv from '../interactableDiv';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { SplitButtonProps } from './splitButton.types';\n\nimport styles from './splitButton.module.pcss';\nimport { renderIcon } from '../utils/renderIcon';\n\nconst DEFAULT_LABELS: Required<SplitButtonLabels> = {\n moreActions: 'More actions',\n};\n\nfunction mod(n: number, m: number) {\n return ((n % m) + m) % m;\n}\n\nfunction SplitButton(props: SplitButtonProps) {\n const {\n children,\n onClick = () => {},\n actions = [],\n styleType = ButtonStyleType.Primary,\n size = ButtonSize.Default,\n disabled = false,\n isLoading = false,\n align = Align.Right,\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('SplitButton', props);\n const text = useLabels('SplitButton', labels, DEFAULT_LABELS);\n\n const [isOpen, setIsOpen] = useState(false);\n const itemRefs = useRef<(HTMLDivElement | null)[]>([]);\n\n // Adjusting state during render (not in an effect) on a prop change is the documented React\n // pattern for this: closing the menu as soon as `disabled` becomes true, without an extra\n // render tick or a setState-in-effect lint violation.\n const [prevDisabled, setPrevDisabled] = useState(disabled);\n if (disabled !== prevDisabled) {\n setPrevDisabled(disabled);\n if (disabled) setIsOpen(false);\n }\n\n useEffect(() => {\n if (!isOpen) return;\n const firstEnabled = actions.findIndex((action) => !action.disabled);\n if (firstEnabled !== -1) itemRefs.current[firstEnabled]?.focus();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n function focusEnabledItem(fromIndex: number, direction: 1 | -1) {\n const enabledIndexes = actions.map((action, index) => index).filter((index) => !actions[index].disabled);\n if (enabledIndexes.length === 0) return;\n\n const currentPos = enabledIndexes.indexOf(fromIndex);\n const nextPos =\n currentPos === -1\n ? direction === 1\n ? 0\n : enabledIndexes.length - 1\n : mod(currentPos + direction, enabledIndexes.length);\n itemRefs.current[enabledIndexes[nextPos]]?.focus();\n }\n\n function handleMenuKeyDown(event: KeyboardEvent<HTMLUListElement>) {\n const activeIndex = itemRefs.current.findIndex((el) => el === document.activeElement);\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusEnabledItem(activeIndex, 1);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusEnabledItem(activeIndex, -1);\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusEnabledItem(-1, 1);\n } else if (event.key === 'End') {\n event.preventDefault();\n focusEnabledItem(-1, -1);\n }\n // Escape and Tab-boundary handling live in FloatingMenu itself, since any menu content with\n // focusable elements needs the same treatment, not just this one.\n }\n\n return (\n <ButtonGroup\n {...rest}\n className={cx(styles.splitButton, classNames?.root, className)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <Button\n styleType={styleType}\n size={size}\n disabled={disabled}\n isLoading={isLoading}\n onClick={onClick}\n className={cx(styles.splitButtonPrimary, classNames?.primaryButton)}\n style={slotStyles?.primaryButton}\n >\n {children}\n </Button>\n\n <FloatingMenu\n isOpen={isOpen}\n onOpenChange={setIsOpen}\n align={align}\n dontCloseOnChildClick\n content={\n <ul\n className={cx(styles.splitButtonMenu, classNames?.menu)}\n style={slotStyles?.menu}\n role='menu'\n onKeyDown={handleMenuKeyDown}\n >\n {actions.map((action, index) => (\n <li key={action.id} role='none'>\n <InteractableDiv\n ref={(el) => {\n itemRefs.current[index] = el;\n }}\n role='menuitem'\n tabIndex={action.disabled ? -1 : 0}\n aria-disabled={action.disabled}\n className={cx(\n styles.splitButtonMenuItem,\n { [styles.splitButtonMenuItemDisabled]: action.disabled },\n classNames?.menuItem,\n )}\n style={slotStyles?.menuItem}\n onClick={() => {\n if (disabled || action.disabled) return;\n action.onClick();\n setIsOpen(false);\n }}\n >\n {action.icon ? renderIcon(action.icon, { className: styles.splitButtonMenuItemIcon }) : null}\n {action.label}\n </InteractableDiv>\n </li>\n ))}\n </ul>\n }\n >\n <Button\n styleType={styleType}\n size={size}\n disabled={disabled}\n icon={faChevronDown}\n aria-label={text.moreActions}\n className={cx(styles.splitButtonTrigger, classNames?.triggerButton)}\n style={slotStyles?.triggerButton}\n />\n </FloatingMenu>\n </ButtonGroup>\n );\n}\n\nexport default SplitButton;\n"],"mappings":"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"}
1
+ {"version":3,"file":"splitButton.mjs","names":[],"sources":["../../../../package/common/splitButton/splitButton.tsx"],"sourcesContent":["import { useState } from 'react';\nimport cx from 'classnames';\nimport { faChevronDown } from '@fortawesome/free-solid-svg-icons';\n\nimport Button from '../button';\nimport { ButtonStyleType, ButtonSize } from '../button/button.types';\nimport ButtonGroup from '../buttonGroup';\nimport Menu from '../menu';\nimport { PopoverAlign, PopoverPlacement } from '../popover/popover.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { SplitButtonLabels, SplitButtonProps } from './splitButton.types';\n\nimport styles from './splitButton.module.pcss';\n\nconst DEFAULT_LABELS: Required<SplitButtonLabels> = {\n moreActions: 'More actions',\n};\n\nfunction SplitButton(props: SplitButtonProps) {\n const {\n children,\n onClick = () => {},\n actions = [],\n styleType = ButtonStyleType.Primary,\n size = ButtonSize.Default,\n disabled = false,\n isLoading = false,\n align = PopoverAlign.End,\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('SplitButton', props);\n const text = useLabels('SplitButton', labels, DEFAULT_LABELS);\n\n const [isOpen, setIsOpen] = useState(false);\n\n // Adjusting state during render (not in an effect) on a prop change is the documented React\n // pattern for this: closing the menu as soon as `disabled` becomes true, without an extra\n // render tick or a setState-in-effect lint violation.\n const [prevDisabled, setPrevDisabled] = useState(disabled);\n if (disabled !== prevDisabled) {\n setPrevDisabled(disabled);\n if (disabled) setIsOpen(false);\n }\n\n return (\n <ButtonGroup\n {...rest}\n className={cx(styles.splitButton, classNames?.root, className)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <Button\n styleType={styleType}\n size={size}\n disabled={disabled}\n isLoading={isLoading}\n onClick={onClick}\n className={cx(styles.splitButtonPrimary, classNames?.primaryButton)}\n style={slotStyles?.primaryButton}\n >\n {children}\n </Button>\n\n {/* The list, its keys, its focus and its menu semantics are Menu's; this\n component only welds a second button to the first. */}\n <Menu\n items={actions}\n isOpen={isOpen}\n onOpenChange={setIsOpen}\n placement={PopoverPlacement.Bottom}\n align={align}\n classNames={{ menu: classNames?.menu, item: classNames?.menuItem }}\n styles={{ menu: slotStyles?.menu, item: slotStyles?.menuItem }}\n >\n <Button\n styleType={styleType}\n size={size}\n disabled={disabled}\n icon={faChevronDown}\n aria-label={text.moreActions}\n className={cx(styles.splitButtonTrigger, classNames?.triggerButton)}\n style={slotStyles?.triggerButton}\n />\n </Menu>\n </ButtonGroup>\n );\n}\n\nexport default SplitButton;\n"],"mappings":"snBAcA,IAAM,EAA8C,CAClD,YAAa,cACf,EAEA,SAAS,EAAY,EAAyB,CAC5C,GAAM,CACJ,WACA,cAAgB,CAAC,EACjB,UAAU,CAAC,EACX,YAAY,EAAgB,QAC5B,OAAO,EAAW,QAClB,WAAW,GACX,YAAY,GACZ,QAAQ,EAAa,IACrB,YACA,QACA,aACA,OAAQ,EACR,SACA,GAAG,GACD,EAAqB,cAAe,CAAK,EACvC,EAAO,EAAU,cAAe,EAAQ,CAAc,EAEtD,CAAC,EAAQ,GAAa,EAAS,EAAK,EAKpC,CAAC,EAAc,GAAmB,EAAS,CAAQ,EAMzD,OALI,IAAa,IACf,EAAgB,CAAQ,EACpB,GAAU,EAAU,EAAK,GAI7B,EAAC,EAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAO,YAAa,GAAY,KAAM,CAAS,EAC7D,MAAO,CAAE,GAAG,EAAO,GAAG,GAAY,IAAK,EAHzC,SAAA,CAKE,EAAC,EAAD,CACa,YACL,OACI,WACC,YACF,UACT,UAAW,EAAG,EAAO,mBAAoB,GAAY,aAAa,EAClE,MAAO,GAAY,cAElB,UACK,CAAA,EAIR,EAAC,EAAD,CACE,MAAO,EACC,SACR,aAAc,EACd,UAAW,EAAiB,OACrB,QACP,WAAY,CAAE,KAAM,GAAY,KAAM,KAAM,GAAY,QAAS,EACjE,OAAQ,CAAE,KAAM,GAAY,KAAM,KAAM,GAAY,QAAS,EAE7D,SAAA,EAAC,EAAD,CACa,YACL,OACI,WACV,KAAM,EACN,aAAY,EAAK,YACjB,UAAW,EAAG,EAAO,mBAAoB,GAAY,aAAa,EAClE,MAAO,GAAY,aACpB,CAAA,CACG,CAAA,CACK,GAEjB"}
@@ -1,2 +1,2 @@
1
- var e=`splitButton_5ak5W`,t=`splitButtonPrimary_4mVy8`,n=`splitButtonTrigger_32cQA`,r=`splitButtonMenu_P6Ofl`,i=`splitButtonMenuItem_dbEEz`,a=`splitButtonMenuItem-disabled_Dw1mr`,o=`splitButtonMenuItem-icon_dMuKX`,s={splitButton:e,splitButtonPrimary:t,splitButtonTrigger:n,splitButtonMenu:r,splitButtonMenuItem:i,"splitButtonMenuItem-disabled":`splitButtonMenuItem-disabled_Dw1mr`,splitButtonMenuItemDisabled:a,"splitButtonMenuItem-icon":`splitButtonMenuItem-icon_dMuKX`,splitButtonMenuItemIcon:o};export{s as default,e as splitButton,r as splitButtonMenu,i as splitButtonMenuItem,a as splitButtonMenuItemDisabled,o as splitButtonMenuItemIcon,t as splitButtonPrimary,n as splitButtonTrigger};
1
+ var e=`splitButton_5ak5W`,t=`splitButtonPrimary_4mVy8`,n=`splitButtonTrigger_32cQA`,r={splitButton:e,splitButtonPrimary:t,splitButtonTrigger:n};export{r as default,e as splitButton,t as splitButtonPrimary,n as splitButtonTrigger};
2
2
  //# sourceMappingURL=splitButton.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"splitButton.module.mjs","names":[],"sources":["../../../../package/common/splitButton/splitButton.module.pcss"],"sourcesContent":[".splitButton {\n display: inline-flex;\n}\n\n/* The class is doubled to boost specificity above Button's own .button rule (both are plain\n single classes, so specificity would otherwise tie and the outcome would depend on which\n CSS module happens to load first in the bundle). This guarantees the flattened corner always\n wins regardless of load order. */\n.splitButtonPrimary.splitButtonPrimary {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.splitButtonTrigger.splitButtonTrigger {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: -1px;\n}\n\n.splitButtonMenu {\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin: 0;\n padding: 6px;\n list-style: none;\n min-width: 140px;\n}\n\n.splitButtonMenuItem {\n display: flex;\n align-items: center;\n padding: 8px 10px;\n border-radius: var(--default-border-radius);\n color: var(--text-color);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n &-disabled {\n opacity: 0.5;\n cursor: default;\n pointer-events: none;\n }\n\n &-icon {\n width: 1em;\n flex: none;\n margin-right: 8px;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"splitButton.module.mjs","names":[],"sources":["../../../../package/common/splitButton/splitButton.module.pcss"],"sourcesContent":[".splitButton {\n display: inline-flex;\n}\n\n/* The class is doubled to boost specificity above Button's own .button rule (both are plain\n single classes, so specificity would otherwise tie and the outcome would depend on which\n CSS module happens to load first in the bundle). This guarantees the flattened corner always\n wins regardless of load order. */\n.splitButtonPrimary.splitButtonPrimary {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.splitButtonTrigger.splitButtonTrigger {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: -1px;\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- import{ButtonStyleType as e}from"../button/button.types.mjs";import t from"../button/button.mjs";import{Align as n}from"../floatingMenu/floatingMenu.types.mjs";import r from"../floatingMenu/floatingMenu.mjs";import i from"../tooltip/tooltip.mjs";import a from"../input/input.mjs";import ee from"../modal/modal.mjs";import{clampHour as te,clampToRange as o,formatTime as s,parseTimeString as c,snapMinute as l}from"./timeFunctions.mjs";import ne from"./components/clockDial/clockDial.mjs";import u from"./timeInput.module.mjs";import{useEffect as re,useRef as ie,useState as d}from"react";import f from"classnames";import{FontAwesomeIcon as ae}from"@fortawesome/react-fontawesome";import{faClock as oe}from"@fortawesome/free-solid-svg-icons";import{jsx as p,jsxs as m}from"react/jsx-runtime";import h from"@mona-health/react-input-mask";function g({value:g,selected:se,onChange:ce=()=>null,onSelect:_=()=>null,formValidator:v=null,isInline:y=!1,isModal:b=!1,noInput:le=!1,noHeader:ue=!1,showClearButton:x=!1,showNowButton:S=!1,minuteStep:C=1,use24Hour:w=!0,minTime:T=null,maxTime:E=null,label:D=``,isValid:de=!0,errorMessage:O=``,isRequired:k=!1,disabled:A=!1,className:fe=``,style:pe,classNames:j,styles:M,...me}){let N=()=>v?v.value||``:g??se??``,[P,F]=d(N),[I,L]=d(!1),[R,z]=d(`hours`),[he,B]=d(!1),[ge,V]=d(!1),[,_e]=d(0),H=N(),[ve,ye]=d(H),U=ie(v);!v&&ve!==H&&(ye(H),F(H)),re(()=>{if(U.current=v,!v)return;let e=()=>{F(v.value||``),_e(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v]);let be=()=>v?v.touched&&v.hasError():!de||!!O,xe=()=>!!(k||v?.validators.find(e=>e.validatorId===`required`)),W=e=>{let t=e?s(e):null;v&&v.set(t),ce?.(t)},G=e=>{F(e?s(e):``),W(e)},K=c(P),q=K??{hours:12,minutes:0},J=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)};G(o(t,T,E))},Se=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)},n=o(t,T,E);if(G(n),R===`hours`){z(`minutes`);return}_?.(s(n)),y||L(!1)},Y=()=>{A||(z(`hours`),L(!0))},Ce=({previousState:e,nextState:t})=>{if(!e||t.value===e.value)return t;let n=t.value,r=n.slice(0,2);/^\d\d$/.test(r)&&Number(r)>23&&(n=`23${n.slice(2)}`);let i=n.slice(3,5);return/^\d\d$/.test(i)&&Number(i)>59&&(n=`${n.slice(0,3)}59`),n===t.value?t:{...t,value:n}},we=e=>{F(e);let t=c(e);t&&W(t)},Te=()=>{U.current&&(U.current.touched=!0),B(!1),W(c(P))},X=e=>{e!==q.hours>=12&&G({hours:te(q.hours+(e?12:-12)),minutes:q.minutes})},Z=be(),Ee=K?String(w?K.hours:(K.hours+11)%12+1).padStart(2,`0`):`--`,De=K?String(K.minutes).padStart(2,`0`):`--`,Oe=ue?null:m(`div`,{className:f(u.timeInputClockHeader,j?.clockHeader),style:M?.clockHeader,children:[p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`hours`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`hours`),children:Ee}),p(`span`,{className:u.timeInputHeaderColon,children:`:`}),p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`minutes`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`minutes`),children:De}),!w&&m(`div`,{className:f(u.timeInputMeridiem,j?.meridiem),style:M?.meridiem,children:[p(`button`,{type:`button`,className:f(q.hours<12&&u.timeInputMeridiemActive),onClick:()=>X(!1),children:`AM`}),p(`button`,{type:`button`,className:f(q.hours>=12&&u.timeInputMeridiemActive),onClick:()=>X(!0),children:`PM`})]})]}),ke=x||S?m(`div`,{className:f(u.timeInputFooter,j?.footer),style:M?.footer,children:[S&&p(t,{styleType:e.Default,onClick:()=>{let e=new Date;J({hours:e.getHours(),minutes:e.getMinutes()})},children:`Now`}),x&&p(t,{styleType:e.Default,onClick:()=>{G(null),_?.(null)},children:`Clear`})]}):null,Q=m(`div`,{className:f(u.timeInputClock,j?.clock),style:M?.clock,children:[Oe,p(ne,{time:q,mode:R,use24Hour:w,minuteStep:C,onChange:J,onCommit:Se,classNames:j,styles:M}),ke]}),$=le?null:p(a,{autoComplete:`off`,label:`${D}${xe()?` *`:``}`,value:P,icon:p(ae,{icon:oe}),onIconClick:Y,onClick:Y,readOnly:b,disabled:A,isValid:!Z,customInput:p(h,{mask:`99:99`,maskPlaceholder:`_`,beforeMaskedStateChange:Ce}),onChange:e=>we(e),onBlur:Te,onFocus:()=>B(!0),onMouseEnter:()=>V(!0),onMouseLeave:()=>V(!1)}),Ae=y?Q:b?p(ee,{hideHeader:!0,isOpen:I,onClose:()=>L(!1),children:Q}):p(r,{isOpen:I,onOpenChange:L,content:Q,align:n.Left,dontCloseOnChildClick:!0,children:$});return m(`div`,{className:f(u.timeInput,j?.root,fe),style:{...M?.root,...pe},...me,children:[(b||y)&&$,Ae,p(i,{variant:`error`,message:v?v.getCurrentErrorMessage()??``:O||``,isVisible:Z&&(he||ge)})]})}export{g as default};
1
+ import{ButtonStyleType as e}from"../button/button.types.mjs";import t from"../button/button.mjs";import{PopoverAlign as n,PopoverPlacement as r}from"../popover/popover.types.mjs";import i from"../popover/popover.mjs";import a from"../tooltip/tooltip.mjs";import o from"../input/input.mjs";import ee from"../modal/modal.mjs";import{clampHour as te,clampToRange as s,formatTime as c,parseTimeString as l,snapMinute as u}from"./timeFunctions.mjs";import ne from"./components/clockDial/clockDial.mjs";import d from"./timeInput.module.mjs";import{useEffect as f,useRef as re,useState as p}from"react";import m from"classnames";import{FontAwesomeIcon as ie}from"@fortawesome/react-fontawesome";import{faClock as ae}from"@fortawesome/free-solid-svg-icons";import{jsx as h,jsxs as g}from"react/jsx-runtime";import oe from"@mona-health/react-input-mask";function _({value:_,selected:se,onChange:ce=()=>null,onSelect:v=()=>null,formValidator:y=null,isInline:b=!1,isModal:x=!1,noInput:le=!1,noHeader:ue=!1,showClearButton:S=!1,showNowButton:C=!1,minuteStep:w=1,use24Hour:T=!0,minTime:E=null,maxTime:D=null,label:de=``,isValid:fe=!0,errorMessage:O=``,isRequired:pe=!1,disabled:k=!1,className:me=``,style:he,classNames:A,styles:j,...ge}){let M=()=>y?y.value||``:_??se??``,[N,P]=p(M),[F,I]=p(!1),[L,R]=p(`hours`),[z,B]=p(!1),[_e,V]=p(!1),[,ve]=p(0),H=M(),[ye,be]=p(H),U=re(y);!y&&ye!==H&&(be(H),P(H)),f(()=>{if(U.current=y,!y)return;let e=()=>{P(y.value||``),ve(e=>e+1)};return y.registerOnUpdateListener(e),()=>y.removeOnUpdateListener(e)},[y]);let xe=()=>y?y.touched&&y.hasError():!fe||!!O,Se=()=>!!(pe||y?.validators.find(e=>e.validatorId===`required`)),W=e=>{let t=e?c(e):null;y&&y.set(t),ce?.(t)},G=e=>{P(e?c(e):``),W(e)},K=l(N),q=K??{hours:12,minutes:0},J=e=>{let t={hours:e.hours,minutes:u(e.minutes,w)};G(s(t,E,D))},Ce=e=>{let t={hours:e.hours,minutes:u(e.minutes,w)},n=s(t,E,D);if(G(n),L===`hours`){R(`minutes`);return}v?.(c(n)),b||I(!1)},Y=()=>{k||(R(`hours`),I(!0))},we=({previousState:e,nextState:t})=>{if(!e||t.value===e.value)return t;let n=t.value,r=n.slice(0,2);/^\d\d$/.test(r)&&Number(r)>23&&(n=`23${n.slice(2)}`);let i=n.slice(3,5);return/^\d\d$/.test(i)&&Number(i)>59&&(n=`${n.slice(0,3)}59`),n===t.value?t:{...t,value:n}},Te=e=>{P(e);let t=l(e);t&&W(t)},Ee=()=>{U.current&&(U.current.touched=!0),B(!1),W(l(N))},X=e=>{e!==q.hours>=12&&G({hours:te(q.hours+(e?12:-12)),minutes:q.minutes})},Z=xe(),De=K?String(T?K.hours:(K.hours+11)%12+1).padStart(2,`0`):`--`,Oe=K?String(K.minutes).padStart(2,`0`):`--`,ke=ue?null:g(`div`,{className:m(d.timeInputClockHeader,A?.clockHeader),style:j?.clockHeader,children:[h(`button`,{type:`button`,className:m(d.timeInputHeaderSegment,L===`hours`&&d.timeInputHeaderSegmentActive,A?.headerSegment),style:j?.headerSegment,onClick:()=>R(`hours`),children:De}),h(`span`,{className:d.timeInputHeaderColon,children:`:`}),h(`button`,{type:`button`,className:m(d.timeInputHeaderSegment,L===`minutes`&&d.timeInputHeaderSegmentActive,A?.headerSegment),style:j?.headerSegment,onClick:()=>R(`minutes`),children:Oe}),!T&&g(`div`,{className:m(d.timeInputMeridiem,A?.meridiem),style:j?.meridiem,children:[h(`button`,{type:`button`,className:m(q.hours<12&&d.timeInputMeridiemActive),onClick:()=>X(!1),children:`AM`}),h(`button`,{type:`button`,className:m(q.hours>=12&&d.timeInputMeridiemActive),onClick:()=>X(!0),children:`PM`})]})]}),Ae=S||C?g(`div`,{className:m(d.timeInputFooter,A?.footer),style:j?.footer,children:[C&&h(t,{styleType:e.Default,onClick:()=>{let e=new Date;J({hours:e.getHours(),minutes:e.getMinutes()})},children:`Now`}),S&&h(t,{styleType:e.Default,onClick:()=>{G(null),v?.(null)},children:`Clear`})]}):null,Q=g(`div`,{className:m(d.timeInputClock,A?.clock),style:j?.clock,children:[ke,h(ne,{time:q,mode:L,use24Hour:T,minuteStep:w,onChange:J,onCommit:Ce,classNames:A,styles:j}),Ae]}),$=le?null:h(o,{autoComplete:`off`,label:`${de}${Se()?` *`:``}`,value:N,icon:h(ie,{icon:ae}),onIconClick:Y,onClick:Y,readOnly:x,disabled:k,isValid:!Z,customInput:h(oe,{mask:`99:99`,maskPlaceholder:`_`,beforeMaskedStateChange:we}),onChange:e=>Te(e),onBlur:Ee,onFocus:()=>B(!0),onMouseEnter:()=>V(!0),onMouseLeave:()=>V(!1)}),je=b?Q:x?h(ee,{hideHeader:!0,isOpen:F,onClose:()=>I(!1),children:Q}):h(i,{isOpen:F,onOpenChange:I,content:Q,placement:r.Bottom,align:n.Start,closeOnTriggerClick:!1,constrainWidth:!1,children:$});return g(`div`,{className:m(d.timeInput,A?.root,me),style:{...j?.root,...he},...ge,children:[(x||b)&&$,je,h(a,{variant:`error`,message:y?y.getCurrentErrorMessage()??``:O||``,isVisible:Z&&(z||_e)})]})}export{_ as default};
2
2
  //# sourceMappingURL=timeInput.mjs.map