@plenustech/design-system 0.2.3 → 0.2.5

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 (233) hide show
  1. package/README.md +8 -0
  2. package/dist/components/actions/ButtonTile/ButtonTile.module.css.cjs +1 -1
  3. package/dist/components/actions/ButtonTile/ButtonTile.module.css.js +10 -10
  4. package/dist/components/actions/Toolbar/Toolbar.cjs +1 -1
  5. package/dist/components/actions/Toolbar/Toolbar.cjs.map +1 -1
  6. package/dist/components/actions/Toolbar/Toolbar.js +64 -53
  7. package/dist/components/actions/Toolbar/Toolbar.js.map +1 -1
  8. package/dist/components/charts/ChartGauge/ChartGauge.cjs +2 -0
  9. package/dist/components/charts/ChartGauge/ChartGauge.cjs.map +1 -0
  10. package/dist/components/charts/ChartGauge/ChartGauge.js +307 -0
  11. package/dist/components/charts/ChartGauge/ChartGauge.js.map +1 -0
  12. package/dist/components/charts/ChartGauge/ChartGauge.module.css.cjs +2 -0
  13. package/dist/components/charts/ChartGauge/ChartGauge.module.css.cjs.map +1 -0
  14. package/dist/components/charts/ChartGauge/ChartGauge.module.css.js +76 -0
  15. package/dist/components/charts/ChartGauge/ChartGauge.module.css.js.map +1 -0
  16. package/dist/components/charts/ChartGauge/gaugeLayout.cjs +2 -0
  17. package/dist/components/charts/ChartGauge/gaugeLayout.cjs.map +1 -0
  18. package/dist/components/charts/ChartGauge/gaugeLayout.js +107 -0
  19. package/dist/components/charts/ChartGauge/gaugeLayout.js.map +1 -0
  20. package/dist/components/charts/ChartGauge/gaugeReading.cjs +2 -0
  21. package/dist/components/charts/ChartGauge/gaugeReading.cjs.map +1 -0
  22. package/dist/components/charts/ChartGauge/gaugeReading.js +112 -0
  23. package/dist/components/charts/ChartGauge/gaugeReading.js.map +1 -0
  24. package/dist/components/charts/ChartGauge/gaugeScale.cjs +2 -0
  25. package/dist/components/charts/ChartGauge/gaugeScale.cjs.map +1 -0
  26. package/dist/components/charts/ChartGauge/gaugeScale.js +57 -0
  27. package/dist/components/charts/ChartGauge/gaugeScale.js.map +1 -0
  28. package/dist/components/charts/ChartMap/ChartMap.cjs +2 -0
  29. package/dist/components/charts/ChartMap/ChartMap.cjs.map +1 -0
  30. package/dist/components/charts/ChartMap/ChartMap.js +523 -0
  31. package/dist/components/charts/ChartMap/ChartMap.js.map +1 -0
  32. package/dist/components/charts/ChartMap/ChartMap.module.css.cjs +2 -0
  33. package/dist/components/charts/ChartMap/ChartMap.module.css.cjs.map +1 -0
  34. package/dist/components/charts/ChartMap/ChartMap.module.css.js +124 -0
  35. package/dist/components/charts/ChartMap/ChartMap.module.css.js.map +1 -0
  36. package/dist/components/charts/ChartMap/ChartMapLegend.cjs +2 -0
  37. package/dist/components/charts/ChartMap/ChartMapLegend.cjs.map +1 -0
  38. package/dist/components/charts/ChartMap/ChartMapLegend.js +102 -0
  39. package/dist/components/charts/ChartMap/ChartMapLegend.js.map +1 -0
  40. package/dist/components/charts/ChartMap/ChartMapTable.cjs +2 -0
  41. package/dist/components/charts/ChartMap/ChartMapTable.cjs.map +1 -0
  42. package/dist/components/charts/ChartMap/ChartMapTable.js +118 -0
  43. package/dist/components/charts/ChartMap/ChartMapTable.js.map +1 -0
  44. package/dist/components/charts/ChartMap/mapGeometry.cjs +2 -0
  45. package/dist/components/charts/ChartMap/mapGeometry.cjs.map +1 -0
  46. package/dist/components/charts/ChartMap/mapGeometry.js +113 -0
  47. package/dist/components/charts/ChartMap/mapGeometry.js.map +1 -0
  48. package/dist/components/charts/ChartMap/mapLabels.cjs +2 -0
  49. package/dist/components/charts/ChartMap/mapLabels.cjs.map +1 -0
  50. package/dist/components/charts/ChartMap/mapLabels.js +80 -0
  51. package/dist/components/charts/ChartMap/mapLabels.js.map +1 -0
  52. package/dist/components/charts/ChartMap/mapScales.cjs +2 -0
  53. package/dist/components/charts/ChartMap/mapScales.cjs.map +1 -0
  54. package/dist/components/charts/ChartMap/mapScales.js +131 -0
  55. package/dist/components/charts/ChartMap/mapScales.js.map +1 -0
  56. package/dist/components/charts/ChartMap/polylabel.cjs +2 -0
  57. package/dist/components/charts/ChartMap/polylabel.cjs.map +1 -0
  58. package/dist/components/charts/ChartMap/polylabel.js +50 -0
  59. package/dist/components/charts/ChartMap/polylabel.js.map +1 -0
  60. package/dist/components/charts/ChartTimeline/ChartTimeline.cjs +2 -0
  61. package/dist/components/charts/ChartTimeline/ChartTimeline.cjs.map +1 -0
  62. package/dist/components/charts/ChartTimeline/ChartTimeline.js +703 -0
  63. package/dist/components/charts/ChartTimeline/ChartTimeline.js.map +1 -0
  64. package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.cjs +2 -0
  65. package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.cjs.map +1 -0
  66. package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.js +124 -0
  67. package/dist/components/charts/ChartTimeline/ChartTimeline.module.css.js.map +1 -0
  68. package/dist/components/charts/ChartTimeline/ChartTimelineTable.cjs +2 -0
  69. package/dist/components/charts/ChartTimeline/ChartTimelineTable.cjs.map +1 -0
  70. package/dist/components/charts/ChartTimeline/ChartTimelineTable.js +42 -0
  71. package/dist/components/charts/ChartTimeline/ChartTimelineTable.js.map +1 -0
  72. package/dist/components/charts/ChartTimeline/timelineLayout.cjs +2 -0
  73. package/dist/components/charts/ChartTimeline/timelineLayout.cjs.map +1 -0
  74. package/dist/components/charts/ChartTimeline/timelineLayout.js +109 -0
  75. package/dist/components/charts/ChartTimeline/timelineLayout.js.map +1 -0
  76. package/dist/components/charts/ChartTimeline/timelineTime.cjs +2 -0
  77. package/dist/components/charts/ChartTimeline/timelineTime.cjs.map +1 -0
  78. package/dist/components/charts/ChartTimeline/timelineTime.js +91 -0
  79. package/dist/components/charts/ChartTimeline/timelineTime.js.map +1 -0
  80. package/dist/components/charts/ChartTimeline/timelineTooltip.cjs +2 -0
  81. package/dist/components/charts/ChartTimeline/timelineTooltip.cjs.map +1 -0
  82. package/dist/components/charts/ChartTimeline/timelineTooltip.js +77 -0
  83. package/dist/components/charts/ChartTimeline/timelineTooltip.js.map +1 -0
  84. package/dist/components/charts/core/ChartLegend.cjs +1 -1
  85. package/dist/components/charts/core/ChartLegend.cjs.map +1 -1
  86. package/dist/components/charts/core/ChartLegend.js +37 -25
  87. package/dist/components/charts/core/ChartLegend.js.map +1 -1
  88. package/dist/components/charts/core/useChartMetrics.cjs +1 -1
  89. package/dist/components/charts/core/useChartMetrics.cjs.map +1 -1
  90. package/dist/components/charts/core/useChartMetrics.js +20 -25
  91. package/dist/components/charts/core/useChartMetrics.js.map +1 -1
  92. package/dist/components/data-display/CodeBlock/syntax.cjs +10 -3
  93. package/dist/components/data-display/CodeBlock/syntax.cjs.map +1 -1
  94. package/dist/components/data-display/CodeBlock/syntax.js +68 -48
  95. package/dist/components/data-display/CodeBlock/syntax.js.map +1 -1
  96. package/dist/components/data-display/List/List.cjs.map +1 -1
  97. package/dist/components/data-display/List/List.js.map +1 -1
  98. package/dist/components/data-display/List/List.module.css.cjs +1 -1
  99. package/dist/components/data-display/List/List.module.css.js +34 -24
  100. package/dist/components/data-display/List/List.module.css.js.map +1 -1
  101. package/dist/components/data-display/List/ListingOptions.cjs +1 -1
  102. package/dist/components/data-display/List/ListingOptions.cjs.map +1 -1
  103. package/dist/components/data-display/List/ListingOptions.js +98 -74
  104. package/dist/components/data-display/List/ListingOptions.js.map +1 -1
  105. package/dist/components/data-display/List/useListing.cjs.map +1 -1
  106. package/dist/components/data-display/List/useListing.js.map +1 -1
  107. package/dist/components/data-display/Timeline/Timeline.cjs +1 -1
  108. package/dist/components/data-display/Timeline/Timeline.cjs.map +1 -1
  109. package/dist/components/data-display/Timeline/Timeline.js +6 -6
  110. package/dist/components/data-display/Timeline/Timeline.js.map +1 -1
  111. package/dist/components/data-display/Timeline/Timeline.module.css.cjs +1 -1
  112. package/dist/components/data-display/Timeline/Timeline.module.css.js +18 -16
  113. package/dist/components/data-display/Timeline/Timeline.module.css.js.map +1 -1
  114. package/dist/components/forms/Checkbox/Checkbox.module.css.cjs +1 -1
  115. package/dist/components/forms/Checkbox/Checkbox.module.css.js +5 -5
  116. package/dist/components/forms/CheckboxGroup/CheckboxGroup.module.css.cjs +1 -1
  117. package/dist/components/forms/CheckboxGroup/CheckboxGroup.module.css.js +1 -1
  118. package/dist/components/forms/ComboBox/ComboBox.cjs.map +1 -1
  119. package/dist/components/forms/ComboBox/ComboBox.js.map +1 -1
  120. package/dist/components/forms/Field/Field.cjs +1 -1
  121. package/dist/components/forms/Field/Field.cjs.map +1 -1
  122. package/dist/components/forms/Field/Field.js +22 -22
  123. package/dist/components/forms/Field/Field.js.map +1 -1
  124. package/dist/components/forms/Field/Field.module.css.cjs +1 -1
  125. package/dist/components/forms/Field/Field.module.css.js +19 -17
  126. package/dist/components/forms/Field/Field.module.css.js.map +1 -1
  127. package/dist/components/forms/InputText/InputText.cjs +1 -1
  128. package/dist/components/forms/InputText/InputText.cjs.map +1 -1
  129. package/dist/components/forms/InputText/InputText.js +24 -24
  130. package/dist/components/forms/InputText/InputText.js.map +1 -1
  131. package/dist/components/forms/InputText/InputText.module.css.cjs +1 -1
  132. package/dist/components/forms/InputText/InputText.module.css.js +9 -7
  133. package/dist/components/forms/InputText/InputText.module.css.js.map +1 -1
  134. package/dist/components/forms/RadioGroup/RadioGroup.module.css.cjs +1 -1
  135. package/dist/components/forms/RadioGroup/RadioGroup.module.css.js +4 -4
  136. package/dist/components/forms/Select/Select.cjs.map +1 -1
  137. package/dist/components/forms/Select/Select.js.map +1 -1
  138. package/dist/components/forms/Switch/Switch.module.css.cjs +1 -1
  139. package/dist/components/forms/Switch/Switch.module.css.js +6 -6
  140. package/dist/components/icons/suite.cjs +1 -0
  141. package/dist/components/icons/suite.js +10894 -0
  142. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  143. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  144. package/dist/components/navigation/Pagination/Pagination.js +71 -44
  145. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  146. package/dist/components/navigation/Pagination/Pagination.module.css.cjs +1 -1
  147. package/dist/components/navigation/Pagination/Pagination.module.css.js +18 -14
  148. package/dist/components/navigation/Pagination/Pagination.module.css.js.map +1 -1
  149. package/dist/components/navigation/TabsNav/TabsNav.cjs +2 -0
  150. package/dist/components/navigation/TabsNav/TabsNav.cjs.map +1 -0
  151. package/dist/components/navigation/TabsNav/TabsNav.js +21 -0
  152. package/dist/components/navigation/TabsNav/TabsNav.js.map +1 -0
  153. package/dist/components/navigation/TabsNav/TabsNav.module.css.cjs +2 -0
  154. package/dist/components/navigation/TabsNav/TabsNav.module.css.cjs.map +1 -0
  155. package/dist/components/navigation/TabsNav/TabsNav.module.css.js +18 -0
  156. package/dist/components/navigation/TabsNav/TabsNav.module.css.js.map +1 -0
  157. package/dist/components/overlays/Dialog/Dialog.cjs.map +1 -1
  158. package/dist/components/overlays/Dialog/Dialog.js.map +1 -1
  159. package/dist/components/overlays/Dialog/DialogFrame.cjs +1 -1
  160. package/dist/components/overlays/Dialog/DialogFrame.cjs.map +1 -1
  161. package/dist/components/overlays/Dialog/DialogFrame.js +30 -30
  162. package/dist/components/overlays/Dialog/DialogFrame.js.map +1 -1
  163. package/dist/components/overlays/Drawer/Drawer.cjs.map +1 -1
  164. package/dist/components/overlays/Drawer/Drawer.js.map +1 -1
  165. package/dist/components/overlays/Menu/Menu.cjs +1 -1
  166. package/dist/components/overlays/Menu/Menu.cjs.map +1 -1
  167. package/dist/components/overlays/Menu/Menu.js +37 -36
  168. package/dist/components/overlays/Menu/Menu.js.map +1 -1
  169. package/dist/components/overlays/Menu/keyShortcuts.cjs +2 -0
  170. package/dist/components/overlays/Menu/keyShortcuts.cjs.map +1 -0
  171. package/dist/components/overlays/Menu/keyShortcuts.js +55 -0
  172. package/dist/components/overlays/Menu/keyShortcuts.js.map +1 -0
  173. package/dist/components/overlays/Tooltip/Tooltip.cjs +1 -1
  174. package/dist/components/overlays/Tooltip/Tooltip.cjs.map +1 -1
  175. package/dist/components/overlays/Tooltip/Tooltip.js +81 -56
  176. package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
  177. package/dist/design-system.css +1 -1
  178. package/dist/icons.cjs +2 -0
  179. package/dist/icons.cjs.map +1 -0
  180. package/dist/icons.js +2054 -0
  181. package/dist/icons.js.map +1 -0
  182. package/dist/index.cjs +1 -1
  183. package/dist/index.js +184 -174
  184. package/dist/index.js.map +1 -1
  185. package/dist/types/components/charts/ChartGauge/ChartGauge.d.ts +83 -0
  186. package/dist/types/components/charts/ChartGauge/gaugeLayout.d.ts +64 -0
  187. package/dist/types/components/charts/ChartGauge/gaugeReading.d.ts +97 -0
  188. package/dist/types/components/charts/ChartGauge/gaugeScale.d.ts +38 -0
  189. package/dist/types/components/charts/ChartGauge/index.d.ts +2 -0
  190. package/dist/types/components/charts/ChartMap/ChartMap.d.ts +104 -0
  191. package/dist/types/components/charts/ChartMap/ChartMapLegend.d.ts +44 -0
  192. package/dist/types/components/charts/ChartMap/ChartMapTable.d.ts +38 -0
  193. package/dist/types/components/charts/ChartMap/index.d.ts +4 -0
  194. package/dist/types/components/charts/ChartMap/mapGeometry.d.ts +56 -0
  195. package/dist/types/components/charts/ChartMap/mapLabels.d.ts +51 -0
  196. package/dist/types/components/charts/ChartMap/mapScales.d.ts +76 -0
  197. package/dist/types/components/charts/ChartMap/polylabel.d.ts +9 -0
  198. package/dist/types/components/charts/ChartTimeline/ChartTimeline.d.ts +137 -0
  199. package/dist/types/components/charts/ChartTimeline/ChartTimelineTable.d.ts +25 -0
  200. package/dist/types/components/charts/ChartTimeline/index.d.ts +2 -0
  201. package/dist/types/components/charts/ChartTimeline/timelineLayout.d.ts +70 -0
  202. package/dist/types/components/charts/ChartTimeline/timelineTime.d.ts +16 -0
  203. package/dist/types/components/charts/ChartTimeline/timelineTooltip.d.ts +45 -0
  204. package/dist/types/components/charts/core/ChartLegend.d.ts +3 -1
  205. package/dist/types/components/data-display/CodeBlock/syntax.d.ts +1 -1
  206. package/dist/types/components/data-display/List/List.d.ts +1 -1
  207. package/dist/types/components/data-display/List/useListing.d.ts +7 -1
  208. package/dist/types/components/data-display/Timeline/Timeline.d.ts +4 -1
  209. package/dist/types/components/data-display/Timeline/index.d.ts +1 -1
  210. package/dist/types/components/forms/ComboBox/ComboBox.d.ts +7 -1
  211. package/dist/types/components/forms/Field/Field.d.ts +1 -1
  212. package/dist/types/components/forms/InputText/InputText.d.ts +1 -1
  213. package/dist/types/components/forms/Select/Select.d.ts +5 -1
  214. package/dist/types/components/icons/suite.d.ts +2051 -0
  215. package/dist/types/components/navigation/Pagination/Pagination.d.ts +13 -1
  216. package/dist/types/components/navigation/Pagination/index.d.ts +1 -1
  217. package/dist/types/components/navigation/TabsNav/TabsNav.d.ts +20 -0
  218. package/dist/types/components/navigation/TabsNav/index.d.ts +2 -0
  219. package/dist/types/components/overlays/Dialog/Dialog.d.ts +19 -7
  220. package/dist/types/components/overlays/Dialog/DialogFrame.d.ts +8 -2
  221. package/dist/types/components/overlays/Drawer/Drawer.d.ts +2 -2
  222. package/dist/types/components/overlays/Menu/Menu.d.ts +3 -1
  223. package/dist/types/components/overlays/Menu/keyShortcuts.d.ts +2 -0
  224. package/dist/types/components/overlays/Tooltip/Tooltip.d.ts +26 -5
  225. package/dist/types/icons.d.ts +6 -0
  226. package/dist/types/index.d.ts +11 -3
  227. package/dist/types/utils/formatters/formatarDuracao.d.ts +5 -0
  228. package/dist/types/utils/formatters/index.d.ts +1 -0
  229. package/dist/utils/formatters/formatarDuracao.cjs +2 -0
  230. package/dist/utils/formatters/formatarDuracao.cjs.map +1 -0
  231. package/dist/utils/formatters/formatarDuracao.js +10 -0
  232. package/dist/utils/formatters/formatarDuracao.js.map +1 -0
  233. package/package.json +10 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.js","sources":["../../../../src/components/overlays/Drawer/Drawer.tsx"],"sourcesContent":["import type { DialogProps } from '../Dialog';\nimport { DialogFrame } from '../Dialog/DialogFrame';\nimport styles from './Drawer.module.css';\n\nexport type DrawerSide = 'left' | 'right';\nexport type DrawerSize = 'sm' | 'md' | 'lg';\n\nexport interface DrawerProps extends Omit<DialogProps, 'icon' | 'role' | 'size'> {\n side?: DrawerSide;\n size?: DrawerSize;\n}\n\n/** Painel modal preso a lateral da tela, com a mesma mecanica do `Dialog`: foco preso, Esc fecha, a pagina nao rola. */\nexport function Drawer({ side = 'right', size = 'md', ...props }: DrawerProps) {\n return (\n <DialogFrame\n {...props}\n surfaceClassName={[styles.drawer, styles[size]].join(' ')}\n underlayClassName={[styles.underlay, styles[side]].join(' ')}\n />\n );\n}\n"],"names":["Drawer","side","size","props","jsx","DialogFrame","styles"],"mappings":";;;AAaO,SAASA,EAAO,EAAE,MAAAC,IAAO,SAAS,MAAAC,IAAO,MAAM,GAAGC,KAAsB;AAC7E,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACE,GAAGF;AAAA,MACJ,kBAAkB,CAACG,EAAO,QAAQA,EAAOJ,CAAI,CAAC,EAAE,KAAK,GAAG;AAAA,MACxD,mBAAmB,CAACI,EAAO,UAAUA,EAAOL,CAAI,CAAC,EAAE,KAAK,GAAG;AAAA,IAAA;AAAA,EAAA;AAGjE;"}
