@intlayer/design-system 6.1.5 → 6.1.6-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/dist/.vite/manifest.json +13 -9
  2. package/dist/Form-CriPBaZk.js.map +1 -1
  3. package/dist/Form-DJrUK3mm.cjs.map +1 -1
  4. package/dist/components/Accordion/Accordion.cjs +51 -15
  5. package/dist/components/Accordion/Accordion.cjs.map +1 -1
  6. package/dist/components/Accordion/Accordion.d.ts +44 -5
  7. package/dist/components/Accordion/Accordion.d.ts.map +1 -1
  8. package/dist/components/Accordion/Accordion.mjs +52 -16
  9. package/dist/components/Accordion/Accordion.mjs.map +1 -1
  10. package/dist/components/Avatar/index.cjs +114 -31
  11. package/dist/components/Avatar/index.cjs.map +1 -1
  12. package/dist/components/Avatar/index.d.ts +46 -2
  13. package/dist/components/Avatar/index.d.ts.map +1 -1
  14. package/dist/components/Avatar/index.mjs +115 -32
  15. package/dist/components/Avatar/index.mjs.map +1 -1
  16. package/dist/components/Badge/index.cjs +88 -9
  17. package/dist/components/Badge/index.cjs.map +1 -1
  18. package/dist/components/Badge/index.d.ts +80 -2
  19. package/dist/components/Badge/index.d.ts.map +1 -1
  20. package/dist/components/Badge/index.mjs +89 -10
  21. package/dist/components/Badge/index.mjs.map +1 -1
  22. package/dist/components/Breadcrumb/index.cjs +124 -59
  23. package/dist/components/Breadcrumb/index.cjs.map +1 -1
  24. package/dist/components/Breadcrumb/index.d.ts +89 -5
  25. package/dist/components/Breadcrumb/index.d.ts.map +1 -1
  26. package/dist/components/Breadcrumb/index.mjs +124 -59
  27. package/dist/components/Breadcrumb/index.mjs.map +1 -1
  28. package/dist/components/Button/Button.cjs +44 -25
  29. package/dist/components/Button/Button.cjs.map +1 -1
  30. package/dist/components/Button/Button.d.ts +95 -1
  31. package/dist/components/Button/Button.d.ts.map +1 -1
  32. package/dist/components/Button/Button.mjs +44 -25
  33. package/dist/components/Button/Button.mjs.map +1 -1
  34. package/dist/components/ClickOutsideDiv/index.cjs +38 -7
  35. package/dist/components/ClickOutsideDiv/index.cjs.map +1 -1
  36. package/dist/components/ClickOutsideDiv/index.d.ts +13 -0
  37. package/dist/components/ClickOutsideDiv/index.d.ts.map +1 -1
  38. package/dist/components/ClickOutsideDiv/index.mjs +39 -8
  39. package/dist/components/ClickOutsideDiv/index.mjs.map +1 -1
  40. package/dist/components/Container/index.cjs +2 -0
  41. package/dist/components/Container/index.cjs.map +1 -1
  42. package/dist/components/Container/index.d.ts +42 -0
  43. package/dist/components/Container/index.d.ts.map +1 -1
  44. package/dist/components/Container/index.mjs +2 -0
  45. package/dist/components/Container/index.mjs.map +1 -1
  46. package/dist/components/ContentEditor/ContentEditor.cjs +80 -33
  47. package/dist/components/ContentEditor/ContentEditor.cjs.map +1 -1
  48. package/dist/components/ContentEditor/ContentEditor.d.ts +29 -0
  49. package/dist/components/ContentEditor/ContentEditor.d.ts.map +1 -1
  50. package/dist/components/ContentEditor/ContentEditor.mjs +80 -33
  51. package/dist/components/ContentEditor/ContentEditor.mjs.map +1 -1
  52. package/dist/components/ContentEditor/ContentEditorInput.cjs +58 -31
  53. package/dist/components/ContentEditor/ContentEditorInput.cjs.map +1 -1
  54. package/dist/components/ContentEditor/ContentEditorInput.d.ts +33 -0
  55. package/dist/components/ContentEditor/ContentEditorInput.d.ts.map +1 -1
  56. package/dist/components/ContentEditor/ContentEditorInput.mjs +58 -31
  57. package/dist/components/ContentEditor/ContentEditorInput.mjs.map +1 -1
  58. package/dist/components/ContentEditor/ContentEditorTextArea.cjs +58 -30
  59. package/dist/components/ContentEditor/ContentEditorTextArea.cjs.map +1 -1
  60. package/dist/components/ContentEditor/ContentEditorTextArea.d.ts +35 -0
  61. package/dist/components/ContentEditor/ContentEditorTextArea.d.ts.map +1 -1
  62. package/dist/components/ContentEditor/ContentEditorTextArea.mjs +59 -31
  63. package/dist/components/ContentEditor/ContentEditorTextArea.mjs.map +1 -1
  64. package/dist/components/ContentEditor/index.cjs +4 -0
  65. package/dist/components/ContentEditor/index.cjs.map +1 -1
  66. package/dist/components/ContentEditor/index.d.ts +2 -0
  67. package/dist/components/ContentEditor/index.d.ts.map +1 -1
  68. package/dist/components/ContentEditor/index.mjs +5 -1
  69. package/dist/components/ContentEditor/index.mjs.map +1 -1
  70. package/dist/components/ContentSelector/ContentSelector.cjs +9 -1
  71. package/dist/components/ContentSelector/ContentSelector.cjs.map +1 -1
  72. package/dist/components/ContentSelector/ContentSelector.d.ts +167 -0
  73. package/dist/components/ContentSelector/ContentSelector.d.ts.map +1 -1
  74. package/dist/components/ContentSelector/ContentSelector.mjs +9 -1
  75. package/dist/components/ContentSelector/ContentSelector.mjs.map +1 -1
  76. package/dist/components/CopyButton/index.cjs +23 -8
  77. package/dist/components/CopyButton/index.cjs.map +1 -1
  78. package/dist/components/CopyButton/index.d.ts +78 -0
  79. package/dist/components/CopyButton/index.d.ts.map +1 -1
  80. package/dist/components/CopyButton/index.mjs +23 -8
  81. package/dist/components/CopyButton/index.mjs.map +1 -1
  82. package/dist/components/CopyToClipboard/index.cjs +58 -22
  83. package/dist/components/CopyToClipboard/index.cjs.map +1 -1
  84. package/dist/components/CopyToClipboard/index.d.ts +68 -2
  85. package/dist/components/CopyToClipboard/index.d.ts.map +1 -1
  86. package/dist/components/CopyToClipboard/index.mjs +59 -23
  87. package/dist/components/CopyToClipboard/index.mjs.map +1 -1
  88. package/dist/components/DropDown/index.cjs +6 -4
  89. package/dist/components/DropDown/index.cjs.map +1 -1
  90. package/dist/components/DropDown/index.d.ts +92 -15
  91. package/dist/components/DropDown/index.d.ts.map +1 -1
  92. package/dist/components/DropDown/index.mjs +6 -4
  93. package/dist/components/DropDown/index.mjs.map +1 -1
  94. package/dist/components/EditableField/EditableFieldInput.cjs.map +1 -1
  95. package/dist/components/EditableField/EditableFieldInput.d.ts +38 -0
  96. package/dist/components/EditableField/EditableFieldInput.d.ts.map +1 -1
  97. package/dist/components/EditableField/EditableFieldInput.mjs.map +1 -1
  98. package/dist/components/EditableField/EditableFieldLayout.cjs +10 -2
  99. package/dist/components/EditableField/EditableFieldLayout.cjs.map +1 -1
  100. package/dist/components/EditableField/EditableFieldLayout.d.ts.map +1 -1
  101. package/dist/components/EditableField/EditableFieldLayout.mjs +10 -2
  102. package/dist/components/EditableField/EditableFieldLayout.mjs.map +1 -1
  103. package/dist/components/EditableField/EditableFieldTextArea.cjs.map +1 -1
  104. package/dist/components/EditableField/EditableFieldTextArea.d.ts +42 -0
  105. package/dist/components/EditableField/EditableFieldTextArea.d.ts.map +1 -1
  106. package/dist/components/EditableField/EditableFieldTextArea.mjs.map +1 -1
  107. package/dist/components/ExpandCollapse/ExpandCollapse.cjs.map +1 -1
  108. package/dist/components/ExpandCollapse/ExpandCollapse.d.ts +58 -0
  109. package/dist/components/ExpandCollapse/ExpandCollapse.d.ts.map +1 -1
  110. package/dist/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
  111. package/dist/components/Footer/index.cjs.map +1 -1
  112. package/dist/components/Footer/index.d.ts +101 -0
  113. package/dist/components/Footer/index.d.ts.map +1 -1
  114. package/dist/components/Footer/index.mjs.map +1 -1
  115. package/dist/components/Form/elements/MultiselectElement.d.ts.map +1 -1
  116. package/dist/components/Form/elements/SelectElement.d.ts.map +1 -1
  117. package/dist/components/Form/elements/SwitchSelectorElement.d.ts.map +1 -1
  118. package/dist/components/Headers/index.cjs.map +1 -1
  119. package/dist/components/Headers/index.d.ts +69 -2
  120. package/dist/components/Headers/index.d.ts.map +1 -1
  121. package/dist/components/Headers/index.mjs.map +1 -1
  122. package/dist/components/HeightResizer/index.cjs +10 -7
  123. package/dist/components/HeightResizer/index.cjs.map +1 -1
  124. package/dist/components/HeightResizer/index.d.ts +89 -0
  125. package/dist/components/HeightResizer/index.d.ts.map +1 -1
  126. package/dist/components/HeightResizer/index.mjs +10 -7
  127. package/dist/components/HeightResizer/index.mjs.map +1 -1
  128. package/dist/components/InformationTag/index.cjs.map +1 -1
  129. package/dist/components/InformationTag/index.d.ts +72 -0
  130. package/dist/components/InformationTag/index.d.ts.map +1 -1
  131. package/dist/components/InformationTag/index.mjs.map +1 -1
  132. package/dist/components/KeyboardScreenAdapter/index.cjs.map +1 -1
  133. package/dist/components/KeyboardScreenAdapter/index.d.ts +100 -0
  134. package/dist/components/KeyboardScreenAdapter/index.d.ts.map +1 -1
  135. package/dist/components/KeyboardScreenAdapter/index.mjs.map +1 -1
  136. package/dist/components/Label/index.cjs +25 -3
  137. package/dist/components/Label/index.cjs.map +1 -1
  138. package/dist/components/Label/index.d.ts +65 -1
  139. package/dist/components/Label/index.d.ts.map +1 -1
  140. package/dist/components/Label/index.mjs +26 -4
  141. package/dist/components/Label/index.mjs.map +1 -1
  142. package/dist/components/Link/Link.cjs.map +1 -1
  143. package/dist/components/Link/Link.d.ts +169 -0
  144. package/dist/components/Link/Link.d.ts.map +1 -1
  145. package/dist/components/Link/Link.mjs.map +1 -1
  146. package/dist/components/Loader/index.cjs.map +1 -1
  147. package/dist/components/Loader/index.d.ts +82 -11
  148. package/dist/components/Loader/index.d.ts.map +1 -1
  149. package/dist/components/Loader/index.mjs.map +1 -1
  150. package/dist/components/Loader/spinner.cjs.map +1 -1
  151. package/dist/components/Loader/spinner.d.ts +56 -0
  152. package/dist/components/Loader/spinner.d.ts.map +1 -1
  153. package/dist/components/Loader/spinner.mjs.map +1 -1
  154. package/dist/components/MarkDownRender/MarkDownRender.cjs +0 -1
  155. package/dist/components/MarkDownRender/MarkDownRender.cjs.map +1 -1
  156. package/dist/components/MarkDownRender/MarkDownRender.d.ts +147 -0
  157. package/dist/components/MarkDownRender/MarkDownRender.d.ts.map +1 -1
  158. package/dist/components/MarkDownRender/MarkDownRender.mjs +0 -1
  159. package/dist/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
  160. package/dist/components/MaxHeightSmoother/index.cjs.map +1 -1
  161. package/dist/components/MaxHeightSmoother/index.d.ts +152 -0
  162. package/dist/components/MaxHeightSmoother/index.d.ts.map +1 -1
  163. package/dist/components/MaxHeightSmoother/index.mjs.map +1 -1
  164. package/dist/components/Modal/Modal.cjs +5 -0
  165. package/dist/components/Modal/Modal.cjs.map +1 -1
  166. package/dist/components/Modal/Modal.d.ts +81 -3
  167. package/dist/components/Modal/Modal.d.ts.map +1 -1
  168. package/dist/components/Modal/Modal.mjs +5 -0
  169. package/dist/components/Modal/Modal.mjs.map +1 -1
  170. package/dist/components/Navbar/Burger.cjs.map +1 -1
  171. package/dist/components/Navbar/Burger.d.ts +54 -0
  172. package/dist/components/Navbar/Burger.d.ts.map +1 -1
  173. package/dist/components/Navbar/Burger.mjs.map +1 -1
  174. package/dist/components/Navbar/DesktopNavbar.cjs.map +1 -1
  175. package/dist/components/Navbar/DesktopNavbar.d.ts +78 -0
  176. package/dist/components/Navbar/DesktopNavbar.d.ts.map +1 -1
  177. package/dist/components/Navbar/DesktopNavbar.mjs.map +1 -1
  178. package/dist/components/Navbar/MobileNavbar.cjs.map +1 -1
  179. package/dist/components/Navbar/MobileNavbar.d.ts +88 -0
  180. package/dist/components/Navbar/MobileNavbar.d.ts.map +1 -1
  181. package/dist/components/Navbar/MobileNavbar.mjs.map +1 -1
  182. package/dist/components/Navbar/index.cjs.map +1 -1
  183. package/dist/components/Navbar/index.d.ts +69 -0
  184. package/dist/components/Navbar/index.d.ts.map +1 -1
  185. package/dist/components/Navbar/index.mjs.map +1 -1
  186. package/dist/components/Navbar/useNavigation.cjs +8 -1
  187. package/dist/components/Navbar/useNavigation.cjs.map +1 -1
  188. package/dist/components/Navbar/useNavigation.d.ts +83 -0
  189. package/dist/components/Navbar/useNavigation.d.ts.map +1 -1
  190. package/dist/components/Navbar/useNavigation.mjs +8 -1
  191. package/dist/components/Navbar/useNavigation.mjs.map +1 -1
  192. package/dist/components/Pattern/DotPattern.cjs.map +1 -1
  193. package/dist/components/Pattern/DotPattern.d.ts +101 -0
  194. package/dist/components/Pattern/DotPattern.d.ts.map +1 -1
  195. package/dist/components/Pattern/DotPattern.mjs.map +1 -1
  196. package/dist/components/Pattern/GridPattern.cjs.map +1 -1
  197. package/dist/components/Pattern/GridPattern.d.ts +114 -0
  198. package/dist/components/Pattern/GridPattern.d.ts.map +1 -1
  199. package/dist/components/Pattern/GridPattern.mjs.map +1 -1
  200. package/dist/components/Pattern/SpotLight.cjs.map +1 -1
  201. package/dist/components/Pattern/SpotLight.d.ts +125 -0
  202. package/dist/components/Pattern/SpotLight.d.ts.map +1 -1
  203. package/dist/components/Pattern/SpotLight.mjs.map +1 -1
  204. package/dist/components/Popover/index.cjs +10 -10
  205. package/dist/components/Popover/index.cjs.map +1 -1
  206. package/dist/components/Popover/index.d.ts +110 -15
  207. package/dist/components/Popover/index.d.ts.map +1 -1
  208. package/dist/components/Popover/index.mjs +10 -10
  209. package/dist/components/Popover/index.mjs.map +1 -1
  210. package/dist/components/PressableSpan/PressableSpan.cjs +22 -5
  211. package/dist/components/PressableSpan/PressableSpan.cjs.map +1 -1
  212. package/dist/components/PressableSpan/PressableSpan.d.ts +105 -3
  213. package/dist/components/PressableSpan/PressableSpan.d.ts.map +1 -1
  214. package/dist/components/PressableSpan/PressableSpan.mjs +22 -5
  215. package/dist/components/PressableSpan/PressableSpan.mjs.map +1 -1
  216. package/dist/components/RightDrawer/RightDrawer.cjs.map +1 -1
  217. package/dist/components/RightDrawer/RightDrawer.d.ts +182 -0
  218. package/dist/components/RightDrawer/RightDrawer.d.ts.map +1 -1
  219. package/dist/components/RightDrawer/RightDrawer.mjs.map +1 -1
  220. package/dist/components/RightDrawer/isElementAtTopAndNotCovered.cjs.map +1 -1
  221. package/dist/components/RightDrawer/isElementAtTopAndNotCovered.d.ts +44 -0
  222. package/dist/components/RightDrawer/isElementAtTopAndNotCovered.d.ts.map +1 -1
  223. package/dist/components/RightDrawer/isElementAtTopAndNotCovered.mjs.map +1 -1
  224. package/dist/components/RightDrawer/useRightDrawerStore.cjs.map +1 -1
  225. package/dist/components/RightDrawer/useRightDrawerStore.d.ts +102 -0
  226. package/dist/components/RightDrawer/useRightDrawerStore.d.ts.map +1 -1
  227. package/dist/components/RightDrawer/useRightDrawerStore.mjs.map +1 -1
  228. package/dist/components/Select/Multiselect.cjs.map +1 -1
  229. package/dist/components/Select/Multiselect.d.ts +125 -18
  230. package/dist/components/Select/Multiselect.d.ts.map +1 -1
  231. package/dist/components/Select/Multiselect.mjs.map +1 -1
  232. package/dist/components/Select/Select.cjs.map +1 -1
  233. package/dist/components/Select/Select.d.ts +214 -7
  234. package/dist/components/Select/Select.d.ts.map +1 -1
  235. package/dist/components/Select/Select.mjs.map +1 -1
  236. package/dist/components/SwitchSelector/index.cjs.map +1 -1
  237. package/dist/components/SwitchSelector/index.d.ts +157 -8
  238. package/dist/components/SwitchSelector/index.d.ts.map +1 -1
  239. package/dist/components/SwitchSelector/index.mjs.map +1 -1
  240. package/dist/components/Table/Table.cjs.map +1 -1
  241. package/dist/components/Table/Table.d.ts +184 -0
  242. package/dist/components/Table/Table.d.ts.map +1 -1
  243. package/dist/components/Table/Table.mjs.map +1 -1
  244. package/dist/components/Tag/index.cjs.map +1 -1
  245. package/dist/components/Tag/index.d.ts +223 -0
  246. package/dist/components/Tag/index.d.ts.map +1 -1
  247. package/dist/components/Tag/index.mjs.map +1 -1
  248. package/dist/components/TextArea/AutoSizeTextArea.cjs.map +1 -1
  249. package/dist/components/TextArea/AutoSizeTextArea.d.ts +91 -0
  250. package/dist/components/TextArea/AutoSizeTextArea.d.ts.map +1 -1
  251. package/dist/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
  252. package/dist/components/TextArea/AutocompleteTextArea.cjs.map +1 -1
  253. package/dist/components/TextArea/AutocompleteTextArea.d.ts +145 -0
  254. package/dist/components/TextArea/AutocompleteTextArea.d.ts.map +1 -1
  255. package/dist/components/TextArea/AutocompleteTextArea.mjs.map +1 -1
  256. package/dist/components/TextArea/TextArea.cjs.map +1 -1
  257. package/dist/components/TextArea/TextArea.d.ts +74 -0
  258. package/dist/components/TextArea/TextArea.d.ts.map +1 -1
  259. package/dist/components/TextArea/TextArea.mjs.map +1 -1
  260. package/dist/components/Toaster/Toast.cjs +4 -0
  261. package/dist/components/Toaster/Toast.cjs.map +1 -1
  262. package/dist/components/Toaster/Toast.d.ts +148 -2
  263. package/dist/components/Toaster/Toast.d.ts.map +1 -1
  264. package/dist/components/Toaster/Toast.mjs +4 -0
  265. package/dist/components/Toaster/Toast.mjs.map +1 -1
  266. package/dist/components/Toaster/Toaster.cjs.map +1 -1
  267. package/dist/components/Toaster/Toaster.d.ts +42 -0
  268. package/dist/components/Toaster/Toaster.d.ts.map +1 -1
  269. package/dist/components/Toaster/Toaster.mjs.map +1 -1
  270. package/dist/components/Toaster/useToast.cjs.map +1 -1
  271. package/dist/components/Toaster/useToast.d.ts +199 -2
  272. package/dist/components/Toaster/useToast.d.ts.map +1 -1
  273. package/dist/components/Toaster/useToast.mjs.map +1 -1
  274. package/dist/components/WithResizer/index.cjs.map +1 -1
  275. package/dist/components/WithResizer/index.d.ts +143 -0
  276. package/dist/components/WithResizer/index.d.ts.map +1 -1
  277. package/dist/components/WithResizer/index.mjs.map +1 -1
  278. package/dist/components/index.cjs +2 -2
  279. package/dist/components/index.d.ts +0 -1
  280. package/dist/components/index.d.ts.map +1 -1
  281. package/dist/components/index.mjs +4 -4
  282. package/dist/components/index.mjs.map +1 -1
  283. package/dist/hooks/reactQuery.cjs +2 -1
  284. package/dist/hooks/reactQuery.cjs.map +1 -1
  285. package/dist/hooks/reactQuery.d.ts +1 -1
  286. package/dist/hooks/reactQuery.d.ts.map +1 -1
  287. package/dist/hooks/reactQuery.mjs +2 -1
  288. package/dist/hooks/reactQuery.mjs.map +1 -1
  289. package/dist/utils/image.cjs +30 -0
  290. package/dist/utils/image.cjs.map +1 -0
  291. package/dist/utils/image.d.ts +37 -0
  292. package/dist/utils/image.d.ts.map +1 -0
  293. package/dist/utils/image.mjs +30 -0
  294. package/dist/utils/image.mjs.map +1 -0
  295. package/package.json +20 -18
  296. package/dist/utils/capitalize.cjs +0 -10
  297. package/dist/utils/capitalize.cjs.map +0 -1
  298. package/dist/utils/capitalize.d.ts +0 -2
  299. package/dist/utils/capitalize.d.ts.map +0 -1
  300. package/dist/utils/capitalize.mjs +0 -10
  301. package/dist/utils/capitalize.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/components/Popover/index.tsx"],"sourcesContent":["import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Container } from '../Container';\n\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n identifier: string;\n};\n\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Trigger allowing to open a popover menu.\n *\n * Example:\n * ```jsx\n * <Popover identifier=\"popover\">\n * Open popover\n *\n * <Popover.Detail identifier=\"popover\">\n * <div>Content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * > Note Popover.Trigger can be replaced by a button. Don't add a button inside the trigger.\n */\nexport const Popover: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn('group/popover relative flex cursor-pointer', className)}\n aria-label={`Popover ${identifier}`}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n isFocusable?: boolean;\n isHidden?: boolean;\n isOverable?: boolean;\n identifier: string;\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n displayArrow?: boolean;\n};\n\nexport enum PopoverXAlign {\n START = 'start',\n END = 'end',\n}\n\nexport enum PopoverYAlign {\n BELOW = 'bellow',\n ABOVE = 'above',\n}\n\n/**\n * Component that opens a popover menu when the trigger is clicked.\n *\n * Example:\n * ```jsx\n * <Popover.Detail identifier=\"popover\">\n * <div>Content</div>\n * </Popover.Detail>\n * ```\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"sm\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-[1000] min-w-full ring-neutral ring-1 rounded-md',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:content-[\"\"] before:w-0 before:h-0',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-t-[10px] before:border-t-neutral',\n\n /* Visibility management */\n 'overflow-x-visible transition-all duration-400 ease-in-out opacity-0',\n isHidden !== false ? 'invisible' : 'delay-800 visible opacity-100',\n isOverable &&\n 'group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800',\n isFocusable &&\n 'group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800',\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopover.Detail = Detail;\n"],"names":["jsx","cn","PopoverXAlign","PopoverYAlign","Container"],"mappings":";;;;;AA+BO,MAAM,UAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACEA,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC,SAAAA,GAAG,8CAA8C,SAAS;AAAA,IACrE,cAAY,WAAW,UAAU;AAAA,IACjC,IAAI,2BAA2B,UAAU;AAAA,IACzC,iBAAa;AAAA,IACZ,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAaK,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,KAAA,IAAM;AAFI,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,OAAA,IAAQ;AAFE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAeZ,MAAM,SAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,MACEH,2BAAAA;AAAAA,EAACI,2BAAAA;AAAAA,EAAA;AAAA,IACC,cAAa;AAAA,IACb,eAAa;AAAA,IACb,mBAAiB,2BAA2B,UAAU;AAAA,IACtD,IAAI,oBAAoB,UAAU;AAAA,IAClC,WAAWH,SAAAA;AAAAA,MACT;AAAA;AAAA,MAGA,WAAW,WAAW;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,WAAW,WAAW;AAAA;AAAA,MAGtB,gBACE;AAAA;AAAA,MAGF,gBAAgB,WAAW,WAAW;AAAA,MACtC,gBAAgB,WAAW,SAAS;AAAA;AAAA,MAGpC,gBACE,WAAW,YACX;AAAA;AAAA,MAGF,gBACE,WAAW,WACX;AAAA;AAAA,MAGF;AAAA,MACA,aAAa,QAAQ,cAAc;AAAA,MACnC,cACE;AAAA,MACF,eACE;AAAA,MACF;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAGF,QAAQ,SAAS;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/components/Popover/index.tsx"],"sourcesContent":["import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Container } from '../Container';\n\n/**\n * Props for the main Popover component\n * Extends HTMLDivElement attributes for full DOM compatibility\n */\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n /** Unique identifier linking the trigger to its popover content for accessibility */\n identifier: string;\n};\n\n/**\n * Composite type for the Popover component with Detail subcomponent\n * Allows for Popover.Detail usage pattern\n */\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Horizontal alignment options for popover positioning\n */\nexport enum PopoverXAlign {\n /** Align popover to start (left) of trigger */\n START = 'start',\n /** Align popover to end (right) of trigger */\n END = 'end',\n}\n\n/**\n * Vertical alignment options for popover positioning\n */\nexport enum PopoverYAlign {\n /** Position popover below the trigger */\n BELOW = 'bellow',\n /** Position popover above the trigger */\n ABOVE = 'above',\n}\n\n/**\n * Popover Component\n *\n * A versatile popover container that displays contextual content when triggered by hover\n * or focus interactions. Built with accessibility in mind and supports multiple positioning\n * options with smooth animations.\n *\n * Features:\n * - Hover and focus-based triggering\n * - Multiple positioning options (above/below, start/end)\n * - Accessibility compliant with ARIA attributes\n * - Smooth animations with configurable delays\n * - Optional directional arrows\n * - Automatic z-index management\n * - Responsive design support\n *\n * Architecture:\n * - Main Popover acts as trigger container\n * - Popover.Detail renders the actual popover content\n * - Uses CSS groups for coordinated hover/focus states\n * - Unique identifier system prevents conflicts\n *\n * @example\n * Basic hover popover:\n * ```jsx\n * <Popover identifier=\"help-tooltip\">\n * <button>Need Help?</button>\n *\n * <Popover.Detail identifier=\"help-tooltip\">\n * <div>This is helpful information!</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Focus-triggered popover:\n * ```jsx\n * <Popover identifier=\"focus-menu\">\n * <input placeholder=\"Focus me\" />\n *\n * <Popover.Detail\n * identifier=\"focus-menu\"\n * isFocusable\n * isOverable={false}\n * >\n * <div>Focus-only menu content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Positioned popover with custom alignment:\n * ```jsx\n * <Popover identifier=\"positioned\">\n * <span>Hover me</span>\n *\n * <Popover.Detail\n * identifier=\"positioned\"\n * xAlign={PopoverXAlign.END}\n * yAlign={PopoverYAlign.ABOVE}\n * displayArrow={false}\n * >\n * <div>Above and right-aligned</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * Accessibility Features:\n * - Proper ARIA labeling and relationships\n * - Keyboard navigation support\n * - Screen reader compatibility\n * - Focus management\n *\n * Performance Considerations:\n * - CSS-only animations for smooth transitions\n * - Efficient group-based state management\n * - Minimal DOM updates during interactions\n *\n * @param props - Popover component props\n * @returns Trigger container with popover functionality\n */\nexport const Popover: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn('group/popover relative flex cursor-pointer', className)}\n aria-label={`Popover ${identifier}`}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Props for the Popover.Detail component\n * Extends HTMLDivElement attributes for styling flexibility\n */\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n /** Whether the popover responds to focus events on the trigger */\n isFocusable?: boolean;\n /** Controls visibility state - undefined allows automatic hover/focus control */\n isHidden?: boolean;\n /** Whether the popover responds to hover events on the trigger */\n isOverable?: boolean;\n /** Unique identifier matching the trigger's identifier for accessibility */\n identifier: string;\n /** Horizontal positioning relative to trigger */\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n /** Vertical positioning relative to trigger */\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n /** Whether to display the directional arrow indicator */\n displayArrow?: boolean;\n};\n\n/**\n * Popover Detail Component\n *\n * The actual popover content container with advanced positioning, animation, and\n * accessibility features. Automatically manages visibility based on trigger interactions.\n *\n * Features:\n * - Precise positioning with alignment options\n * - Smooth fade and slide animations\n * - Configurable directional arrows\n * - Hover and focus interaction support\n * - Accessibility-compliant ARIA attributes\n * - High z-index for overlay behavior\n * - Automatic visibility management\n *\n * Positioning System:\n * - X-axis: START (left-aligned) or END (right-aligned)\n * - Y-axis: BELOW (underneath) or ABOVE (on top)\n * - Automatic spacing with 1rem gap from trigger\n * - Responsive minimum width matching trigger\n *\n * Arrow Indicators:\n * - CSS-generated triangular arrows\n * - Positioned based on alignment settings\n * - Points toward trigger for visual connection\n * - Can be disabled for clean, minimal appearance\n *\n * Animation Behavior:\n * - Starts invisible with opacity: 0\n * - Smooth 400ms transitions with easing\n * - 800ms delay for hover states (prevents flicker)\n * - Immediate hiding when trigger loses focus/hover\n *\n * @example\n * Rich content popover:\n * ```jsx\n * <Popover.Detail identifier=\"rich-content\">\n * <div className=\"p-4\">\n * <h3>Popover Title</h3>\n * <p>Detailed information with multiple paragraphs.</p>\n * <button>Action Button</button>\n * </div>\n * </Popover.Detail>\n * ```\n *\n * @example\n * Menu-style popover:\n * ```jsx\n * <Popover.Detail\n * identifier=\"context-menu\"\n * displayArrow={false}\n * xAlign={PopoverXAlign.END}\n * >\n * <ul className=\"py-2\">\n * <li><button className=\"w-full px-4 py-2\">Edit</button></li>\n * <li><button className=\"w-full px-4 py-2\">Delete</button></li>\n * </ul>\n * </Popover.Detail>\n * ```\n *\n * @param props - Popover Detail component props\n * @returns Positioned popover content with animations and accessibility\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"sm\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-[1000] min-w-full ring-neutral ring-1 rounded-md',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:content-[\"\"] before:w-0 before:h-0',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-t-[10px] before:border-t-neutral',\n\n /* Visibility management */\n 'overflow-x-visible transition-all duration-400 ease-in-out opacity-0',\n isHidden !== false ? 'invisible' : 'delay-800 visible opacity-100',\n isOverable &&\n 'group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800',\n isFocusable &&\n 'group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800',\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopover.Detail = Detail;\n"],"names":["PopoverXAlign","PopoverYAlign","jsx","cn","Container"],"mappings":";;;;;AA2BO,IAAK,kCAAAA,mBAAL;AAELA,iBAAA,OAAA,IAAQ;AAERA,iBAAA,KAAA,IAAM;AAJI,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAUL,IAAK,kCAAAC,mBAAL;AAELA,iBAAA,OAAA,IAAQ;AAERA,iBAAA,OAAA,IAAQ;AAJE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAwFL,MAAM,UAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACEC,2BAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAWC,SAAAA,GAAG,8CAA8C,SAAS;AAAA,IACrE,cAAY,WAAW,UAAU;AAAA,IACjC,IAAI,2BAA2B,UAAU;AAAA,IACzC,iBAAa;AAAA,IACZ,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAuFF,MAAM,SAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,MACED,2BAAAA;AAAAA,EAACE,2BAAAA;AAAAA,EAAA;AAAA,IACC,cAAa;AAAA,IACb,eAAa;AAAA,IACb,mBAAiB,2BAA2B,UAAU;AAAA,IACtD,IAAI,oBAAoB,UAAU;AAAA,IAClC,WAAWD,SAAAA;AAAAA,MACT;AAAA;AAAA,MAGA,WAAW,WAAW;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,WAAW,WAAW;AAAA;AAAA,MAGtB,gBACE;AAAA;AAAA,MAGF,gBAAgB,WAAW,WAAW;AAAA,MACtC,gBAAgB,WAAW,SAAS;AAAA;AAAA,MAGpC,gBACE,WAAW,YACX;AAAA;AAAA,MAGF,gBACE,WAAW,WACX;AAAA;AAAA,MAGF;AAAA,MACA,aAAa,QAAQ,cAAc;AAAA,MACnC,cACE;AAAA,MACF,eACE;AAAA,MACF;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAGF,QAAQ,SAAS;;;;"}
@@ -1,42 +1,137 @@
1
1
  import { DetailedHTMLProps, FC, HTMLAttributes } from 'react';
2
+ /**
3
+ * Props for the main Popover component
4
+ * Extends HTMLDivElement attributes for full DOM compatibility
5
+ */
2
6
  export type PopoverProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
7
+ /** Unique identifier linking the trigger to its popover content for accessibility */
3
8
  identifier: string;
4
9
  };
10
+ /**
11
+ * Composite type for the Popover component with Detail subcomponent
12
+ * Allows for Popover.Detail usage pattern
13
+ */
5
14
  export type PopoverType = FC<PopoverProps> & {
6
15
  Detail: FC<DetailProps>;
7
16
  };
8
17
  /**
9
- * Trigger allowing to open a popover menu.
18
+ * Horizontal alignment options for popover positioning
19
+ */
20
+ export declare enum PopoverXAlign {
21
+ /** Align popover to start (left) of trigger */
22
+ START = "start",
23
+ /** Align popover to end (right) of trigger */
24
+ END = "end"
25
+ }
26
+ /**
27
+ * Vertical alignment options for popover positioning
28
+ */
29
+ export declare enum PopoverYAlign {
30
+ /** Position popover below the trigger */
31
+ BELOW = "bellow",
32
+ /** Position popover above the trigger */
33
+ ABOVE = "above"
34
+ }
35
+ /**
36
+ * Popover Component
37
+ *
38
+ * A versatile popover container that displays contextual content when triggered by hover
39
+ * or focus interactions. Built with accessibility in mind and supports multiple positioning
40
+ * options with smooth animations.
10
41
  *
11
- * Example:
42
+ * Features:
43
+ * - Hover and focus-based triggering
44
+ * - Multiple positioning options (above/below, start/end)
45
+ * - Accessibility compliant with ARIA attributes
46
+ * - Smooth animations with configurable delays
47
+ * - Optional directional arrows
48
+ * - Automatic z-index management
49
+ * - Responsive design support
50
+ *
51
+ * Architecture:
52
+ * - Main Popover acts as trigger container
53
+ * - Popover.Detail renders the actual popover content
54
+ * - Uses CSS groups for coordinated hover/focus states
55
+ * - Unique identifier system prevents conflicts
56
+ *
57
+ * @example
58
+ * Basic hover popover:
12
59
  * ```jsx
13
- * <Popover identifier="popover">
14
- * Open popover
60
+ * <Popover identifier="help-tooltip">
61
+ * <button>Need Help?</button>
15
62
  *
16
- * <Popover.Detail identifier="popover">
17
- * <div>Content</div>
63
+ * <Popover.Detail identifier="help-tooltip">
64
+ * <div>This is helpful information!</div>
18
65
  * </Popover.Detail>
19
66
  * </Popover>
20
67
  * ```
21
68
  *
22
- * > Note Popover.Trigger can be replaced by a button. Don't add a button inside the trigger.
69
+ * @example
70
+ * Focus-triggered popover:
71
+ * ```jsx
72
+ * <Popover identifier="focus-menu">
73
+ * <input placeholder="Focus me" />
74
+ *
75
+ * <Popover.Detail
76
+ * identifier="focus-menu"
77
+ * isFocusable
78
+ * isOverable={false}
79
+ * >
80
+ * <div>Focus-only menu content</div>
81
+ * </Popover.Detail>
82
+ * </Popover>
83
+ * ```
84
+ *
85
+ * @example
86
+ * Positioned popover with custom alignment:
87
+ * ```jsx
88
+ * <Popover identifier="positioned">
89
+ * <span>Hover me</span>
90
+ *
91
+ * <Popover.Detail
92
+ * identifier="positioned"
93
+ * xAlign={PopoverXAlign.END}
94
+ * yAlign={PopoverYAlign.ABOVE}
95
+ * displayArrow={false}
96
+ * >
97
+ * <div>Above and right-aligned</div>
98
+ * </Popover.Detail>
99
+ * </Popover>
100
+ * ```
101
+ *
102
+ * Accessibility Features:
103
+ * - Proper ARIA labeling and relationships
104
+ * - Keyboard navigation support
105
+ * - Screen reader compatibility
106
+ * - Focus management
107
+ *
108
+ * Performance Considerations:
109
+ * - CSS-only animations for smooth transitions
110
+ * - Efficient group-based state management
111
+ * - Minimal DOM updates during interactions
112
+ *
113
+ * @param props - Popover component props
114
+ * @returns Trigger container with popover functionality
23
115
  */