1
+ {"version":3,"file":"Drawer.js","sources":["../../../../src/components/overlays/Drawer/Drawer.tsx"],"sourcesContent":["import type { DialogBaseProps, DialogTitledProps } from '../Dialog/Dialog';\nimport { DialogFrame } from '../Dialog/DialogFrame';\nimport styles from './Drawer.module.css';\n\nexport type DrawerSide = 'left' | 'right';\nexport type DrawerSize = 'sm' | 'md' | 'lg';\n\nexport interface DrawerProps extends DialogBaseProps, Omit<DialogTitledProps, 'icon'> {\n side?: DrawerSide;\n size?: DrawerSize;\n}\n\n/** Painel modal preso a lateral da tela, com a mesma mecanica do `Dialog`: foco preso, Esc fecha, a pagina nao rola. */\nexport function Drawer({ side = 'right', size = 'md', ...props }: DrawerProps) {\n return (\n <DialogFrame\n {...props}\n surfaceClassName={[styles.drawer, styles[size]].join(' ')}\n underlayClassName={[styles.underlay, styles[side]].join(' ')}\n />\n );\n}\n"],"names":["Drawer","side","size","props","jsx","DialogFrame","styles"],"mappings":";;;AAaO,SAASA,EAAO,EAAE,MAAAC,IAAO,SAAS,MAAAC,IAAO,MAAM,GAAGC,KAAsB;AAC7E,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACE,GAAGF;AAAA,MACJ,kBAAkB,CAACG,EAAO,QAAQA,EAAOJ,CAAI,CAAC,EAAE,KAAK,GAAG;AAAA,MACxD,mBAAmB,CAACI,EAAO,UAAUA,EAAOL,CAAI,CAAC,EAAE,KAAK,GAAG;AAAA,IAAA;AAAA,EAAA;AAGjE;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),c=require("react"),A=require("react-dom"),E=require("@react-aria/focus"),R=require("@react-aria/overlays"),I=require("../../../hooks/useMergedRefs.cjs"),o=require("./Menu.module.css.cjs"),T=require("../../../hooks/useSelection/useSelection.cjs"),B=require("../../icons/icons.cjs");function S(n,y){return u=>{n==null||n(u),y(u)}}function F({children:n,defaultOpen:y=!1,items:u,label:D,onOpenChange:a,open:h}){const l=c.useRef(null),[p,w]=c.useState(y),[M,i]=c.useState("first"),f=h??p;function k(t){w(t),a==null||a(t)}function b(t){i(t),k(!0)}function x(t){var g;k(!1),t&&((g=l.current)==null||g.focus())}const m=n.props,d=I.useMergedRefs(l,m.ref),j=c.cloneElement(n,{ref:d,"aria-haspopup":"menu","aria-expanded":f,onClick:S(m.onClick,()=>f?x(!0):b("first")),onKeyDown:S(m.onKeyDown,t=>{(t.key==="ArrowDown"||t.key==="ArrowUp")&&(t.preventDefault(),b(t.key==="ArrowDown"?"first":"last"))})});return r.jsxs(r.Fragment,{children:[j,f&&typeof document<"u"&&A.createPortal(r.jsx(E.FocusScope,{children:r.jsx(H,{items:u,label:D,openedWith:M,onClose:x,triggerRef:l})}),document.body)]})}function K(n){return"items"in n}function H({items:n,label:y,onClose:u,openedWith:D,triggerRef:a}){var q;const h=c.useRef(null),l=c.useRef(new Map),p=c.useMemo(()=>n.flatMap(e=>K(e)?e.items:[e]),[n]),w=c.useMemo(()=>p.map(e=>({key:e.key,disabled:e.disabled,textValue:e.label})),[p]),M=T.useSelection({items:w,mode:"none"}),{focusedKey:i,focusFirst:f,focusLast:k,focusNext:b,focusPrevious:x,search:m}=M,{overlayProps:d}=R.useOverlay({isOpen:!0,onClose:()=>u(!1),isDismissable:!0,shouldCloseOnBlur:!1,shouldCloseOnInteractOutside:e=>{var s;return!((s=a.current)!=null&&s.contains(e))}},h),{overlayProps:j}=R.useOverlayPosition({targetRef:a,overlayRef:h,placement:"bottom start",offset:6,containerPadding:8,isOpen:!0}),t=Math.min(Number((q=j.style)==null?void 0:q.maxHeight)||360,360);c.useEffect(()=>{D==="last"?k():f()},[]),c.useEffect(()=>{var e;i&&((e=l.current.get(i))==null||e.focus())},[i]);function g(e){var s;e.disabled||(u(!0),(s=e.onSelect)==null||s.call(e))}function N(e){const s=e.checked!==void 0;return r.jsxs("button",{"aria-checked":s?e.checked:void 0,"aria-keyshortcuts":e.shortcut,className:[o.default.item,e.tone==="danger"&&o.default.danger].filter(Boolean).join(" "),disabled:e.disabled,onClick:()=>g(e),ref:O=>{O?l.current.set(e.key,O):l.current.delete(e.key)},role:s?"menuitemcheckbox":"menuitem",tabIndex:i===e.key?0:-1,type:"button",children:[e.icon&&r.jsx("span",{"aria-hidden":"true",className:o.default.icon,children:e.icon}),r.jsx("span",{className:o.default.label,children:e.label}),e.shortcut&&r.jsx("kbd",{"aria-hidden":"true",className:o.default.shortcut,children:e.shortcut}),s&&r.jsx(B.IconCheck,{className:[o.default.check,e.checked&&o.default.checkOn].filter(Boolean).join(" ")})]},e.key)}function P(e){e.key==="ArrowDown"?(e.preventDefault(),b()):e.key==="ArrowUp"?(e.preventDefault(),x()):e.key==="Home"?(e.preventDefault(),f()):e.key==="End"?(e.preventDefault(),k()):e.key==="Escape"||e.key==="Tab"?u(!0):e.key.length===1&&!e.metaKey&&!e.ctrlKey&&m(e.key)}return r.jsx("div",{...d,"data-react-aria-top-layer":"true",ref:h,className:o.default.menu,style:{...j.style,maxHeight:t},role:"menu","aria-label":y,onKeyDown:e=>{var s;P(e),(s=d.onKeyDown)==null||s.call(d,e)},children:n.map((e,s)=>K(e)?r.jsxs("div",{"aria-label":e.title,className:o.default.section,role:"group",children:[s>0&&r.jsx("div",{"aria-hidden":"true",className:o.default.divider}),e.title&&r.jsx("div",{"aria-hidden":"true",className:o.default.sectionTitle,children:e.title}),e.items.map(N)]},e.key):N(e))})}exports.Menu=F;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),c=require("react"),P=require("react-dom"),E=require("@react-aria/focus"),K=require("@react-aria/overlays"),I=require("../../../hooks/useMergedRefs.cjs"),T=require("./keyShortcuts.cjs"),n=require("./Menu.module.css.cjs"),B=require("../../../hooks/useSelection/useSelection.cjs"),F=require("../../icons/icons.cjs");function O(o,y){return u=>{o==null||o(u),y(u)}}function H({children:o,defaultOpen:y=!1,items:u,label:D,onOpenChange:a,open:h}){const l=c.useRef(null),[m,w]=c.useState(y),[M,i]=c.useState("first"),f=h??m;function k(t){w(t),a==null||a(t)}function b(t){i(t),k(!0)}function x(t){var g;k(!1),t&&((g=l.current)==null||g.focus())}const p=o.props,d=I.useMergedRefs(l,p.ref),j=c.cloneElement(o,{ref:d,"aria-haspopup":"menu","aria-expanded":f,onClick:O(p.onClick,()=>f?x(!0):b("first")),onKeyDown:O(p.onKeyDown,t=>{(t.key==="ArrowDown"||t.key==="ArrowUp")&&(t.preventDefault(),b(t.key==="ArrowDown"?"first":"last"))})});return r.jsxs(r.Fragment,{children:[j,f&&typeof document<"u"&&P.createPortal(r.jsx(E.FocusScope,{children:r.jsx(v,{items:u,label:D,openedWith:M,onClose:x,triggerRef:l})}),document.body)]})}function R(o){return"items"in o}function v({items:o,label:y,onClose:u,openedWith:D,triggerRef:a}){var S;const h=c.useRef(null),l=c.useRef(new Map),m=c.useMemo(()=>o.flatMap(e=>R(e)?e.items:[e]),[o]),w=c.useMemo(()=>m.map(e=>({key:e.key,disabled:e.disabled,textValue:e.label})),[m]),M=B.useSelection({items:w,mode:"none"}),{focusedKey:i,focusFirst:f,focusLast:k,focusNext:b,focusPrevious:x,search:p}=M,{overlayProps:d}=K.useOverlay({isOpen:!0,onClose:()=>u(!1),isDismissable:!0,shouldCloseOnBlur:!1,shouldCloseOnInteractOutside:e=>{var s;return!((s=a.current)!=null&&s.contains(e))}},h),{overlayProps:j}=K.useOverlayPosition({targetRef:a,overlayRef:h,placement:"bottom start",offset:6,containerPadding:8,isOpen:!0}),t=Math.min(Number((S=j.style)==null?void 0:S.maxHeight)||360,360);c.useEffect(()=>{D==="last"?k():f()},[]),c.useEffect(()=>{var e;i&&((e=l.current.get(i))==null||e.focus())},[i]);function g(e){var s;e.disabled||(u(!0),(s=e.onSelect)==null||s.call(e))}function N(e){const s=e.checked!==void 0;return r.jsxs("button",{"aria-checked":s?e.checked:void 0,"aria-keyshortcuts":e.shortcutKeys??(e.shortcut?T.toAriaKeyShortcuts(e.shortcut):void 0),className:[n.default.item,e.tone==="danger"&&n.default.danger].filter(Boolean).join(" "),disabled:e.disabled,onClick:()=>g(e),ref:q=>{q?l.current.set(e.key,q):l.current.delete(e.key)},role:s?"menuitemcheckbox":"menuitem",tabIndex:i===e.key?0:-1,type:"button",children:[e.icon&&r.jsx("span",{"aria-hidden":"true",className:n.default.icon,children:e.icon}),r.jsx("span",{className:n.default.label,children:e.label}),e.shortcut&&r.jsx("kbd",{"aria-hidden":"true",className:n.default.shortcut,children:e.shortcut}),s&&r.jsx(F.IconCheck,{className:[n.default.check,e.checked&&n.default.checkOn].filter(Boolean).join(" ")})]},e.key)}function A(e){e.key==="ArrowDown"?(e.preventDefault(),b()):e.key==="ArrowUp"?(e.preventDefault(),x()):e.key==="Home"?(e.preventDefault(),f()):e.key==="End"?(e.preventDefault(),k()):e.key==="Escape"||e.key==="Tab"?u(!0):e.key.length===1&&!e.metaKey&&!e.ctrlKey&&p(e.key)}return r.jsx("div",{...d,"data-react-aria-top-layer":"true",ref:h,className:n.default.menu,style:{...j.style,maxHeight:t},role:"menu","aria-label":y,onKeyDown:e=>{var s;A(e),(s=d.onKeyDown)==null||s.call(d,e)},children:o.map((e,s)=>R(e)?r.jsxs("div",{"aria-label":e.title,className:n.default.section,role:"group",children:[s>0&&r.jsx("div",{"aria-hidden":"true",className:n.default.divider}),e.title&&r.jsx("div",{"aria-hidden":"true",className:n.default.sectionTitle,children:e.title}),e.items.map(N)]},e.key):N(e))})}exports.Menu=H;
2
2
  //# sourceMappingURL=Menu.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.cjs","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito a direita, como `Ctrl+D`, e anunciado em `aria-keyshortcuts`. */\n shortcut?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcut}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.cjs","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport { toAriaKeyShortcuts } from './keyShortcuts';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito à direita, como `Ctrl+D` ou `⌘⇧D`; convertido nos nomes de tecla de `aria-keyshortcuts`. */\n shortcut?: string;\n /** Valor de `aria-keyshortcuts` quando a conversão do `shortcut` não basta, como `Control+Shift+D Meta+Shift+D`. */\n shortcutKeys?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcutKeys ?? (item.shortcut ? toAriaKeyShortcuts(item.shortcut) : undefined)}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","toAriaKeyShortcuts","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
@@ -1,19 +1,20 @@
1
1
  import { jsxs as K, Fragment as F, jsx as n } from "react/jsx-runtime";
2
- import { useRef as M, useState as P, cloneElement as H, useMemo as R, useEffect as S } from "react";
2
+ import { useRef as M, useState as I, cloneElement as H, useMemo as P, useEffect as R } from "react";
3
3
  import { createPortal as T } from "react-dom";
4
4
  import { FocusScope as C } from "@react-aria/focus";
5
5
  import { useOverlay as L, useOverlayPosition as U } from "@react-aria/overlays";
6
6
  import { useMergedRefs as W } from "../../../hooks/useMergedRefs.js";
7
- import t from "./Menu.module.css.js";
8
- import { useSelection as z } from "../../../hooks/useSelection/useSelection.js";
9
- import { IconCheck as V } from "../../icons/icons.js";
10
- function j(s, d) {
7
+ import { toAriaKeyShortcuts as z } from "./keyShortcuts.js";
8
+ import s from "./Menu.module.css.js";
9
+ import { useSelection as V } from "../../../hooks/useSelection/useSelection.js";
10
+ import { IconCheck as q } from "../../icons/icons.js";
11
+ function j(t, d) {
11
12
  return (c) => {
12
- s == null || s(c), d(c);
13
+ t == null || t(c), d(c);
13
14
  };
14
15
  }
15
- function ee({ children: s, defaultOpen: d = !1, items: c, label: g, onOpenChange: l, open: m }) {
16
- const i = M(null), [h, N] = P(d), [x, a] = P("first"), u = m ?? h;
16
+ function oe({ children: t, defaultOpen: d = !1, items: c, label: g, onOpenChange: l, open: m }) {
17
+ const i = M(null), [p, N] = I(d), [x, a] = I("first"), u = m ?? p;
17
18
  function y(o) {
18
19
  N(o), l == null || l(o);
19
20
  }
@@ -24,15 +25,15 @@ function ee({ children: s, defaultOpen: d = !1, items: c, label: g, onOpenChange
24
25
  var D;
25
26
  y(!1), o && ((D = i.current) == null || D.focus());
26
27
  }
27
- const p = s.props, f = W(i, p.ref), w = H(s, {
28
+ const h = t.props, f = W(i, h.ref), w = H(t, {
28
29
  ref: f,
29
30
  "aria-haspopup": "menu",
30
31
  "aria-expanded": u,
31
32
  onClick: j(
32
- p.onClick,
33
+ h.onClick,
33
34
  () => u ? b(!0) : k("first")
34
35
  ),
35
- onKeyDown: j(p.onKeyDown, (o) => {
36
+ onKeyDown: j(h.onKeyDown, (o) => {
36
37
  (o.key === "ArrowDown" || o.key === "ArrowUp") && (o.preventDefault(), k(o.key === "ArrowDown" ? "first" : "last"));
37
38
  })
38
39
  });
@@ -42,7 +43,7 @@ function ee({ children: s, defaultOpen: d = !1, items: c, label: g, onOpenChange
42
43
  // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.
43
44
  // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.
44
45
  /* @__PURE__ */ n(C, { children: /* @__PURE__ */ n(
45
- q,
46
+ v,
46
47
  {
47
48
  items: c,
48
49
  label: g,
@@ -55,21 +56,21 @@ function ee({ children: s, defaultOpen: d = !1, items: c, label: g, onOpenChange
55
56
  )
56
57
  ] });
57
58
  }
58
- function E(s) {
59
- return "items" in s;
59
+ function E(t) {
60
+ return "items" in t;
60
61
  }
61
- function q({
62
- items: s,
62
+ function v({
63
+ items: t,
63
64
  label: d,
64
65
  onClose: c,
65
66
  openedWith: g,
66
67
  triggerRef: l
67
68
  }) {
68
69
  var A;
69
- const m = M(null), i = M(/* @__PURE__ */ new Map()), h = R(() => s.flatMap((e) => E(e) ? e.items : [e]), [s]), N = R(
70
- () => h.map((e) => ({ key: e.key, disabled: e.disabled, textValue: e.label })),
71
- [h]
72
- ), x = z({ items: N, mode: "none" }), { focusedKey: a, focusFirst: u, focusLast: y, focusNext: k, focusPrevious: b, search: p } = x, { overlayProps: f } = L(
70
+ const m = M(null), i = M(/* @__PURE__ */ new Map()), p = P(() => t.flatMap((e) => E(e) ? e.items : [e]), [t]), N = P(
71
+ () => p.map((e) => ({ key: e.key, disabled: e.disabled, textValue: e.label })),
72
+ [p]
73
+ ), x = V({ items: N, mode: "none" }), { focusedKey: a, focusFirst: u, focusLast: y, focusNext: k, focusPrevious: b, search: h } = x, { overlayProps: f } = L(
73
74
  {
74
75
  isOpen: !0,
75
76
  onClose: () => c(!1),
@@ -89,9 +90,9 @@ function q({
89
90
  containerPadding: 8,
90
91
  isOpen: !0
91
92
  }), o = Math.min(Number((A = w.style) == null ? void 0 : A.maxHeight) || 360, 360);
92
- S(() => {
93
+ R(() => {
93
94
  g === "last" ? y() : u();
94
- }, []), S(() => {
95
+ }, []), R(() => {
95
96
  var e;
96
97
  a && ((e = i.current.get(a)) == null || e.focus());
97
98
  }, [a]);
@@ -105,28 +106,28 @@ function q({
105
106
  "button",
106
107
  {
107
108
  "aria-checked": r ? e.checked : void 0,
108
- "aria-keyshortcuts": e.shortcut,
109
- className: [t.item, e.tone === "danger" && t.danger].filter(Boolean).join(" "),
109
+ "aria-keyshortcuts": e.shortcutKeys ?? (e.shortcut ? z(e.shortcut) : void 0),
110
+ className: [s.item, e.tone === "danger" && s.danger].filter(Boolean).join(" "),
110
111
  disabled: e.disabled,
111
112
  onClick: () => D(e),
112
- ref: (I) => {
113
- I ? i.current.set(e.key, I) : i.current.delete(e.key);
113
+ ref: (S) => {
114
+ S ? i.current.set(e.key, S) : i.current.delete(e.key);
114
115
  },
115
116
  role: r ? "menuitemcheckbox" : "menuitem",
116
117
  tabIndex: a === e.key ? 0 : -1,
117
118
  type: "button",
118
119
  children: [
119
- e.icon && /* @__PURE__ */ n("span", { "aria-hidden": "true", className: t.icon, children: e.icon }),
120
- /* @__PURE__ */ n("span", { className: t.label, children: e.label }),
121
- e.shortcut && /* @__PURE__ */ n("kbd", { "aria-hidden": "true", className: t.shortcut, children: e.shortcut }),
122
- r && /* @__PURE__ */ n(V, { className: [t.check, e.checked && t.checkOn].filter(Boolean).join(" ") })
120
+ e.icon && /* @__PURE__ */ n("span", { "aria-hidden": "true", className: s.icon, children: e.icon }),
121
+ /* @__PURE__ */ n("span", { className: s.label, children: e.label }),
122
+ e.shortcut && /* @__PURE__ */ n("kbd", { "aria-hidden": "true", className: s.shortcut, children: e.shortcut }),
123
+ r && /* @__PURE__ */ n(q, { className: [s.check, e.checked && s.checkOn].filter(Boolean).join(" ") })
123
124
  ]
124
125
  },
125
126
  e.key
126
127
  );
127
128
  }
128
129
  function B(e) {
129
- e.key === "ArrowDown" ? (e.preventDefault(), k()) : e.key === "ArrowUp" ? (e.preventDefault(), b()) : e.key === "Home" ? (e.preventDefault(), u()) : e.key === "End" ? (e.preventDefault(), y()) : e.key === "Escape" || e.key === "Tab" ? c(!0) : e.key.length === 1 && !e.metaKey && !e.ctrlKey && p(e.key);
130
+ e.key === "ArrowDown" ? (e.preventDefault(), k()) : e.key === "ArrowUp" ? (e.preventDefault(), b()) : e.key === "Home" ? (e.preventDefault(), u()) : e.key === "End" ? (e.preventDefault(), y()) : e.key === "Escape" || e.key === "Tab" ? c(!0) : e.key.length === 1 && !e.metaKey && !e.ctrlKey && h(e.key);
130
131
  }
131
132
  return /* @__PURE__ */ n(
132
133
  "div",
@@ -134,7 +135,7 @@ function q({
134
135
  ...f,
135
136
  "data-react-aria-top-layer": "true",
136
137
  ref: m,
137
- className: t.menu,
138
+ className: s.menu,
138
139
  style: { ...w.style, maxHeight: o },
139
140
  role: "menu",
140
141
  "aria-label": d,
@@ -142,15 +143,15 @@ function q({
142
143
  var r;
143
144
  B(e), (r = f.onKeyDown) == null || r.call(f, e);
144
145
  },
145
- children: s.map((e, r) => E(e) ? /* @__PURE__ */ K("div", { "aria-label": e.title, className: t.section, role: "group", children: [
146
- r > 0 && /* @__PURE__ */ n("div", { "aria-hidden": "true", className: t.divider }),
147
- e.title && /* @__PURE__ */ n("div", { "aria-hidden": "true", className: t.sectionTitle, children: e.title }),
146
+ children: t.map((e, r) => E(e) ? /* @__PURE__ */ K("div", { "aria-label": e.title, className: s.section, role: "group", children: [
147
+ r > 0 && /* @__PURE__ */ n("div", { "aria-hidden": "true", className: s.divider }),
148
+ e.title && /* @__PURE__ */ n("div", { "aria-hidden": "true", className: s.sectionTitle, children: e.title }),
148
149
  e.items.map(O)
149
150
  ] }, e.key) : O(e))
150
151
  }
151
152
  );
152
153
  }
153
154
  export {
154
- ee as Menu
155
+ oe as Menu
155
156
  };
156
157
  //# sourceMappingURL=Menu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Menu.js","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito a direita, como `Ctrl+D`, e anunciado em `aria-keyshortcuts`. */\n shortcut?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcut}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
1
+ {"version":3,"file":"Menu.js","sources":["../../../../src/components/overlays/Menu/Menu.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { FocusScope } from '@react-aria/focus';\nimport { useOverlay, useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport { useSelection, type SelectionItem } from '../../../hooks/useSelection';\nimport { IconCheck } from '../../icons';\nimport { toAriaKeyShortcuts } from './keyShortcuts';\nimport styles from './Menu.module.css';\n\nexport interface MenuItem {\n /** Com ele, o item e de marcar e mostra o visto quando marcado, como o tipo atual de um bloco. */\n checked?: boolean;\n disabled?: boolean;\n /** Icone decorativo antes do texto. */\n icon?: ReactNode;\n key: string;\n label: string;\n onSelect?: () => void;\n /** Atalho escrito à direita, como `Ctrl+D` ou `⌘⇧D`; convertido nos nomes de tecla de `aria-keyshortcuts`. */\n shortcut?: string;\n /** Valor de `aria-keyshortcuts` quando a conversão do `shortcut` não basta, como `Control+Shift+D Meta+Shift+D`. */\n shortcutKeys?: string;\n /** `danger` para a acao que destroi, como remover. */\n tone?: 'danger';\n}\n\n/** Grupo de itens, com titulo opcional; entre dois grupos, o menu desenha o divisor. */\nexport interface MenuSection {\n items: readonly MenuItem[];\n key: string;\n title?: string;\n}\n\nexport interface MenuProps {\n children: ReactElement<Record<string, unknown>>;\n /** Abertura inicial no modo nao controlado. */\n defaultOpen?: boolean;\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n /** Avisa cada abertura e fechamento pedidos pelo gatilho, pelo teclado, pela opcao ou pelo clique fora. */\n onOpenChange?: (open: boolean) => void;\n /** Controla a abertura; sem ele, o menu guarda o proprio estado. */\n open?: boolean;\n}\n\n/** Encadeia o manipulador do gatilho ao do menu, em vez de substitui-lo. */\nfunction encadear<E>(proprio: ((evento: E) => void) | undefined, seguinte: (evento: E) => void) {\n return (evento: E) => {\n proprio?.(evento);\n seguinte(evento);\n };\n}\n\nexport function Menu({ children, defaultOpen = false, items, label, onOpenChange, open: controlledOpen }: MenuProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const [openedWith, setOpenedWith] = useState<'first' | 'last'>('first');\n const open = controlledOpen ?? internalOpen;\n\n function setOpen(proximo: boolean) {\n setInternalOpen(proximo);\n onOpenChange?.(proximo);\n }\n\n function abrir(from: 'first' | 'last') {\n setOpenedWith(from);\n setOpen(true);\n }\n\n // O foco volta na hora, antes de o `onSelect` montar o que vem depois, como um campo com `autoFocus` ou\n // um Dialog, que guarda o elemento em foco para devolver. Clique fora nao devolve: o foco e de quem foi clicado.\n function fechar(devolverFoco: boolean) {\n setOpen(false);\n\n if (devolverFoco) {\n triggerRef.current?.focus();\n }\n }\n\n const dono = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, dono.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n onClick: encadear(dono.onClick as (evento: unknown) => void, () =>\n open ? fechar(true) : abrir('first'),\n ),\n onKeyDown: encadear(dono.onKeyDown as (evento: KeyboardEvent) => void, (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n abrir(event.key === 'ArrowDown' ? 'first' : 'last');\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n // O escopo proprio poe o menu na arvore de escopos do Dialog, cujo `contain` puxaria o foco de volta.\n // Sem `contain` aqui: ele disputaria o foco com o gatilho quando o menu fecha.\n <FocusScope>\n <MenuList\n items={items}\n label={label}\n openedWith={openedWith}\n onClose={fechar}\n triggerRef={triggerRef}\n />\n </FocusScope>,\n document.body,\n )}\n </>\n );\n}\n\nfunction ehSecao(entrada: MenuItem | MenuSection): entrada is MenuSection {\n return 'items' in entrada;\n}\n\nfunction MenuList({\n items: entradas,\n label,\n onClose,\n openedWith,\n triggerRef,\n}: {\n items: readonly (MenuItem | MenuSection)[];\n label: string;\n onClose: (devolverFoco: boolean) => void;\n openedWith: 'first' | 'last';\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const nodes = useRef(new Map<string, HTMLElement>());\n // O teclado percorre os itens de todos os grupos como uma lista so.\n const items = useMemo(() => entradas.flatMap((entrada) => (ehSecao(entrada) ? entrada.items : [entrada])), [entradas]);\n const collection = useMemo<SelectionItem[]>(\n () => items.map((item) => ({ key: item.key, disabled: item.disabled, textValue: item.label })),\n [items],\n );\n const selection = useSelection({ items: collection, mode: 'none' });\n const { focusedKey, focusFirst, focusLast, focusNext, focusPrevious, search } = selection;\n\n // useOverlayPosition entrega toda a altura disponivel; limitamos para que\n // uma lista longa nao ocupe a tela inteira.\n // Sem isto o gatilho conta como \"fora\": o ponteiro fecha o menu e o clique\n // dele reabre em seguida, e o menu pisca sem abrir.\n const { overlayProps } = useOverlay(\n {\n isOpen: true,\n onClose: () => onClose(false),\n isDismissable: true,\n shouldCloseOnBlur: false,\n shouldCloseOnInteractOutside: (elemento) => !triggerRef.current?.contains(elemento),\n },\n ref,\n );\n const { overlayProps: positionProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement: 'bottom start',\n offset: 6,\n containerPadding: 8,\n isOpen: true,\n });\n\n const alturaMaxima = Math.min(Number(positionProps.style?.maxHeight) || 360, 360);\n\n useEffect(() => {\n if (openedWith === 'last') {\n focusLast();\n } else {\n focusFirst();\n }\n // Posicao inicial depende apenas de como o menu foi aberto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (focusedKey) {\n nodes.current.get(focusedKey)?.focus();\n }\n }, [focusedKey]);\n\n function acionar(item: MenuItem) {\n if (item.disabled) {\n return;\n }\n\n onClose(true);\n item.onSelect?.();\n }\n\n function renderizarItem(item: MenuItem) {\n const marcavel = item.checked !== undefined;\n\n return (\n <button\n aria-checked={marcavel ? item.checked : undefined}\n aria-keyshortcuts={item.shortcutKeys ?? (item.shortcut ? toAriaKeyShortcuts(item.shortcut) : undefined)}\n className={[styles.item, item.tone === 'danger' && styles.danger].filter(Boolean).join(' ')}\n disabled={item.disabled}\n key={item.key}\n onClick={() => acionar(item)}\n ref={(node) => {\n if (node) {\n nodes.current.set(item.key, node);\n } else {\n nodes.current.delete(item.key);\n }\n }}\n role={marcavel ? 'menuitemcheckbox' : 'menuitem'}\n tabIndex={focusedKey === item.key ? 0 : -1}\n type=\"button\"\n >\n {item.icon && (\n <span aria-hidden=\"true\" className={styles.icon}>\n {item.icon}\n </span>\n )}\n <span className={styles.label}>{item.label}</span>\n {item.shortcut && (\n <kbd aria-hidden=\"true\" className={styles.shortcut}>\n {item.shortcut}\n </kbd>\n )}\n {marcavel && <IconCheck className={[styles.check, item.checked && styles.checkOn].filter(Boolean).join(' ')} />}\n </button>\n );\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusNext();\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusPrevious();\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusFirst();\n } else if (event.key === 'End') {\n event.preventDefault();\n focusLast();\n } else if (event.key === 'Escape' || event.key === 'Tab') {\n onClose(true);\n } else if (event.key.length === 1 && !event.metaKey && !event.ctrlKey) {\n search(event.key);\n }\n }\n\n return (\n <div\n {...overlayProps}\n data-react-aria-top-layer=\"true\"\n ref={ref}\n className={styles.menu}\n style={{ ...positionProps.style, maxHeight: alturaMaxima }}\n role=\"menu\"\n aria-label={label}\n onKeyDown={(event) => {\n // Espalhar overlayProps antes nao basta: este onKeyDown o substituiria.\n handleKeyDown(event);\n overlayProps.onKeyDown?.(event);\n }}\n >\n {entradas.map((entrada, indice) => {\n if (!ehSecao(entrada)) {\n return renderizarItem(entrada);\n }\n\n return (\n <div aria-label={entrada.title} className={styles.section} key={entrada.key} role=\"group\">\n {indice > 0 && <div aria-hidden=\"true\" className={styles.divider} />}\n {entrada.title && (\n <div aria-hidden=\"true\" className={styles.sectionTitle}>\n {entrada.title}\n </div>\n )}\n {entrada.items.map(renderizarItem)}\n </div>\n );\n })}\n </div>\n );\n}\n"],"names":["encadear","proprio","seguinte","evento","Menu","children","defaultOpen","items","label","onOpenChange","controlledOpen","triggerRef","useRef","internalOpen","setInternalOpen","useState","openedWith","setOpenedWith","open","setOpen","proximo","abrir","from","fechar","devolverFoco","_a","dono","mergedTriggerRef","useMergedRefs","trigger","cloneElement","event","jsxs","Fragment","createPortal","FocusScope","jsx","MenuList","ehSecao","entrada","entradas","onClose","ref","nodes","useMemo","collection","item","selection","useSelection","focusedKey","focusFirst","focusLast","focusNext","focusPrevious","search","overlayProps","useOverlay","elemento","positionProps","useOverlayPosition","alturaMaxima","useEffect","acionar","renderizarItem","marcavel","toAriaKeyShortcuts","styles","node","IconCheck","handleKeyDown","indice"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o={"⌘":"Meta",cmd:"Meta",command:"Meta",meta:"Meta","⌥":"Alt",alt:"Alt",opt:"Alt",option:"Alt","⇧":"Shift",shift:"Shift","⌃":"Control",ctrl:"Control",control:"Control",esc:"Escape",escape:"Escape",del:"Delete",delete:"Delete","⌫":"Backspace",backspace:"Backspace","↵":"Enter",enter:"Enter",return:"Enter","⇥":"Tab",tab:"Tab",space:"Space",espaço:"Space","+":"Plus","↑":"ArrowUp",up:"ArrowUp","↓":"ArrowDown",down:"ArrowDown","←":"ArrowLeft",left:"ArrowLeft","→":"ArrowRight",right:"ArrowRight",home:"Home",end:"End",pageup:"PageUp",pagedown:"PageDown"};function r(e){const t=o[e.toLowerCase()];return t||(e.length===1||/^f\d{1,2}$/i.test(e)?e.toUpperCase():e)}function a(e){return(e.replace(/([⌘⌥⇧⌃])(?=[^+])/g,"$1+").match(/[^+]+|\+$/g)??[]).map(r).join("+")}function n(e){return e.replace(/\s*\+\s*/g,"+").replace(/([^+]),/g,"$1 ").split(/\s+/).filter(Boolean).map(a).join(" ")}exports.toAriaKeyShortcuts=n;
2
+ //# sourceMappingURL=keyShortcuts.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyShortcuts.cjs","sources":["../../../../src/components/overlays/Menu/keyShortcuts.ts"],"sourcesContent":["// Nomes de tecla que a especificação ARIA espera em `aria-keyshortcuts`, pela grafia escrita em minúsculas.\nconst KEY_NAMES: Record<string, string> = {\n '⌘': 'Meta',\n cmd: 'Meta',\n command: 'Meta',\n meta: 'Meta',\n '⌥': 'Alt',\n alt: 'Alt',\n opt: 'Alt',\n option: 'Alt',\n '⇧': 'Shift',\n shift: 'Shift',\n '⌃': 'Control',\n ctrl: 'Control',\n control: 'Control',\n esc: 'Escape',\n escape: 'Escape',\n del: 'Delete',\n delete: 'Delete',\n '⌫': 'Backspace',\n backspace: 'Backspace',\n '↵': 'Enter',\n enter: 'Enter',\n return: 'Enter',\n '⇥': 'Tab',\n tab: 'Tab',\n space: 'Space',\n espaço: 'Space',\n '+': 'Plus',\n '↑': 'ArrowUp',\n up: 'ArrowUp',\n '↓': 'ArrowDown',\n down: 'ArrowDown',\n '←': 'ArrowLeft',\n left: 'ArrowLeft',\n '→': 'ArrowRight',\n right: 'ArrowRight',\n home: 'Home',\n end: 'End',\n pageup: 'PageUp',\n pagedown: 'PageDown',\n};\n\nfunction toKeyName(key: string) {\n const name = KEY_NAMES[key.toLowerCase()];\n\n if (name) {\n return name;\n }\n\n return key.length === 1 || /^f\\d{1,2}$/i.test(key) ? key.toUpperCase() : key;\n}\n\nfunction toKeyCombination(shortcut: string) {\n // Os símbolos do macOS vêm colados (`⌘⇧D`); o `+` final de `Ctrl++` é a própria tecla.\n const separated = shortcut.replace(/([⌘⌥⇧⌃])(?=[^+])/g, '$1+');\n\n return (separated.match(/[^+]+|\\+$/g) ?? []).map(toKeyName).join('+');\n}\n\n/** Converte o atalho escrito, como `Ctrl+Shift+D` ou `⌘K, Ctrl+K`, no valor de `aria-keyshortcuts`. */\nexport function toAriaKeyShortcuts(shortcut: string) {\n return shortcut\n .replace(/\\s*\\+\\s*/g, '+')\n .replace(/([^+]),/g, '$1 ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(toKeyCombination)\n .join(' ');\n}\n"],"names":["KEY_NAMES","toKeyName","key","name","toKeyCombination","shortcut","toAriaKeyShortcuts"],"mappings":"gFACA,MAAMA,EAAoC,CACxC,IAAK,OACL,IAAK,OACL,QAAS,OACT,KAAM,OACN,IAAK,MACL,IAAK,MACL,IAAK,MACL,OAAQ,MACR,IAAK,QACL,MAAO,QACP,IAAK,UACL,KAAM,UACN,QAAS,UACT,IAAK,SACL,OAAQ,SACR,IAAK,SACL,OAAQ,SACR,IAAK,YACL,UAAW,YACX,IAAK,QACL,MAAO,QACP,OAAQ,QACR,IAAK,MACL,IAAK,MACL,MAAO,QACP,OAAQ,QACR,IAAK,OACL,IAAK,UACL,GAAI,UACJ,IAAK,YACL,KAAM,YACN,IAAK,YACL,KAAM,YACN,IAAK,aACL,MAAO,aACP,KAAM,OACN,IAAK,MACL,OAAQ,SACR,SAAU,UACZ,EAEA,SAASC,EAAUC,EAAa,CAC9B,MAAMC,EAAOH,EAAUE,EAAI,YAAA,CAAa,EAExC,OAAIC,IAIGD,EAAI,SAAW,GAAK,cAAc,KAAKA,CAAG,EAAIA,EAAI,YAAA,EAAgBA,EAC3E,CAEA,SAASE,EAAiBC,EAAkB,CAI1C,OAFkBA,EAAS,QAAQ,oBAAqB,KAAK,EAE3C,MAAM,YAAY,GAAK,IAAI,IAAIJ,CAAS,EAAE,KAAK,GAAG,CACtE,CAGO,SAASK,EAAmBD,EAAkB,CACnD,OAAOA,EACJ,QAAQ,YAAa,GAAG,EACxB,QAAQ,WAAY,KAAK,EACzB,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAID,CAAgB,EACpB,KAAK,GAAG,CACb"}
@@ -0,0 +1,55 @@
1
+ const o = {
2
+ "⌘": "Meta",
3
+ cmd: "Meta",
4
+ command: "Meta",
5
+ meta: "Meta",
6
+ "⌥": "Alt",
7
+ alt: "Alt",
8
+ opt: "Alt",
9
+ option: "Alt",
10
+ "⇧": "Shift",
11
+ shift: "Shift",
12
+ "⌃": "Control",
13
+ ctrl: "Control",
14
+ control: "Control",
15
+ esc: "Escape",
16
+ escape: "Escape",
17
+ del: "Delete",
18
+ delete: "Delete",
19
+ "⌫": "Backspace",
20
+ backspace: "Backspace",
21
+ "↵": "Enter",
22
+ enter: "Enter",
23
+ return: "Enter",
24
+ "⇥": "Tab",
25
+ tab: "Tab",
26
+ space: "Space",
27
+ espaço: "Space",
28
+ "+": "Plus",
29
+ "↑": "ArrowUp",
30
+ up: "ArrowUp",
31
+ "↓": "ArrowDown",
32
+ down: "ArrowDown",
33
+ "←": "ArrowLeft",
34
+ left: "ArrowLeft",
35
+ "→": "ArrowRight",
36
+ right: "ArrowRight",
37
+ home: "Home",
38
+ end: "End",
39
+ pageup: "PageUp",
40
+ pagedown: "PageDown"
41
+ };
42
+ function r(e) {
43
+ const t = o[e.toLowerCase()];
44
+ return t || (e.length === 1 || /^f\d{1,2}$/i.test(e) ? e.toUpperCase() : e);
45
+ }
46
+ function a(e) {
47
+ return (e.replace(/([⌘⌥⇧⌃])(?=[^+])/g, "$1+").match(/[^+]+|\+$/g) ?? []).map(r).join("+");
48
+ }
49
+ function n(e) {
50
+ return e.replace(/\s*\+\s*/g, "+").replace(/([^+]),/g, "$1 ").split(/\s+/).filter(Boolean).map(a).join(" ");
51
+ }
52
+ export {
53
+ n as toAriaKeyShortcuts
54
+ };
55
+ //# sourceMappingURL=keyShortcuts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyShortcuts.js","sources":["../../../../src/components/overlays/Menu/keyShortcuts.ts"],"sourcesContent":["// Nomes de tecla que a especificação ARIA espera em `aria-keyshortcuts`, pela grafia escrita em minúsculas.\nconst KEY_NAMES: Record<string, string> = {\n '⌘': 'Meta',\n cmd: 'Meta',\n command: 'Meta',\n meta: 'Meta',\n '⌥': 'Alt',\n alt: 'Alt',\n opt: 'Alt',\n option: 'Alt',\n '⇧': 'Shift',\n shift: 'Shift',\n '⌃': 'Control',\n ctrl: 'Control',\n control: 'Control',\n esc: 'Escape',\n escape: 'Escape',\n del: 'Delete',\n delete: 'Delete',\n '⌫': 'Backspace',\n backspace: 'Backspace',\n '↵': 'Enter',\n enter: 'Enter',\n return: 'Enter',\n '⇥': 'Tab',\n tab: 'Tab',\n space: 'Space',\n espaço: 'Space',\n '+': 'Plus',\n '↑': 'ArrowUp',\n up: 'ArrowUp',\n '↓': 'ArrowDown',\n down: 'ArrowDown',\n '←': 'ArrowLeft',\n left: 'ArrowLeft',\n '→': 'ArrowRight',\n right: 'ArrowRight',\n home: 'Home',\n end: 'End',\n pageup: 'PageUp',\n pagedown: 'PageDown',\n};\n\nfunction toKeyName(key: string) {\n const name = KEY_NAMES[key.toLowerCase()];\n\n if (name) {\n return name;\n }\n\n return key.length === 1 || /^f\\d{1,2}$/i.test(key) ? key.toUpperCase() : key;\n}\n\nfunction toKeyCombination(shortcut: string) {\n // Os símbolos do macOS vêm colados (`⌘⇧D`); o `+` final de `Ctrl++` é a própria tecla.\n const separated = shortcut.replace(/([⌘⌥⇧⌃])(?=[^+])/g, '$1+');\n\n return (separated.match(/[^+]+|\\+$/g) ?? []).map(toKeyName).join('+');\n}\n\n/** Converte o atalho escrito, como `Ctrl+Shift+D` ou `⌘K, Ctrl+K`, no valor de `aria-keyshortcuts`. */\nexport function toAriaKeyShortcuts(shortcut: string) {\n return shortcut\n .replace(/\\s*\\+\\s*/g, '+')\n .replace(/([^+]),/g, '$1 ')\n .split(/\\s+/)\n .filter(Boolean)\n .map(toKeyCombination)\n .join(' ');\n}\n"],"names":["KEY_NAMES","toKeyName","key","name","toKeyCombination","shortcut","toAriaKeyShortcuts"],"mappings":"AACA,MAAMA,IAAoC;AAAA,EACxC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,WAAW;AAAA,EACX,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,UAAU;AACZ;AAEA,SAASC,EAAUC,GAAa;AAC9B,QAAMC,IAAOH,EAAUE,EAAI,YAAA,CAAa;AAExC,SAAIC,MAIGD,EAAI,WAAW,KAAK,cAAc,KAAKA,CAAG,IAAIA,EAAI,YAAA,IAAgBA;AAC3E;AAEA,SAASE,EAAiBC,GAAkB;AAI1C,UAFkBA,EAAS,QAAQ,qBAAqB,KAAK,EAE3C,MAAM,YAAY,KAAK,IAAI,IAAIJ,CAAS,EAAE,KAAK,GAAG;AACtE;AAGO,SAASK,EAAmBD,GAAkB;AACnD,SAAOA,EACJ,QAAQ,aAAa,GAAG,EACxB,QAAQ,YAAY,KAAK,EACzB,MAAM,KAAK,EACX,OAAO,OAAO,EACd,IAAID,CAAgB,EACpB,KAAK,GAAG;AACb;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),o=require("react"),g=require("react-dom"),R=require("@react-aria/overlays"),v=require("../../../hooks/useMergedRefs.cjs"),M=require("./Tooltip.module.css.cjs"),E=120;function c(t,u){return n=>{t==null||t(n),u(n)}}function j({children:t,content:u,delay:n=500,placement:f="top"}){const i=o.useRef(null),[a,s]=o.useState(!1),e=o.useRef(void 0),p=`tooltip-${o.useId()}`,d=o.useCallback(()=>{clearTimeout(e.current),s(!1)},[]),m=o.useCallback(()=>{clearTimeout(e.current),e.current=setTimeout(()=>s(!1),E)},[]);o.useEffect(()=>()=>clearTimeout(e.current),[]);const r=t.props,y=v.useMergedRefs(i,r.ref),T=o.cloneElement(t,{ref:y,"aria-describedby":a?[r["aria-describedby"],p].filter(Boolean).join(" "):r["aria-describedby"],onMouseEnter:c(r.onMouseEnter,()=>{clearTimeout(e.current),e.current=setTimeout(()=>s(!0),n)}),onMouseLeave:c(r.onMouseLeave,m),onFocus:c(r.onFocus,()=>s(!0)),onBlur:c(r.onBlur,d),onKeyDown:c(r.onKeyDown,b=>{b.key==="Escape"&&d()})});return l.jsxs(l.Fragment,{children:[T,a&&g.createPortal(l.jsx(q,{content:u,id:p,onMouseEnter:()=>clearTimeout(e.current),onMouseLeave:d,placement:f,triggerRef:i}),document.body)]})}function q({content:t,id:u,onMouseEnter:n,onMouseLeave:f,placement:i,triggerRef:a}){const s=o.useRef(null),{overlayProps:e}=R.useOverlayPosition({targetRef:a,overlayRef:s,placement:i,offset:6,isOpen:!0});return l.jsx("div",{ref:s,className:M.default.tooltip,"data-react-aria-top-layer":"true",id:u,onMouseEnter:n,onMouseLeave:f,role:"tooltip",style:e.style,children:t})}exports.Tooltip=j;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),n=require("react"),b=require("react-dom"),g=require("@react-aria/overlays"),x=require("../../../hooks/useMergedRefs.cjs"),S=require("./Tooltip.module.css.cjs"),L=120;function d(e,s){return r=>{e==null||e(r),s(r)}}function P(e){return e.anchorRef?l.jsx(B,{...e}):l.jsx(k,{...e})}function k({children:e,content:s,delay:r=500,onOpenChange:t,open:i,placement:f="top"}){const o=n.useRef(null),[a,E]=n.useState(!1),p=i??a,c=n.useRef(void 0),R=`tooltip-${n.useId()}`;function m(y){E(y),t==null||t(y)}function T(){clearTimeout(c.current),m(!1)}function j(){clearTimeout(c.current),c.current=setTimeout(()=>m(!1),L)}n.useEffect(()=>()=>clearTimeout(c.current),[]);const u=e.props,M=x.useMergedRefs(o,u.ref),q=n.cloneElement(e,{ref:M,"aria-describedby":p?[u["aria-describedby"],R].filter(Boolean).join(" "):u["aria-describedby"],onMouseEnter:d(u.onMouseEnter,()=>{clearTimeout(c.current),c.current=setTimeout(()=>m(!0),r)}),onMouseLeave:d(u.onMouseLeave,j),onFocus:d(u.onFocus,()=>m(!0)),onBlur:d(u.onBlur,T),onKeyDown:d(u.onKeyDown,y=>{y.key==="Escape"&&T()})});return l.jsxs(l.Fragment,{children:[q,p&&typeof document<"u"&&b.createPortal(l.jsx(v,{content:s,id:R,onMouseEnter:()=>clearTimeout(c.current),onMouseLeave:T,placement:f,triggerRef:o}),document.body)]})}function B({anchorRef:e,content:s,id:r,onOpenChange:t,open:i,placement:f="top"}){return n.useEffect(()=>{if(!i)return;function o(a){a.key==="Escape"&&(t==null||t(!1))}return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[t,i]),!i||typeof document>"u"?null:b.createPortal(l.jsx(v,{content:s,id:r,placement:f,triggerRef:e}),document.body)}function v({content:e,id:s,onMouseEnter:r,onMouseLeave:t,placement:i,triggerRef:f}){const o=n.useRef(null),{overlayProps:a}=g.useOverlayPosition({targetRef:f,overlayRef:o,placement:i,offset:6,isOpen:!0});return l.jsx("div",{ref:o,className:S.default.tooltip,"data-react-aria-top-layer":"true",id:s,onMouseEnter:r,onMouseLeave:t,role:"tooltip",style:a.style,children:e})}exports.Tooltip=P;
2
2
  //# sourceMappingURL=Tooltip.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface TooltipProps {\n children: ReactElement<Record<string, unknown>>;\n content: ReactNode;\n delay?: number;\n placement?: TooltipPlacement;\n}\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip({ children, content, delay = 500, placement = 'top' }: TooltipProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [open, setOpen] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n const hide = useCallback(() => {\n clearTimeout(timer.current);\n setOpen(false);\n }, []);\n\n // O balao aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia ate ele antes de fechar.\n const hideSoon = useCallback(() => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }, []);\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter: () => void;\n onMouseLeave: () => void;\n placement: TooltipPlacement;\n triggerRef: React.RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","children","content","delay","placement","triggerRef","useRef","open","setOpen","useState","timer","id","useId","hide","useCallback","hideSoon","useEffect","props","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","jsx","TooltipBubble","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":"qRA6BMA,EAAY,IAElB,SAASC,EAASC,EAAuCC,EAA0B,CACjF,OAAQC,GAAa,CACnBF,GAAA,MAAAA,EAAME,GACND,EAAKC,CAAK,CACZ,CACF,CAEO,SAASC,EAAQ,CAAE,SAAAC,EAAU,QAAAC,EAAS,MAAAC,EAAQ,IAAK,UAAAC,EAAY,OAAuB,CAC3F,MAAMC,EAAaC,EAAAA,OAAoB,IAAI,EACrC,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAS,EAAK,EAChCC,EAAQJ,EAAAA,OAAsC,MAAS,EACvDK,EAAK,WAAWC,EAAAA,MAAA,CAAO,GAEvBC,EAAOC,EAAAA,YAAY,IAAM,CAC7B,aAAaJ,EAAM,OAAO,EAC1BF,EAAQ,EAAK,CACf,EAAG,CAAA,CAAE,EAGCO,EAAWD,EAAAA,YAAY,IAAM,CACjC,aAAaJ,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMF,EAAQ,EAAK,EAAGb,CAAS,CAC5D,EAAG,CAAA,CAAE,EAELqB,EAAAA,UAAU,IAAM,IAAM,aAAaN,EAAM,OAAO,EAAG,CAAA,CAAE,EAErD,MAAMO,EAAQhB,EAAS,MACjBiB,EAAmBC,EAAAA,cAAcd,EAAYY,EAAM,GAAmC,EACtFG,EAAUC,EAAAA,aAAapB,EAAU,CACrC,IAAKiB,EACL,mBAAoBX,EAAO,CAACU,EAAM,kBAAkB,EAAGN,CAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAIM,EAAM,kBAAkB,EAC/G,aAAcrB,EAAMqB,EAAM,aAAyC,IAAM,CACvE,aAAaP,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMF,EAAQ,EAAI,EAAGL,CAAK,CACvD,CAAC,EACD,aAAcP,EAAMqB,EAAM,aAAyCF,CAAQ,EAC3E,QAASnB,EAAMqB,EAAM,QAAoC,IAAMT,EAAQ,EAAI,CAAC,EAC5E,OAAQZ,EAAMqB,EAAM,OAAmCJ,CAAI,EAC3D,UAAWjB,EAAMqB,EAAM,UAA0ClB,GAAU,CACrEA,EAAM,MAAQ,UAChBc,EAAA,CAEJ,CAAC,CAAA,CACF,EAED,OACES,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAH,EACAb,GACCiB,EAAAA,aACEC,EAAAA,IAACC,EAAA,CACC,QAAAxB,EACA,GAAAS,EACA,aAAc,IAAM,aAAaD,EAAM,OAAO,EAC9C,aAAcG,EACd,UAAAT,EACA,WAAAC,CAAA,CAAA,EAEF,SAAS,IAAA,CACX,EACJ,CAEJ,CAEA,SAASqB,EAAc,CACrB,QAAAxB,EACA,GAAAS,EACA,aAAAgB,EACA,aAAAC,EACA,UAAAxB,EACA,WAAAC,CACF,EAOG,CACD,MAAMwB,EAAMvB,EAAAA,OAAuB,IAAI,EACjC,CAAE,aAAAwB,CAAA,EAAiBC,qBAAmB,CAC1C,UAAW1B,EACX,WAAYwB,EACZ,UAAAzB,EACA,OAAQ,EACR,OAAQ,EAAA,CACT,EAED,OACEqB,EAAAA,IAAC,MAAA,CACC,IAAAI,EACA,UAAWG,EAAAA,QAAO,QAClB,4BAA0B,OAC1B,GAAArB,EACA,aAAAgB,EACA,aAAAC,EACA,KAAK,UACL,MAAOE,EAAa,MAEnB,SAAA5B,CAAA,CAAA,CAGP"}
1
+ {"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/overlays/Tooltip/Tooltip.tsx"],"sourcesContent":["import {\n cloneElement,\n useEffect,\n useId,\n useRef,\n useState,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefObject,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOverlayPosition } from '@react-aria/overlays';\nimport { useMergedRefs } from '../../../hooks/useMergedRefs';\nimport styles from './Tooltip.module.css';\n\nexport type TooltipPlacement = 'top' | 'bottom' | 'left' | 'right';\n\ninterface TooltipCommonProps {\n content: ReactNode;\n /** Avisa cada pedido de abrir ou fechar: ponteiro, foco, blur e Escape. */\n onOpenChange?: (open: boolean) => void;\n placement?: TooltipPlacement;\n}\n\ninterface TooltipOnChildProps extends TooltipCommonProps {\n anchorRef?: never;\n /** O gatilho: o Tooltip o clona, soma os manipuladores e liga a descrição por `aria-describedby`. */\n children: ReactElement<Record<string, unknown>>;\n delay?: number;\n id?: never;\n /** Controla a abertura; sem ele, o Tooltip guarda o próprio estado. */\n open?: boolean;\n}\n\ninterface TooltipOnAnchorProps extends TooltipCommonProps {\n /** Âncora que não é filho do Tooltip, como um elemento que precisa da própria referência e não pode ser clonado. */\n anchorRef: RefObject<HTMLElement | null>;\n children?: never;\n delay?: never;\n /** Id do balão. O produto o põe no `aria-describedby` da âncora enquanto `open`. */\n id: string;\n /** Com âncora externa, a abertura é sempre do produto. */\n open: boolean;\n}\n\nexport type TooltipProps = TooltipOnChildProps | TooltipOnAnchorProps;\n\n/** Tempo para o ponteiro atravessar a folga entre o gatilho e o balao. */\nconst TRAVESSIA = 120;\n\nfunction chain<E>(own: ((event: E) => void) | undefined, next: (event: E) => void) {\n return (event: E) => {\n own?.(event);\n next(event);\n };\n}\n\nexport function Tooltip(props: TooltipProps) {\n return props.anchorRef ? <TooltipOnAnchor {...props} /> : <TooltipOnChild {...props} />;\n}\n\nfunction TooltipOnChild({\n children,\n content,\n delay = 500,\n onOpenChange,\n open: controlledOpen,\n placement = 'top',\n}: TooltipOnChildProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const [internalOpen, setInternalOpen] = useState(false);\n const open = controlledOpen ?? internalOpen;\n const timer = useRef<ReturnType<typeof setTimeout>>(undefined);\n const id = `tooltip-${useId()}`;\n\n function setOpen(next: boolean) {\n setInternalOpen(next);\n onOpenChange?.(next);\n }\n\n function hide() {\n clearTimeout(timer.current);\n setOpen(false);\n }\n\n // O balão aceita o ponteiro (WCAG 1.4.13): sair do gatilho espera a travessia até ele antes de fechar.\n function hideSoon() {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(false), TRAVESSIA);\n }\n\n useEffect(() => () => clearTimeout(timer.current), []);\n\n const props = children.props;\n const mergedTriggerRef = useMergedRefs(triggerRef, props.ref as Ref<HTMLElement> | undefined);\n const trigger = cloneElement(children, {\n ref: mergedTriggerRef,\n 'aria-describedby': open ? [props['aria-describedby'], id].filter(Boolean).join(' ') : props['aria-describedby'],\n onMouseEnter: chain(props.onMouseEnter as (e: MouseEvent) => void, () => {\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setOpen(true), delay);\n }),\n onMouseLeave: chain(props.onMouseLeave as (e: MouseEvent) => void, hideSoon),\n onFocus: chain(props.onFocus as (e: FocusEvent) => void, () => setOpen(true)),\n onBlur: chain(props.onBlur as (e: FocusEvent) => void, hide),\n onKeyDown: chain(props.onKeyDown as (e: KeyboardEvent) => void, (event) => {\n if (event.key === 'Escape') {\n hide();\n }\n }),\n });\n\n return (\n <>\n {trigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <TooltipBubble\n content={content}\n id={id}\n onMouseEnter={() => clearTimeout(timer.current)}\n onMouseLeave={hide}\n placement={placement}\n triggerRef={triggerRef}\n />,\n document.body,\n )}\n </>\n );\n}\n\nfunction TooltipOnAnchor({ anchorRef, content, id, onOpenChange, open, placement = 'top' }: TooltipOnAnchorProps) {\n // O foco pode estar fora da âncora, como no editor que a contém; o Escape vale em qualquer ponto da página.\n useEffect(() => {\n if (!open) {\n return;\n }\n\n function requestCloseOnEscape(event: globalThis.KeyboardEvent) {\n if (event.key === 'Escape') {\n onOpenChange?.(false);\n }\n }\n\n document.addEventListener('keydown', requestCloseOnEscape);\n return () => document.removeEventListener('keydown', requestCloseOnEscape);\n }, [onOpenChange, open]);\n\n if (!open || typeof document === 'undefined') {\n return null;\n }\n\n return createPortal(<TooltipBubble content={content} id={id} placement={placement} triggerRef={anchorRef} />, document.body);\n}\n\nfunction TooltipBubble({\n content,\n id,\n onMouseEnter,\n onMouseLeave,\n placement,\n triggerRef,\n}: {\n content: ReactNode;\n id: string;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n placement: TooltipPlacement;\n triggerRef: RefObject<HTMLElement | null>;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { overlayProps } = useOverlayPosition({\n targetRef: triggerRef,\n overlayRef: ref,\n placement,\n offset: 6,\n isOpen: true,\n });\n\n return (\n <div\n ref={ref}\n className={styles.tooltip}\n data-react-aria-top-layer=\"true\"\n id={id}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n role=\"tooltip\"\n style={overlayProps.style}\n >\n {content}\n </div>\n );\n}\n"],"names":["TRAVESSIA","chain","own","next","event","Tooltip","props","jsx","TooltipOnAnchor","TooltipOnChild","children","content","delay","onOpenChange","controlledOpen","placement","triggerRef","useRef","internalOpen","setInternalOpen","useState","open","timer","id","useId","setOpen","hide","hideSoon","useEffect","mergedTriggerRef","useMergedRefs","trigger","cloneElement","jsxs","Fragment","createPortal","TooltipBubble","anchorRef","requestCloseOnEscape","onMouseEnter","onMouseLeave","ref","overlayProps","useOverlayPosition","styles"],"mappings":"qRAoDMA,EAAY,IAElB,SAASC,EAASC,EAAuCC,EAA0B,CACjF,OAAQC,GAAa,CACnBF,GAAA,MAAAA,EAAME,GACND,EAAKC,CAAK,CACZ,CACF,CAEO,SAASC,EAAQC,EAAqB,CAC3C,OAAOA,EAAM,UAAYC,EAAAA,IAACC,EAAA,CAAiB,GAAGF,EAAO,EAAKC,EAAAA,IAACE,EAAA,CAAgB,GAAGH,CAAA,CAAO,CACvF,CAEA,SAASG,EAAe,CACtB,SAAAC,EACA,QAAAC,EACA,MAAAC,EAAQ,IACR,aAAAC,EACA,KAAMC,EACN,UAAAC,EAAY,KACd,EAAwB,CACtB,MAAMC,EAAaC,EAAAA,OAAoB,IAAI,EACrC,CAACC,EAAcC,CAAe,EAAIC,EAAAA,SAAS,EAAK,EAChDC,EAAOP,GAAkBI,EACzBI,EAAQL,EAAAA,OAAsC,MAAS,EACvDM,EAAK,WAAWC,EAAAA,MAAA,CAAO,GAE7B,SAASC,EAAQtB,EAAe,CAC9BgB,EAAgBhB,CAAI,EACpBU,GAAA,MAAAA,EAAeV,EACjB,CAEA,SAASuB,GAAO,CACd,aAAaJ,EAAM,OAAO,EAC1BG,EAAQ,EAAK,CACf,CAGA,SAASE,GAAW,CAClB,aAAaL,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMG,EAAQ,EAAK,EAAGzB,CAAS,CAC5D,CAEA4B,EAAAA,UAAU,IAAM,IAAM,aAAaN,EAAM,OAAO,EAAG,CAAA,CAAE,EAErD,MAAMhB,EAAQI,EAAS,MACjBmB,EAAmBC,EAAAA,cAAcd,EAAYV,EAAM,GAAmC,EACtFyB,EAAUC,EAAAA,aAAatB,EAAU,CACrC,IAAKmB,EACL,mBAAoBR,EAAO,CAACf,EAAM,kBAAkB,EAAGiB,CAAE,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAAIjB,EAAM,kBAAkB,EAC/G,aAAcL,EAAMK,EAAM,aAAyC,IAAM,CACvE,aAAagB,EAAM,OAAO,EAC1BA,EAAM,QAAU,WAAW,IAAMG,EAAQ,EAAI,EAAGb,CAAK,CACvD,CAAC,EACD,aAAcX,EAAMK,EAAM,aAAyCqB,CAAQ,EAC3E,QAAS1B,EAAMK,EAAM,QAAoC,IAAMmB,EAAQ,EAAI,CAAC,EAC5E,OAAQxB,EAAMK,EAAM,OAAmCoB,CAAI,EAC3D,UAAWzB,EAAMK,EAAM,UAA0CF,GAAU,CACrEA,EAAM,MAAQ,UAChBsB,EAAA,CAEJ,CAAC,CAAA,CACF,EAED,OACEO,EAAAA,KAAAC,WAAA,CACG,SAAA,CAAAH,EACAV,GACC,OAAO,SAAa,KACpBc,EAAAA,aACE5B,EAAAA,IAAC6B,EAAA,CACC,QAAAzB,EACA,GAAAY,EACA,aAAc,IAAM,aAAaD,EAAM,OAAO,EAC9C,aAAcI,EACd,UAAAX,EACA,WAAAC,CAAA,CAAA,EAEF,SAAS,IAAA,CACX,EACJ,CAEJ,CAEA,SAASR,EAAgB,CAAE,UAAA6B,EAAW,QAAA1B,EAAS,GAAAY,EAAI,aAAAV,EAAc,KAAAQ,EAAM,UAAAN,EAAY,OAA+B,CAiBhH,OAfAa,EAAAA,UAAU,IAAM,CACd,GAAI,CAACP,EACH,OAGF,SAASiB,EAAqBlC,EAAiC,CACzDA,EAAM,MAAQ,WAChBS,GAAA,MAAAA,EAAe,IAEnB,CAEA,gBAAS,iBAAiB,UAAWyB,CAAoB,EAClD,IAAM,SAAS,oBAAoB,UAAWA,CAAoB,CAC3E,EAAG,CAACzB,EAAcQ,CAAI,CAAC,EAEnB,CAACA,GAAQ,OAAO,SAAa,IACxB,KAGFc,eAAa5B,EAAAA,IAAC6B,EAAA,CAAc,QAAAzB,EAAkB,GAAAY,EAAQ,UAAAR,EAAsB,WAAYsB,CAAA,CAAW,EAAI,SAAS,IAAI,CAC7H,CAEA,SAASD,EAAc,CACrB,QAAAzB,EACA,GAAAY,EACA,aAAAgB,EACA,aAAAC,EACA,UAAAzB,EACA,WAAAC,CACF,EAOG,CACD,MAAMyB,EAAMxB,EAAAA,OAAuB,IAAI,EACjC,CAAE,aAAAyB,CAAA,EAAiBC,qBAAmB,CAC1C,UAAW3B,EACX,WAAYyB,EACZ,UAAA1B,EACA,OAAQ,EACR,OAAQ,EAAA,CACT,EAED,OACER,EAAAA,IAAC,MAAA,CACC,IAAAkC,EACA,UAAWG,EAAAA,QAAO,QAClB,4BAA0B,OAC1B,GAAArB,EACA,aAAAgB,EACA,aAAAC,EACA,KAAK,UACL,MAAOE,EAAa,MAEnB,SAAA/B,CAAA,CAAA,CAGP"}