24
116
  export declare const Popover: PopoverType;
117
+ /**
118
+ * Props for the Popover.Detail component
119
+ * Extends HTMLDivElement attributes for styling flexibility
120
+ */
25
121
  export type DetailProps = HTMLAttributes<HTMLDivElement> & {
122
+ /** Whether the popover responds to focus events on the trigger */
26
123
  isFocusable?: boolean;
124
+ /** Controls visibility state - undefined allows automatic hover/focus control */
27
125
  isHidden?: boolean;
126
+ /** Whether the popover responds to hover events on the trigger */
28
127
  isOverable?: boolean;
128
+ /** Unique identifier matching the trigger's identifier for accessibility */
29
129
  identifier: string;
130
+ /** Horizontal positioning relative to trigger */
30
131
  xAlign?: PopoverXAlign | `${PopoverXAlign}`;
132
+ /** Vertical positioning relative to trigger */
31
133
  yAlign?: PopoverYAlign | `${PopoverYAlign}`;
134
+ /** Whether to display the directional arrow indicator */
32
135
  displayArrow?: boolean;
33
136
  };
34
- export declare enum PopoverXAlign {
35
- START = "start",
36
- END = "end"
37
- }
38
- export declare enum PopoverYAlign {
39
- BELOW = "bellow",
40
- ABOVE = "above"
41
- }
42
137
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Popover/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAInE,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAC1C,cAAc,CAAC,cAAc,CAAC,EAC9B,cAAc,CACf,GAAG;IACF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG;IAC3C,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,OAAO,EAAE,WAerB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,oBAAY,aAAa;IACvB,KAAK,UAAU;IACf,GAAG,QAAQ;CACZ;AAED,oBAAY,aAAa;IACvB,KAAK,WAAW;IAChB,KAAK,UAAU;CAChB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Popover/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAInE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAC1C,cAAc,CAAC,cAAc,CAAC,EAC9B,cAAc,CACf,GAAG;IACF,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG;IAC3C,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,oBAAY,aAAa;IACvB,+CAA+C;IAC/C,KAAK,UAAU;IACf,8CAA8C;IAC9C,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,oBAAY,aAAa;IACvB,yCAAyC;IACzC,KAAK,WAAW;IAChB,yCAAyC;IACzC,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,eAAO,MAAM,OAAO,EAAE,WAerB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IACzD,kEAAkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5C,+CAA+C;IAC/C,MAAM,CAAC,EAAE,aAAa,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5C,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC"}
@@ -1,6 +1,16 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../../utils/cn.mjs";
3
3
  import { Container } from "../Container/index.mjs";
4
+ var PopoverXAlign = /* @__PURE__ */ ((PopoverXAlign2) => {
5
+ PopoverXAlign2["START"] = "start";
6
+ PopoverXAlign2["END"] = "end";
7
+ return PopoverXAlign2;
8
+ })(PopoverXAlign || {});
9
+ var PopoverYAlign = /* @__PURE__ */ ((PopoverYAlign2) => {
10
+ PopoverYAlign2["BELOW"] = "bellow";
11
+ PopoverYAlign2["ABOVE"] = "above";
12
+ return PopoverYAlign2;
13
+ })(PopoverYAlign || {});
4
14
  const Popover = ({
5
15
  children,
6
16
  className,
@@ -17,16 +27,6 @@ const Popover = ({
17
27
  children
18
28
  }
19
29
  );
20
- var PopoverXAlign = /* @__PURE__ */ ((PopoverXAlign2) => {
21
- PopoverXAlign2["START"] = "start";
22
- PopoverXAlign2["END"] = "end";
23
- return PopoverXAlign2;
24
- })(PopoverXAlign || {});
25
- var PopoverYAlign = /* @__PURE__ */ ((PopoverYAlign2) => {
26
- PopoverYAlign2["BELOW"] = "bellow";
27
- PopoverYAlign2["ABOVE"] = "above";
28
- return PopoverYAlign2;
29
- })(PopoverYAlign || {});
30
30
  const Detail = ({
31
31
  children,
32
32
  isHidden = void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../src/components/Popover/index.tsx"],"sourcesContent":["import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Container } from '../Container';\n\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n identifier: string;\n};\n\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Trigger allowing to open a popover menu.\n *\n * Example:\n * ```jsx\n * <Popover identifier=\"popover\">\n * Open popover\n *\n * <Popover.Detail identifier=\"popover\">\n * <div>Content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * > Note Popover.Trigger can be replaced by a button. Don't add a button inside the trigger.\n */\nexport const Popover: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn('group/popover relative flex cursor-pointer', className)}\n aria-label={`Popover ${identifier}`}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n isFocusable?: boolean;\n isHidden?: boolean;\n isOverable?: boolean;\n identifier: string;\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n displayArrow?: boolean;\n};\n\nexport enum PopoverXAlign {\n START = 'start',\n END = 'end',\n}\n\nexport enum PopoverYAlign {\n BELOW = 'bellow',\n ABOVE = 'above',\n}\n\n/**\n * Component that opens a popover menu when the trigger is clicked.\n *\n * Example:\n * ```jsx\n * <Popover.Detail identifier=\"popover\">\n * <div>Content</div>\n * </Popover.Detail>\n * ```\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"sm\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-[1000] min-w-full ring-neutral ring-1 rounded-md',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:content-[\"\"] before:w-0 before:h-0',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-t-[10px] before:border-t-neutral',\n\n /* Visibility management */\n 'overflow-x-visible transition-all duration-400 ease-in-out opacity-0',\n isHidden !== false ? 'invisible' : 'delay-800 visible opacity-100',\n isOverable &&\n 'group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800',\n isFocusable &&\n 'group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800',\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopover.Detail = Detail;\n"],"names":["PopoverXAlign","PopoverYAlign"],"mappings":";;;AA+BO,MAAM,UAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAW,GAAG,8CAA8C,SAAS;AAAA,IACrE,cAAY,WAAW,UAAU;AAAA,IACjC,IAAI,2BAA2B,UAAU;AAAA,IACzC,iBAAa;AAAA,IACZ,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAaK,IAAK,kCAAAA,mBAAL;AACLA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,KAAA,IAAM;AAFI,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,OAAA,IAAQ;AACRA,iBAAA,OAAA,IAAQ;AAFE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAeZ,MAAM,SAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,MACE;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,cAAa;AAAA,IACb,eAAa;AAAA,IACb,mBAAiB,2BAA2B,UAAU;AAAA,IACtD,IAAI,oBAAoB,UAAU;AAAA,IAClC,WAAW;AAAA,MACT;AAAA;AAAA,MAGA,WAAW,WAAW;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,WAAW,WAAW;AAAA;AAAA,MAGtB,gBACE;AAAA;AAAA,MAGF,gBAAgB,WAAW,WAAW;AAAA,MACtC,gBAAgB,WAAW,SAAS;AAAA;AAAA,MAGpC,gBACE,WAAW,YACX;AAAA;AAAA,MAGF,gBACE,WAAW,WACX;AAAA;AAAA,MAGF;AAAA,MACA,aAAa,QAAQ,cAAc;AAAA,MACnC,cACE;AAAA,MACF,eACE;AAAA,MACF;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAGF,QAAQ,SAAS;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../src/components/Popover/index.tsx"],"sourcesContent":["import type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Container } from '../Container';\n\n/**\n * Props for the main Popover component\n * Extends HTMLDivElement attributes for full DOM compatibility\n */\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n /** Unique identifier linking the trigger to its popover content for accessibility */\n identifier: string;\n};\n\n/**\n * Composite type for the Popover component with Detail subcomponent\n * Allows for Popover.Detail usage pattern\n */\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Horizontal alignment options for popover positioning\n */\nexport enum PopoverXAlign {\n /** Align popover to start (left) of trigger */\n START = 'start',\n /** Align popover to end (right) of trigger */\n END = 'end',\n}\n\n/**\n * Vertical alignment options for popover positioning\n */\nexport enum PopoverYAlign {\n /** Position popover below the trigger */\n BELOW = 'bellow',\n /** Position popover above the trigger */\n ABOVE = 'above',\n}\n\n/**\n * Popover Component\n *\n * A versatile popover container that displays contextual content when triggered by hover\n * or focus interactions. Built with accessibility in mind and supports multiple positioning\n * options with smooth animations.\n *\n * Features:\n * - Hover and focus-based triggering\n * - Multiple positioning options (above/below, start/end)\n * - Accessibility compliant with ARIA attributes\n * - Smooth animations with configurable delays\n * - Optional directional arrows\n * - Automatic z-index management\n * - Responsive design support\n *\n * Architecture:\n * - Main Popover acts as trigger container\n * - Popover.Detail renders the actual popover content\n * - Uses CSS groups for coordinated hover/focus states\n * - Unique identifier system prevents conflicts\n *\n * @example\n * Basic hover popover:\n * ```jsx\n * <Popover identifier=\"help-tooltip\">\n * <button>Need Help?</button>\n *\n * <Popover.Detail identifier=\"help-tooltip\">\n * <div>This is helpful information!</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Focus-triggered popover:\n * ```jsx\n * <Popover identifier=\"focus-menu\">\n * <input placeholder=\"Focus me\" />\n *\n * <Popover.Detail\n * identifier=\"focus-menu\"\n * isFocusable\n * isOverable={false}\n * >\n * <div>Focus-only menu content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Positioned popover with custom alignment:\n * ```jsx\n * <Popover identifier=\"positioned\">\n * <span>Hover me</span>\n *\n * <Popover.Detail\n * identifier=\"positioned\"\n * xAlign={PopoverXAlign.END}\n * yAlign={PopoverYAlign.ABOVE}\n * displayArrow={false}\n * >\n * <div>Above and right-aligned</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * Accessibility Features:\n * - Proper ARIA labeling and relationships\n * - Keyboard navigation support\n * - Screen reader compatibility\n * - Focus management\n *\n * Performance Considerations:\n * - CSS-only animations for smooth transitions\n * - Efficient group-based state management\n * - Minimal DOM updates during interactions\n *\n * @param props - Popover component props\n * @returns Trigger container with popover functionality\n */\nexport const Popover: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn('group/popover relative flex cursor-pointer', className)}\n aria-label={`Popover ${identifier}`}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Props for the Popover.Detail component\n * Extends HTMLDivElement attributes for styling flexibility\n */\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n /** Whether the popover responds to focus events on the trigger */\n isFocusable?: boolean;\n /** Controls visibility state - undefined allows automatic hover/focus control */\n isHidden?: boolean;\n /** Whether the popover responds to hover events on the trigger */\n isOverable?: boolean;\n /** Unique identifier matching the trigger's identifier for accessibility */\n identifier: string;\n /** Horizontal positioning relative to trigger */\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n /** Vertical positioning relative to trigger */\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n /** Whether to display the directional arrow indicator */\n displayArrow?: boolean;\n};\n\n/**\n * Popover Detail Component\n *\n * The actual popover content container with advanced positioning, animation, and\n * accessibility features. Automatically manages visibility based on trigger interactions.\n *\n * Features:\n * - Precise positioning with alignment options\n * - Smooth fade and slide animations\n * - Configurable directional arrows\n * - Hover and focus interaction support\n * - Accessibility-compliant ARIA attributes\n * - High z-index for overlay behavior\n * - Automatic visibility management\n *\n * Positioning System:\n * - X-axis: START (left-aligned) or END (right-aligned)\n * - Y-axis: BELOW (underneath) or ABOVE (on top)\n * - Automatic spacing with 1rem gap from trigger\n * - Responsive minimum width matching trigger\n *\n * Arrow Indicators:\n * - CSS-generated triangular arrows\n * - Positioned based on alignment settings\n * - Points toward trigger for visual connection\n * - Can be disabled for clean, minimal appearance\n *\n * Animation Behavior:\n * - Starts invisible with opacity: 0\n * - Smooth 400ms transitions with easing\n * - 800ms delay for hover states (prevents flicker)\n * - Immediate hiding when trigger loses focus/hover\n *\n * @example\n * Rich content popover:\n * ```jsx\n * <Popover.Detail identifier=\"rich-content\">\n * <div className=\"p-4\">\n * <h3>Popover Title</h3>\n * <p>Detailed information with multiple paragraphs.</p>\n * <button>Action Button</button>\n * </div>\n * </Popover.Detail>\n * ```\n *\n * @example\n * Menu-style popover:\n * ```jsx\n * <Popover.Detail\n * identifier=\"context-menu\"\n * displayArrow={false}\n * xAlign={PopoverXAlign.END}\n * >\n * <ul className=\"py-2\">\n * <li><button className=\"w-full px-4 py-2\">Edit</button></li>\n * <li><button className=\"w-full px-4 py-2\">Delete</button></li>\n * </ul>\n * </Popover.Detail>\n * ```\n *\n * @param props - Popover Detail component props\n * @returns Positioned popover content with animations and accessibility\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"sm\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-[1000] min-w-full ring-neutral ring-1 rounded-md',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:content-[\"\"] before:w-0 before:h-0',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-l-[10px] before:border-l-transparent before:border-r-[10px] before:border-r-transparent before:border-t-[10px] before:border-t-neutral',\n\n /* Visibility management */\n 'overflow-x-visible transition-all duration-400 ease-in-out opacity-0',\n isHidden !== false ? 'invisible' : 'delay-800 visible opacity-100',\n isOverable &&\n 'group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800',\n isFocusable &&\n 'group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800',\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopover.Detail = Detail;\n"],"names":["PopoverXAlign","PopoverYAlign"],"mappings":";;;AA2BO,IAAK,kCAAAA,mBAAL;AAELA,iBAAA,OAAA,IAAQ;AAERA,iBAAA,KAAA,IAAM;AAJI,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAUL,IAAK,kCAAAC,mBAAL;AAELA,iBAAA,OAAA,IAAQ;AAERA,iBAAA,OAAA,IAAQ;AAJE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAwFL,MAAM,UAAuB,CAAC;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MACE;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,WAAW,GAAG,8CAA8C,SAAS;AAAA,IACrE,cAAY,WAAW,UAAU;AAAA,IACjC,IAAI,2BAA2B,UAAU;AAAA,IACzC,iBAAa;AAAA,IACZ,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAuFF,MAAM,SAA0B,CAAC;AAAA,EAC/B;AAAA,EACA,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,GAAG;AACL,MACE;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,cAAa;AAAA,IACb,eAAa;AAAA,IACb,mBAAiB,2BAA2B,UAAU;AAAA,IACtD,IAAI,oBAAoB,UAAU;AAAA,IAClC,WAAW;AAAA,MACT;AAAA;AAAA,MAGA,WAAW,WAAW;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,WAAW,YAAY;AAAA,MACvB,WAAW,WAAW;AAAA;AAAA,MAGtB,gBACE;AAAA;AAAA,MAGF,gBAAgB,WAAW,WAAW;AAAA,MACtC,gBAAgB,WAAW,SAAS;AAAA;AAAA,MAGpC,gBACE,WAAW,YACX;AAAA;AAAA,MAGF,gBACE,WAAW,WACX;AAAA;AAAA,MAGF;AAAA,MACA,aAAa,QAAQ,cAAc;AAAA,MACnC,cACE;AAAA,MACF,eACE;AAAA,MACF;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEH;AAAA,EAAA;AACH;AAGF,QAAQ,SAAS;"}
@@ -13,7 +13,7 @@ const PressableSpan = ({
13
13
  isSelecting: isSelectingProp,
14
14
  ...props
15
15
  }) => {
16
- const divRef = ReactExports.useRef(null);
16
+ const elementRef = ReactExports.useRef(null);
17
17
  const [isSelectingState, setIsSelectingState] = ReactExports.useState(isSelectingProp);
18
18
  const pressTimerRef = ReactExports.useRef(null);
19
19
  const handleOnLongPress = () => {
@@ -40,7 +40,7 @@ const PressableSpan = ({
40
40
  };
41
41
  const handleClickOutside = ReactExports.useCallback(
42
42
  (event) => {
43
- if (divRef.current && !divRef.current.contains(event.target)) {
43
+ if (elementRef.current && !elementRef.current.contains(event.target)) {
44
44
  setIsSelectingState(false);
45
45
  onUnselect?.();
46
46
  }
@@ -62,16 +62,33 @@ const PressableSpan = ({
62
62
  const handleOnBlur = () => {
63
63
  setIsSelectingState(false);
64
64
  };
65
+ const handleKeyDown = (e) => {
66
+ switch (e.key) {
67
+ case "Enter":
68
+ case " ":
69
+ e.preventDefault();
70
+ handleOnLongPress();
71
+ break;
72
+ case "Escape":
73
+ e.preventDefault();
74
+ setIsSelectingState(false);
75
+ onUnselect?.();
76
+ break;
77
+ }
78
+ };
79
+ const isCurrentlySelecting = isSelectingProp ?? isSelectingState;
65
80
  return /* @__PURE__ */ jsxRuntime.jsx(
66
81
  "span",
67
82
  {
68
83
  className: utils_cn.cn(
69
84
  "inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200",
70
- isSelectingProp ?? isSelectingState ? "outline-inherit" : "hover:outline-inherit"
85
+ isCurrentlySelecting ? "outline-inherit" : "hover:outline-inherit"
71
86
  ),
72
87
  role: "button",
73
88
  tabIndex: 0,
74
- onKeyUp: () => null,
89
+ "aria-pressed": isCurrentlySelecting ? "true" : "false",
90
+ "aria-label": `${isCurrentlySelecting ? "Selected" : "Selectable"} content`,
91
+ onKeyDown: handleKeyDown,
75
92
  onClick: handleOnClick,
76
93
  onMouseDown: handleMouseDown,
77
94
  onMouseUp: handleMouseUp,
@@ -80,7 +97,7 @@ const PressableSpan = ({
80
97
  onTouchEnd: handleMouseUp,
81
98
  onTouchCancel: handleMouseUp,
82
99
  onBlur: handleOnBlur,
83
- ref: divRef,
100
+ ref: elementRef,
84
101
  ...props,
85
102
  children
86
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PressableSpan.cjs","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type FC,\n type HTMLAttributes,\n type MouseEventHandler,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 400;\n\ntype PressableDivProps = {\n onPress: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport const PressableSpan: FC<PressableDivProps> = ({\n children,\n onPress: onSelect,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseUp = () => {\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n className={cn(\n 'inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200',\n (isSelectingProp ?? isSelectingState)\n ? 'outline-inherit'\n : 'hover:outline-inherit'\n )}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"names":["useRef","useState","useCallback","useEffect","jsx","cn"],"mappings":";;;;;;AAaA,MAAM,gCAAgC;AAS/B,MAAM,gBAAuC,CAAC;AAAA,EACnD;AAAA,EACA,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,GAAG;AACL,MAAM;AACJ,QAAM,SAASA,aAAAA,OAAuB,IAAI;AAC1C,QAAM,CAAC,kBAAkB,mBAAmB,IAAIC,aAAAA,SAAS,eAAe;AACxE,QAAM,gBAAgBD,aAAAA,OAA6C,IAAI;AAEvE,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,IAAI;AACxB,aAAA;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,kBAAc,UAAU,WAAW,MAAM;AACvC,wBAAA;AAAA,IACF,GAAG,aAAa;AAAA,EAClB;AAEA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,cAAc,SAAS;AACzB,mBAAa,cAAc,OAAO;AAClC,oBAAc,UAAU;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,oBAAA;AACA,oBAAA;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM;AAC1B,oBAAA;AAAA,EACF;AAGA,QAAM,qBAAqBE,aAAAA;AAAAA,IACzB,CAAC,UAAsB;AACrB,UAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,SAAS,MAAM,MAAc,GAAG;AACpE,4BAAoB,KAAK;AACzB,qBAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAGbC,eAAAA,UAAU,MAAM;AAEd,aAAS,iBAAiB,aAAa,kBAAkB;AAEzD,WAAO,MAAM;AAEX,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAE9D;AAAA,EACF,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,gBAAmD,CAAC,MAAM;AAC9D,QAAI,kBAAkB;AACpB,QAAE,eAAA;AACF,QAAE,gBAAA;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAEzB,wBAAoB,KAAK;AAAA,EAC3B;AAEA,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,SAAAA;AAAAA,QACT;AAAA,QACC,mBAAmB,mBAChB,oBACA;AAAA,MAAA;AAAA,MAEN,MAAK;AAAA,MACL,UAAU;AAAA,MACV,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,KAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
1
+ {"version":3,"file":"PressableSpan.cjs","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type FC,\n type HTMLAttributes,\n type MouseEventHandler,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 400;\n\n/**\n * Props for the PressableSpan component\n */\ntype PressableSpanProps = {\n /**\n * Callback function triggered when a long press is detected\n * @example\n * ```tsx\n * <PressableSpan onPress={() => console.log('Long pressed!')}>\n * Press and hold me\n * </PressableSpan>\n * ```\n */\n onPress: () => void;\n\n /**\n * Optional callback function triggered when clicking outside the component while it's in selecting state\n * @example\n * ```tsx\n * <PressableSpan\n * onPress={() => setIsEditing(true)}\n * onClickOutside={() => setIsEditing(false)}\n * >\n * Click outside to deselect\n * </PressableSpan>\n * ```\n */\n onClickOutside?: () => void;\n\n /**\n * Duration in milliseconds for long press detection\n * @default 400\n * @example\n * ```tsx\n * <PressableSpan pressDuration={800} onPress={() => {}}>\n * Longer press required\n * </PressableSpan>\n * ```\n */\n pressDuration?: number;\n\n /**\n * External control for the selecting state\n * @example\n * ```tsx\n * <PressableSpan isSelecting={isEditing} onPress={() => {}}>\n * Externally controlled\n * </PressableSpan>\n * ```\n */\n isSelecting?: boolean;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * PressableSpan - An interactive span element that responds to long press gestures\n *\n * A versatile component that detects long press interactions and provides visual feedback.\n * Commonly used for text editing interfaces, selection systems, and interactive content\n * that requires differentiation between quick clicks and intentional long presses.\n *\n * ## Key Features\n * - **Long Press Detection**: Configurable press duration for different interaction patterns\n * - **Visual Feedback**: Smooth outline transitions to indicate interactive and selected states\n * - **Click Outside Detection**: Automatically deselects when clicking outside the component\n * - **Touch Support**: Works seamlessly on both desktop and mobile devices\n * - **Accessible**: Keyboard navigation support and proper ARIA attributes\n *\n * ## Use Cases\n * - Text editing interfaces where long press activates edit mode\n * - Content selection systems with visual feedback\n * - Interactive cards or elements that need press-and-hold activation\n * - Mobile-friendly interfaces requiring long press gestures\n *\n * ## Accessibility\n * - Uses semantic `role=\"button\"` for proper screen reader announcement\n * - Keyboard navigable with `tabIndex={0}`\n * - Focus management with proper blur handling\n * - Visual outline indicators for focus and selection states\n *\n * @example\n * Basic usage with long press detection:\n * ```tsx\n * <PressableSpan onPress={() => setIsEditing(true)}>\n * Press and hold to edit this text\n * </PressableSpan>\n * ```\n *\n * @example\n * With custom press duration and click outside handling:\n * ```tsx\n * <PressableSpan\n * pressDuration={600}\n * onPress={() => setIsEditing(true)}\n * onClickOutside={() => setIsEditing(false)}\n * isSelecting={isEditing}\n * >\n * Custom behavior configuration\n * </PressableSpan>\n * ```\n *\n * @example\n * In a content editing context:\n * ```tsx\n * <PressableSpan\n * onPress={() => startEditingContent(contentId)}\n * onClickOutside={() => saveAndExitEditing()}\n * className=\"prose-text\"\n * >\n * {editableContent}\n * </PressableSpan>\n * ```\n */\n\nexport const PressableSpan: FC<PressableSpanProps> = ({\n children,\n onPress: onSelect,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const elementRef = useRef<HTMLSpanElement>(null);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseUp = () => {\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (\n elementRef.current &&\n !elementRef.current.contains(event.target as Node)\n ) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n /**\n * Handle keyboard interactions\n * - Enter/Space: Trigger long press action immediately\n * - Escape: Cancel selection/editing state\n */\n const handleKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault();\n handleOnLongPress();\n break;\n case 'Escape':\n e.preventDefault();\n setIsSelectingState(false);\n onUnselect?.();\n break;\n default:\n break;\n }\n };\n\n const isCurrentlySelecting = isSelectingProp ?? isSelectingState;\n\n return (\n <span\n className={cn(\n 'inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200',\n isCurrentlySelecting ? 'outline-inherit' : 'hover:outline-inherit'\n )}\n role=\"button\"\n tabIndex={0}\n aria-pressed={isCurrentlySelecting ? 'true' : 'false'}\n aria-label={`${isCurrentlySelecting ? 'Selected' : 'Selectable'} content`}\n onKeyDown={handleKeyDown}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n ref={elementRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"names":["useRef","useState","useCallback","useEffect","jsx","cn"],"mappings":";;;;;;AAaA,MAAM,gCAAgC;AAmH/B,MAAM,gBAAwC,CAAC;AAAA,EACpD;AAAA,EACA,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,GAAG;AACL,MAAM;AACJ,QAAM,aAAaA,aAAAA,OAAwB,IAAI;AAC/C,QAAM,CAAC,kBAAkB,mBAAmB,IAAIC,aAAAA,SAAS,eAAe;AACxE,QAAM,gBAAgBD,aAAAA,OAA6C,IAAI;AAEvE,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,IAAI;AACxB,aAAA;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,kBAAc,UAAU,WAAW,MAAM;AACvC,wBAAA;AAAA,IACF,GAAG,aAAa;AAAA,EAClB;AAEA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,cAAc,SAAS;AACzB,mBAAa,cAAc,OAAO;AAClC,oBAAc,UAAU;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,oBAAA;AACA,oBAAA;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM;AAC1B,oBAAA;AAAA,EACF;AAGA,QAAM,qBAAqBE,aAAAA;AAAAA,IACzB,CAAC,UAAsB;AACrB,UACE,WAAW,WACX,CAAC,WAAW,QAAQ,SAAS,MAAM,MAAc,GACjD;AACA,4BAAoB,KAAK;AACzB,qBAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAGbC,eAAAA,UAAU,MAAM;AAEd,aAAS,iBAAiB,aAAa,kBAAkB;AAEzD,WAAO,MAAM;AAEX,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAE9D;AAAA,EACF,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,gBAAmD,CAAC,MAAM;AAC9D,QAAI,kBAAkB;AACpB,QAAE,eAAA;AACF,QAAE,gBAAA;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAEzB,wBAAoB,KAAK;AAAA,EAC3B;AAOA,QAAM,gBAAgB,CAAC,MAA4C;AACjE,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AACH,UAAE,eAAA;AACF,0BAAA;AACA;AAAA,MACF,KAAK;AACH,UAAE,eAAA;AACF,4BAAoB,KAAK;AACzB,qBAAA;AACA;AAAA,IAEA;AAAA,EAEN;AAEA,QAAM,uBAAuB,mBAAmB;AAEhD,SACEC,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,SAAAA;AAAAA,QACT;AAAA,QACA,uBAAuB,oBAAoB;AAAA,MAAA;AAAA,MAE7C,MAAK;AAAA,MACL,UAAU;AAAA,MACV,gBAAc,uBAAuB,SAAS;AAAA,MAC9C,cAAY,GAAG,uBAAuB,aAAa,YAAY;AAAA,MAC/D,WAAW;AAAA,MACX,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,KAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
@@ -1,10 +1,112 @@
1
1
  import { FC, HTMLAttributes } from 'react';
2
- type PressableDivProps = {
2
+ /**
3
+ * Props for the PressableSpan component
4
+ */
5
+ type PressableSpanProps = {
6
+ /**
7
+ * Callback function triggered when a long press is detected
8
+ * @example
9
+ * ```tsx
10
+ * <PressableSpan onPress={() => console.log('Long pressed!')}>
11
+ * Press and hold me
12
+ * </PressableSpan>
13
+ * ```
14
+ */
3
15
  onPress: () => void;
16
+ /**
17
+ * Optional callback function triggered when clicking outside the component while it's in selecting state
18
+ * @example
19
+ * ```tsx
20
+ * <PressableSpan
21
+ * onPress={() => setIsEditing(true)}
22
+ * onClickOutside={() => setIsEditing(false)}
23
+ * >
24
+ * Click outside to deselect
25
+ * </PressableSpan>
26
+ * ```
27
+ */
4
28
  onClickOutside?: () => void;
29
+ /**
30
+ * Duration in milliseconds for long press detection
31
+ * @default 400
32
+ * @example
33
+ * ```tsx
34
+ * <PressableSpan pressDuration={800} onPress={() => {}}>
35
+ * Longer press required
36
+ * </PressableSpan>
37
+ * ```
38
+ */
5
39
  pressDuration?: number;
40
+ /**
41
+ * External control for the selecting state
42
+ * @example
43
+ * ```tsx
44
+ * <PressableSpan isSelecting={isEditing} onPress={() => {}}>
45
+ * Externally controlled
46
+ * </PressableSpan>
47
+ * ```
48
+ */
6
49
  isSelecting?: boolean;
7
- } & HTMLAttributes<HTMLDivElement>;
8
- export declare const PressableSpan: FC<PressableDivProps>;
50
+ } & HTMLAttributes<HTMLSpanElement>;
51
+ /**
52
+ * PressableSpan - An interactive span element that responds to long press gestures
53
+ *
54
+ * A versatile component that detects long press interactions and provides visual feedback.
55
+ * Commonly used for text editing interfaces, selection systems, and interactive content
56
+ * that requires differentiation between quick clicks and intentional long presses.
57
+ *
58
+ * ## Key Features
59
+ * - **Long Press Detection**: Configurable press duration for different interaction patterns
60
+ * - **Visual Feedback**: Smooth outline transitions to indicate interactive and selected states
61
+ * - **Click Outside Detection**: Automatically deselects when clicking outside the component
62
+ * - **Touch Support**: Works seamlessly on both desktop and mobile devices
63
+ * - **Accessible**: Keyboard navigation support and proper ARIA attributes
64
+ *
65
+ * ## Use Cases
66
+ * - Text editing interfaces where long press activates edit mode
67
+ * - Content selection systems with visual feedback
68
+ * - Interactive cards or elements that need press-and-hold activation
69
+ * - Mobile-friendly interfaces requiring long press gestures
70
+ *
71
+ * ## Accessibility
72
+ * - Uses semantic `role="button"` for proper screen reader announcement
73
+ * - Keyboard navigable with `tabIndex={0}`
74
+ * - Focus management with proper blur handling
75
+ * - Visual outline indicators for focus and selection states
76
+ *
77
+ * @example
78
+ * Basic usage with long press detection:
79
+ * ```tsx
80
+ * <PressableSpan onPress={() => setIsEditing(true)}>
81
+ * Press and hold to edit this text
82
+ * </PressableSpan>
83
+ * ```
84
+ *
85
+ * @example
86
+ * With custom press duration and click outside handling:
87
+ * ```tsx
88
+ * <PressableSpan
89
+ * pressDuration={600}
90
+ * onPress={() => setIsEditing(true)}
91
+ * onClickOutside={() => setIsEditing(false)}
92
+ * isSelecting={isEditing}
93
+ * >
94
+ * Custom behavior configuration
95
+ * </PressableSpan>
96
+ * ```
97
+ *
98
+ * @example
99
+ * In a content editing context:
100
+ * ```tsx
101
+ * <PressableSpan
102
+ * onPress={() => startEditingContent(contentId)}
103
+ * onClickOutside={() => saveAndExitEditing()}
104
+ * className="prose-text"
105
+ * >
106
+ * {editableContent}
107
+ * </PressableSpan>
108
+ * ```
109
+ */
110
+ export declare const PressableSpan: FC<PressableSpanProps>;
9
111
  export {};
10
112
  //# sourceMappingURL=PressableSpan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PressableSpan.d.ts","sourceRoot":"","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,cAAc,EAEpB,MAAM,OAAO,CAAC;AAKf,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;AAEnC,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,iBAAiB,CAkG/C,CAAC"}
1
+ {"version":3,"file":"PressableSpan.d.ts","sourceRoot":"","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,cAAc,EAEpB,MAAM,OAAO,CAAC;AAKf;;GAEG;AACH,KAAK,kBAAkB,GAAG;IACxB;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAEH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CA6HhD,CAAC"}
@@ -11,7 +11,7 @@ const PressableSpan = ({
11
11
  isSelecting: isSelectingProp,
12
12
  ...props
13
13
  }) => {
14
- const divRef = useRef(null);
14
+ const elementRef = useRef(null);
15
15
  const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);
16
16
  const pressTimerRef = useRef(null);
17
17
  const handleOnLongPress = () => {
@@ -38,7 +38,7 @@ const PressableSpan = ({
38
38
  };
39
39
  const handleClickOutside = useCallback(
40
40
  (event) => {
41
- if (divRef.current && !divRef.current.contains(event.target)) {
41
+ if (elementRef.current && !elementRef.current.contains(event.target)) {
42
42
  setIsSelectingState(false);
43
43
  onUnselect?.();
44
44
  }
@@ -60,16 +60,33 @@ const PressableSpan = ({
60
60
  const handleOnBlur = () => {
61
61
  setIsSelectingState(false);
62
62
  };
63
+ const handleKeyDown = (e) => {
64
+ switch (e.key) {
65
+ case "Enter":
66
+ case " ":
67
+ e.preventDefault();
68
+ handleOnLongPress();
69
+ break;
70
+ case "Escape":
71
+ e.preventDefault();
72
+ setIsSelectingState(false);
73
+ onUnselect?.();
74
+ break;
75
+ }
76
+ };
77
+ const isCurrentlySelecting = isSelectingProp ?? isSelectingState;
63
78
  return /* @__PURE__ */ jsx(
64
79
  "span",
65
80
  {
66
81
  className: cn(
67
82
  "inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200",
68
- isSelectingProp ?? isSelectingState ? "outline-inherit" : "hover:outline-inherit"
83
+ isCurrentlySelecting ? "outline-inherit" : "hover:outline-inherit"
69
84
  ),
70
85
  role: "button",
71
86
  tabIndex: 0,
72
- onKeyUp: () => null,
87
+ "aria-pressed": isCurrentlySelecting ? "true" : "false",
88
+ "aria-label": `${isCurrentlySelecting ? "Selected" : "Selectable"} content`,
89
+ onKeyDown: handleKeyDown,
73
90
  onClick: handleOnClick,
74
91
  onMouseDown: handleMouseDown,
75
92
  onMouseUp: handleMouseUp,
@@ -78,7 +95,7 @@ const PressableSpan = ({
78
95
  onTouchEnd: handleMouseUp,
79
96
  onTouchCancel: handleMouseUp,
80
97
  onBlur: handleOnBlur,
81
- ref: divRef,
98
+ ref: elementRef,
82
99
  ...props,
83
100
  children
84
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PressableSpan.mjs","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type FC,\n type HTMLAttributes,\n type MouseEventHandler,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 400;\n\ntype PressableDivProps = {\n onPress: () => void;\n onClickOutside?: () => void;\n pressDuration?: number;\n isSelecting?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport const PressableSpan: FC<PressableDivProps> = ({\n children,\n onPress: onSelect,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const divRef = useRef<HTMLDivElement>(null);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseUp = () => {\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (divRef.current && !divRef.current.contains(event.target as Node)) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n return (\n <span\n className={cn(\n 'inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200',\n (isSelectingProp ?? isSelectingState)\n ? 'outline-inherit'\n : 'hover:outline-inherit'\n )}\n role=\"button\"\n tabIndex={0}\n onKeyUp={() => null}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n ref={divRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"names":[],"mappings":";;;;AAaA,MAAM,gCAAgC;AAS/B,MAAM,gBAAuC,CAAC;AAAA,EACnD;AAAA,EACA,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,OAAuB,IAAI;AAC1C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,eAAe;AACxE,QAAM,gBAAgB,OAA6C,IAAI;AAEvE,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,IAAI;AACxB,aAAA;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,kBAAc,UAAU,WAAW,MAAM;AACvC,wBAAA;AAAA,IACF,GAAG,aAAa;AAAA,EAClB;AAEA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,cAAc,SAAS;AACzB,mBAAa,cAAc,OAAO;AAClC,oBAAc,UAAU;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,oBAAA;AACA,oBAAA;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM;AAC1B,oBAAA;AAAA,EACF;AAGA,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAAsB;AACrB,UAAI,OAAO,WAAW,CAAC,OAAO,QAAQ,SAAS,MAAM,MAAc,GAAG;AACpE,4BAAoB,KAAK;AACzB,qBAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAGb,YAAU,MAAM;AAEd,aAAS,iBAAiB,aAAa,kBAAkB;AAEzD,WAAO,MAAM;AAEX,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAE9D;AAAA,EACF,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,gBAAmD,CAAC,MAAM;AAC9D,QAAI,kBAAkB;AACpB,QAAE,eAAA;AACF,QAAE,gBAAA;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAEzB,wBAAoB,KAAK;AAAA,EAC3B;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACC,mBAAmB,mBAChB,oBACA;AAAA,MAAA;AAAA,MAEN,MAAK;AAAA,MACL,UAAU;AAAA,MACV,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,KAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"PressableSpan.mjs","sources":["../../../src/components/PressableSpan/PressableSpan.tsx"],"sourcesContent":["'use client';\n\nimport {\n useCallback,\n useEffect,\n useRef,\n useState,\n type FC,\n type HTMLAttributes,\n type MouseEventHandler,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\nconst DEFAULT_PRESS_DETECT_DURATION = 400;\n\n/**\n * Props for the PressableSpan component\n */\ntype PressableSpanProps = {\n /**\n * Callback function triggered when a long press is detected\n * @example\n * ```tsx\n * <PressableSpan onPress={() => console.log('Long pressed!')}>\n * Press and hold me\n * </PressableSpan>\n * ```\n */\n onPress: () => void;\n\n /**\n * Optional callback function triggered when clicking outside the component while it's in selecting state\n * @example\n * ```tsx\n * <PressableSpan\n * onPress={() => setIsEditing(true)}\n * onClickOutside={() => setIsEditing(false)}\n * >\n * Click outside to deselect\n * </PressableSpan>\n * ```\n */\n onClickOutside?: () => void;\n\n /**\n * Duration in milliseconds for long press detection\n * @default 400\n * @example\n * ```tsx\n * <PressableSpan pressDuration={800} onPress={() => {}}>\n * Longer press required\n * </PressableSpan>\n * ```\n */\n pressDuration?: number;\n\n /**\n * External control for the selecting state\n * @example\n * ```tsx\n * <PressableSpan isSelecting={isEditing} onPress={() => {}}>\n * Externally controlled\n * </PressableSpan>\n * ```\n */\n isSelecting?: boolean;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * PressableSpan - An interactive span element that responds to long press gestures\n *\n * A versatile component that detects long press interactions and provides visual feedback.\n * Commonly used for text editing interfaces, selection systems, and interactive content\n * that requires differentiation between quick clicks and intentional long presses.\n *\n * ## Key Features\n * - **Long Press Detection**: Configurable press duration for different interaction patterns\n * - **Visual Feedback**: Smooth outline transitions to indicate interactive and selected states\n * - **Click Outside Detection**: Automatically deselects when clicking outside the component\n * - **Touch Support**: Works seamlessly on both desktop and mobile devices\n * - **Accessible**: Keyboard navigation support and proper ARIA attributes\n *\n * ## Use Cases\n * - Text editing interfaces where long press activates edit mode\n * - Content selection systems with visual feedback\n * - Interactive cards or elements that need press-and-hold activation\n * - Mobile-friendly interfaces requiring long press gestures\n *\n * ## Accessibility\n * - Uses semantic `role=\"button\"` for proper screen reader announcement\n * - Keyboard navigable with `tabIndex={0}`\n * - Focus management with proper blur handling\n * - Visual outline indicators for focus and selection states\n *\n * @example\n * Basic usage with long press detection:\n * ```tsx\n * <PressableSpan onPress={() => setIsEditing(true)}>\n * Press and hold to edit this text\n * </PressableSpan>\n * ```\n *\n * @example\n * With custom press duration and click outside handling:\n * ```tsx\n * <PressableSpan\n * pressDuration={600}\n * onPress={() => setIsEditing(true)}\n * onClickOutside={() => setIsEditing(false)}\n * isSelecting={isEditing}\n * >\n * Custom behavior configuration\n * </PressableSpan>\n * ```\n *\n * @example\n * In a content editing context:\n * ```tsx\n * <PressableSpan\n * onPress={() => startEditingContent(contentId)}\n * onClickOutside={() => saveAndExitEditing()}\n * className=\"prose-text\"\n * >\n * {editableContent}\n * </PressableSpan>\n * ```\n */\n\nexport const PressableSpan: FC<PressableSpanProps> = ({\n children,\n onPress: onSelect,\n onClickOutside: onUnselect,\n pressDuration = DEFAULT_PRESS_DETECT_DURATION,\n isSelecting: isSelectingProp,\n ...props\n}) => {\n const elementRef = useRef<HTMLSpanElement>(null);\n const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);\n const pressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const handleOnLongPress = () => {\n setIsSelectingState(true);\n onSelect();\n };\n\n const startPressTimer = () => {\n pressTimerRef.current = setTimeout(() => {\n handleOnLongPress();\n }, pressDuration);\n };\n\n const clearPressTimer = () => {\n if (pressTimerRef.current) {\n clearTimeout(pressTimerRef.current);\n pressTimerRef.current = null;\n }\n };\n\n const handleMouseDown = () => {\n clearPressTimer(); // Ensure any previous timer is cleared\n startPressTimer();\n };\n\n const handleMouseUp = () => {\n clearPressTimer();\n };\n\n // Use useCallback to ensure the function identity remains stable\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (\n elementRef.current &&\n !elementRef.current.contains(event.target as Node)\n ) {\n setIsSelectingState(false);\n onUnselect?.();\n }\n },\n [onUnselect]\n );\n\n useEffect(() => {\n // Attach click outside listener\n document.addEventListener('mousedown', handleClickOutside);\n\n return () => {\n // Cleanup\n document.removeEventListener('mousedown', handleClickOutside);\n // clearPressTimer(); // Ensure to clear the timer when component unmounts\n };\n }, [handleClickOutside]);\n\n const handleOnClick: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n };\n\n const handleOnBlur = () => {\n // Stop editing when the element loses focus\n setIsSelectingState(false);\n };\n\n /**\n * Handle keyboard interactions\n * - Enter/Space: Trigger long press action immediately\n * - Escape: Cancel selection/editing state\n */\n const handleKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>) => {\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault();\n handleOnLongPress();\n break;\n case 'Escape':\n e.preventDefault();\n setIsSelectingState(false);\n onUnselect?.();\n break;\n default:\n break;\n }\n };\n\n const isCurrentlySelecting = isSelectingProp ?? isSelectingState;\n\n return (\n <span\n className={cn(\n 'inline cursor-pointer select-none rounded-md outline outline-2 outline-offset-4 outline-transparent transition-all delay-100 duration-200',\n isCurrentlySelecting ? 'outline-inherit' : 'hover:outline-inherit'\n )}\n role=\"button\"\n tabIndex={0}\n aria-pressed={isCurrentlySelecting ? 'true' : 'false'}\n aria-label={`${isCurrentlySelecting ? 'Selected' : 'Selectable'} content`}\n onKeyDown={handleKeyDown}\n onClick={handleOnClick}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onTouchStart={handleMouseDown}\n onTouchEnd={handleMouseUp}\n onTouchCancel={handleMouseUp}\n onBlur={handleOnBlur}\n ref={elementRef}\n {...props}\n >\n {children}\n </span>\n );\n};\n"],"names":[],"mappings":";;;;AAaA,MAAM,gCAAgC;AAmH/B,MAAM,gBAAwC,CAAC;AAAA,EACpD;AAAA,EACA,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,GAAG;AACL,MAAM;AACJ,QAAM,aAAa,OAAwB,IAAI;AAC/C,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,eAAe;AACxE,QAAM,gBAAgB,OAA6C,IAAI;AAEvE,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,IAAI;AACxB,aAAA;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,kBAAc,UAAU,WAAW,MAAM;AACvC,wBAAA;AAAA,IACF,GAAG,aAAa;AAAA,EAClB;AAEA,QAAM,kBAAkB,MAAM;AAC5B,QAAI,cAAc,SAAS;AACzB,mBAAa,cAAc,OAAO;AAClC,oBAAc,UAAU;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,kBAAkB,MAAM;AAC5B,oBAAA;AACA,oBAAA;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM;AAC1B,oBAAA;AAAA,EACF;AAGA,QAAM,qBAAqB;AAAA,IACzB,CAAC,UAAsB;AACrB,UACE,WAAW,WACX,CAAC,WAAW,QAAQ,SAAS,MAAM,MAAc,GACjD;AACA,4BAAoB,KAAK;AACzB,qBAAA;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAGb,YAAU,MAAM;AAEd,aAAS,iBAAiB,aAAa,kBAAkB;AAEzD,WAAO,MAAM;AAEX,eAAS,oBAAoB,aAAa,kBAAkB;AAAA,IAE9D;AAAA,EACF,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,gBAAmD,CAAC,MAAM;AAC9D,QAAI,kBAAkB;AACpB,QAAE,eAAA;AACF,QAAE,gBAAA;AAAA,IACJ;AAAA,EACF;AAEA,QAAM,eAAe,MAAM;AAEzB,wBAAoB,KAAK;AAAA,EAC3B;AAOA,QAAM,gBAAgB,CAAC,MAA4C;AACjE,YAAQ,EAAE,KAAA;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AACH,UAAE,eAAA;AACF,0BAAA;AACA;AAAA,MACF,KAAK;AACH,UAAE,eAAA;AACF,4BAAoB,KAAK;AACzB,qBAAA;AACA;AAAA,IAEA;AAAA,EAEN;AAEA,QAAM,uBAAuB,mBAAmB;AAEhD,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,uBAAuB,oBAAoB;AAAA,MAAA;AAAA,MAE7C,MAAK;AAAA,MACL,UAAU;AAAA,MACV,gBAAc,uBAAuB,SAAS;AAAA,MAC9C,cAAY,GAAG,uBAAuB,aAAa,YAAY;AAAA,MAC/D,WAAW;AAAA,MACX,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc;AAAA,MACd,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,MACR,KAAK;AAAA,MACJ,GAAG;AAAA,MAEH;AAAA,IAAA;AAAA,EAAA;AAGP;"}