@povio/ui 5.0.0-rc.1 → 5.0.0-rc.11

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 (452) hide show
  1. package/.rulesync/rules/ui-buttons-and-content.md +56 -0
  2. package/.rulesync/rules/ui-inputs-and-forms.md +62 -0
  3. package/.rulesync/rules/ui-overlays-navigation-and-styling.md +49 -0
  4. package/.rulesync/rules/ui-overview.md +33 -0
  5. package/README.md +102 -17
  6. package/dist/{Accordion-CzFKi8Bp.js → Accordion-BzwO4_ml.js} +20 -136
  7. package/dist/{Alert-T25LY8ZL.js → Alert-CnvEb1D_.js} +16 -12
  8. package/dist/{Alert-f1dG-4Uy.d.ts → Alert-DfiJbKH0.d.ts} +2 -1
  9. package/dist/{AlertDialog-B6R2MbNg.d.ts → AlertDialog-OWTbR4km.d.ts} +3 -3
  10. package/dist/AppCanvasPage-BTmt8poT.d.ts +82 -0
  11. package/dist/AppCanvasPage-BsQrZ8q7.js +2497 -0
  12. package/dist/{Autocomplete-CQ63Cynd.d.ts → Autocomplete-C6RRxImn.d.ts} +1 -1
  13. package/dist/{Badge-YKlKz-Jy.d.ts → Badge-CBNpj823.d.ts} +8 -5
  14. package/dist/BadgeButton-Ccgt3oGO.d.ts +15 -0
  15. package/dist/{BottomSheet-DvqBvth_.js → BottomSheet-BXLE3161.js} +7 -6
  16. package/dist/{BottomSheet-xaymO7aQ.d.ts → BottomSheet-DbQuzfAB.d.ts} +1 -1
  17. package/dist/{BottomSheet.lazy-CGBRPve_.d.ts → BottomSheet.lazy-D9LCEo7s.d.ts} +1 -1
  18. package/dist/{Breadcrumbs-DyriI-Bi.d.ts → Breadcrumbs-CUV6CU8Q.d.ts} +1 -1
  19. package/dist/{Breadcrumbs-DiIYJAWf.js → Breadcrumbs-FF8hMfXd.js} +24 -38
  20. package/dist/Button-C5rv4Cr2.js +506 -0
  21. package/dist/{Button-BZ3is6IU.d.ts → Button-D-4qb0IR.d.ts} +3 -3
  22. package/dist/{ButtonContent-B2_dZ6vA.js → ButtonContent-c7lJayVQ.js} +10 -8
  23. package/dist/{Calendar-DzQApBCy.js → Calendar-DRHruqr_.js} +26 -148
  24. package/dist/CanvasComponentsFrame-C0Sf9RcC.js +21 -0
  25. package/dist/{CheckContent-DZ7Gk8GS.js → CheckContent-D7sZPmzx.js} +2 -2
  26. package/dist/{Checkbox-BepzfVfK.js → Checkbox-D3f2Plbc.js} +6 -6
  27. package/dist/{Checkbox-CHpgW3fI.d.ts → Checkbox-x2MuL477.d.ts} +1 -1
  28. package/dist/{CheckboxCheckmark-B3lnOjsU.js → CheckboxCheckmark-FwKjPVbV.js} +19 -16
  29. package/dist/{CheckboxGroup-CXrR3A-c.d.ts → CheckboxGroup-Dio2rvF5.d.ts} +3 -3
  30. package/dist/ComponentGallery-DDSqnm9f.js +3574 -0
  31. package/dist/{DatePicker-B3l9TEjW.d.ts → DatePicker-1LJ2LqST.d.ts} +3 -3
  32. package/dist/{DatePicker-CI87jC4_.js → DatePicker-xDEqzNJv.js} +17 -16
  33. package/dist/{DatePickerInput-UBZcTmdv.js → DatePickerInput-B0fEeCOf.js} +17 -27
  34. package/dist/{DatePickerInput-CZTEsrS0.d.ts → DatePickerInput-ai4apf8B.d.ts} +3 -3
  35. package/dist/{DateRangePicker-DKkc2B3n.d.ts → DateRangePicker-Dfptit_Z.d.ts} +3 -3
  36. package/dist/{DateRangePicker-BX2O5zA8.js → DateRangePicker-DxuVhRaf.js} +26 -195
  37. package/dist/{DateTimePicker-CVfkp45w.js → DateTimePicker-4N1Pka07.js} +16 -15
  38. package/dist/{DateTimePicker-IHr-wPq8.d.ts → DateTimePicker-DpsfukpQ.d.ts} +3 -3
  39. package/dist/{Dialog-DdRP4YFC.js → Dialog-9manOgMA.js} +4 -4
  40. package/dist/{Dialog-CXoVeIkU.js → Dialog-CKLkS00H.js} +10 -2
  41. package/dist/{Dialog-DEbI_9S-.d.ts → Dialog-CW93T9X1.d.ts} +3 -2
  42. package/dist/{DropdownMenu-zrodtd44.js → DropdownMenu-5jmtgLXd.js} +8 -6
  43. package/dist/{DropdownMenu-CWDhk3XA.d.ts → DropdownMenu-JNpYT4-3.d.ts} +3 -2
  44. package/dist/{DropdownMenuDesktop-CGYxsavQ.js → DropdownMenuDesktop-Cl9gZVq0.js} +9 -38
  45. package/dist/{FileInput-Dz1eESr_.js → FileInput-DUyc_sVu.js} +11 -9
  46. package/dist/{FileInput-BQbn77bE.d.ts → FileInput-Dt3UDg2s.d.ts} +5 -4
  47. package/dist/{FileTrigger-CDXcQthK.js → FileTrigger-Cthk5_Wp.js} +1 -30
  48. package/dist/{FileUpload-qySCMcLn.d.ts → FileUpload-BXlKtQ4L.d.ts} +1 -1
  49. package/dist/{FileUpload-D3Io7Is5.js → FileUpload-Cx98L1jz.js} +53 -140
  50. package/dist/{FileUploadContainer-qOyGvb5J.d.ts → FileUploadContainer-BURZAS2M.d.ts} +1 -1
  51. package/dist/{Form-u_N_6mwo.d.ts → Form-DmcByQts.d.ts} +1 -1
  52. package/dist/{FormField-CHD4OJOt.js → FormField-9h3JAhaY.js} +11 -10
  53. package/dist/{FormField-B0miX3gu.d.ts → FormField-C8_T6by9.d.ts} +1 -1
  54. package/dist/{FormFieldError-QRAFHUTt.js → FormFieldError-DeOHHLo2.js} +1 -1
  55. package/dist/FormFieldHeaderTooltip-BV2Ju4oB.js +17 -0
  56. package/dist/{IconButton-KXecZgYX.d.ts → IconButton-D4thBurp.d.ts} +2 -2
  57. package/dist/IconSlot-DSK7qNxc.js +79 -0
  58. package/dist/{InlineIconButton-CbKZ2U_a.d.ts → InlineIconButton-BeJCjl-q.d.ts} +2 -2
  59. package/dist/{InlineTooltipWrapper-g5yoeH1B.js → InlineTooltipWrapper-BpApaGXV.js} +3 -3
  60. package/dist/{Input-efmPwk8f.d.ts → Input-CHD67H4o.d.ts} +3 -3
  61. package/dist/{InputContent-DuBa9FuI.d.ts → InputContent-B6CIQNnE.d.ts} +3 -3
  62. package/dist/{InputItem-2zf6QI5L.js → InputItem-Cv19Hwnx.js} +11 -11
  63. package/dist/{Inputs-C-w03Q_F.d.ts → Inputs-C0sUmuPv.d.ts} +1 -1
  64. package/dist/{Inputs-BceDTmdT.js → Inputs-D1aE_J9f.js} +1 -1
  65. package/dist/{Link-QYpprkN1.d.ts → Link-Ow9H7kNv.d.ts} +3 -2
  66. package/dist/{ListBox-B7DW1S7n.js → ListBox-CL8Ar4Q_.js} +5 -4
  67. package/dist/{MenuItem--Mjd_yK8.d.ts → MenuItem-DHyqOqln.d.ts} +1 -1
  68. package/dist/{Modal-CoFt5PGP.js → Modal-w60dVQcb.js} +1 -1
  69. package/dist/{NumberField-z2JatYK0.d.ts → NumberField-4SX3R6IR.d.ts} +3 -3
  70. package/dist/NumberFormatter-CLDS_LRZ.js +265 -0
  71. package/dist/{NumberRangeInput-BxVrHq8R.js → NumberRangeInput-Bzfe-RlV.js} +9 -8
  72. package/dist/{NumberRangeInput-Chai3iEi.d.ts → NumberRangeInput-CKmLfgVD.d.ts} +2 -2
  73. package/dist/{Pagination-CXtIDclf.d.ts → Pagination-CwQu5Py8.d.ts} +1 -1
  74. package/dist/{PaginationList-CXG4jWFD.d.ts → PaginationList-DMRUGtf8.d.ts} +1 -1
  75. package/dist/{PaginationList-0bAmvXC0.js → PaginationList-DtvuP63b.js} +2 -2
  76. package/dist/{PasswordInput-ub2TQxef.d.ts → PasswordInput-tLGcHS6H.d.ts} +1 -1
  77. package/dist/{Popover-DUKH0q9u.d.ts → Popover-BTHPteIh.d.ts} +2 -2
  78. package/dist/{Progress-DQWiFP0L.js → Progress-B3mY9rIP.js} +2 -2
  79. package/dist/{Progress-Dho39FDs.d.ts → Progress-CjWOR38H.d.ts} +2 -1
  80. package/dist/{QuerySelect-Bo1K6gi_.d.ts → QuerySelect-CgfnA3d-.d.ts} +2 -2
  81. package/dist/{RadioGroup-B_zJdn4y.d.ts → RadioGroup-CvmI9i_U.d.ts} +3 -3
  82. package/dist/{RadioGroup-SSZYch-J.js → RadioGroup-efBKgTYA.js} +13 -13
  83. package/dist/{RichTextEditor-D6RewmRj.js → RichTextEditor-Bd7F5D8f.js} +52 -133
  84. package/dist/{RichTextEditor-B_JX3nor.d.ts → RichTextEditor-CsDZcgyf.d.ts} +1 -1
  85. package/dist/{Select-CuZDkeQs.js → Select-CgIhoWgk.js} +5 -4
  86. package/dist/{Select-DeapZMYx.d.ts → Select-DKBPfNUe.d.ts} +1 -1
  87. package/dist/{SelectBase-7SE9Za2r.d.ts → SelectBase-BkIhS9Dg.d.ts} +3 -3
  88. package/dist/{Slider-BFViQmM3.d.ts → Slider-BtUXzztJ.d.ts} +1 -1
  89. package/dist/{Slider-DJ9K_a-x.js → Slider-CMg0BXJO.js} +11 -11
  90. package/dist/{Spinner-BEYBu85B.js → Spinner-BeVTUzzx.js} +1 -1
  91. package/dist/{Spinner-BbcI6IOb.d.ts → Spinner-DbXeDOa2.d.ts} +2 -1
  92. package/dist/{SplitButton-lL87EcBL.d.ts → SplitButton-D9ngY1rJ.d.ts} +3 -3
  93. package/dist/{Stepper-C1YPgTBG.js → Stepper-Cp5vbL5g.js} +4 -117
  94. package/dist/{Stepper-hlhViuaK.d.ts → Stepper-TATlHZhQ.d.ts} +9 -8
  95. package/dist/{Switch-JxRmH1dX.js → Switch-CqnGEdeD.js} +11 -11
  96. package/dist/{Switch-DPftmB1b.d.ts → Switch-s_EPn0Jz.d.ts} +1 -1
  97. package/dist/Table-BN2_J_Ne.js +636 -0
  98. package/dist/Tag-AHfV_XSf.d.ts +44 -0
  99. package/dist/{Tag-HiDH438e.js → Tag-DPg5sL1Z.js} +22 -21
  100. package/dist/{TextArea-BhrCBGbq.d.ts → TextArea-D6kcAwGn.d.ts} +2 -2
  101. package/dist/{TextArea-gikUKKDl.js → TextArea-uPffb457.js} +7 -7
  102. package/dist/{TextButton-DnXRykhF.d.ts → TextButton-XUhV_1s0.d.ts} +4 -4
  103. package/dist/{TimePicker-DtNTOOGr.js → TimePicker-DN-i98z5.js} +15 -14
  104. package/dist/{TimePicker-CmT89X7v.d.ts → TimePicker-Dex9aU7D.d.ts} +2 -2
  105. package/dist/Toast-DtG3pA61.js +53 -0
  106. package/dist/{Toast-B4cXs2rj.d.ts → Toast-ruXqONDA.d.ts} +1 -1
  107. package/dist/{ToastContainer-BbsMIwtC.js → ToastContainer-qgpzMFD4.js} +4 -3
  108. package/dist/{ToggleButton-BGuzPJDO.d.ts → ToggleButton-7aP8Jb11.d.ts} +2 -2
  109. package/dist/{ToggleGroup-D9CFdM5-.d.ts → ToggleGroup-CRFDIPGZ.d.ts} +1 -1
  110. package/dist/{ToggleGroup-Cl0NS3fe.js → ToggleGroup-DmVPNWok.js} +29 -123
  111. package/dist/{Tooltip-aE1Vswxz.js → Tooltip-CpG1nz7Y.js} +8 -49
  112. package/dist/{Tooltip-D7dNwGy9.d.ts → Tooltip-DHv6vAqW.d.ts} +6 -5
  113. package/dist/{TooltipWrapper-CRf-JFeo.js → TooltipWrapper-CDHFaUKZ.js} +4 -4
  114. package/dist/{Typography-B0Gp1lpc.js → Typography-LU4z2pR1.js} +2 -2
  115. package/dist/{Typography-BiuidzDC.d.ts → Typography-XljT9s02.d.ts} +1 -1
  116. package/dist/UIConfigurator-C_2kgJtm.js +6880 -0
  117. package/dist/accordion.cva-CL1bVscW.js +129 -0
  118. package/dist/{autocomplete-BJ7rqWa4.d.ts → autocomplete-B-JuxTYN.d.ts} +2 -2
  119. package/dist/badgeButton.cva-B2bgCQP6.d.ts +41 -0
  120. package/dist/badgeButton.cva-CvN4CTx5.js +300 -0
  121. package/dist/breadcrumbs.cva-7zzdDhVR.js +27 -0
  122. package/dist/{button.cva-BvRI-3Gn.d.ts → button.cva-C7kEhgoA.d.ts} +7 -6
  123. package/dist/{buttonContent.cva-BDT_CReI.d.ts → buttonContent.cva-DPIlROA9.d.ts} +2 -2
  124. package/dist/{checkbox-BfcE8J5P.d.ts → checkbox-CRP4QRfP.d.ts} +1 -1
  125. package/dist/{checkbox-group-CHs2wFHS.d.ts → checkbox-group-BI_RwIJ4.d.ts} +1 -1
  126. package/dist/{checkbox.cva-gv87kr1W.d.ts → checkbox.cva-DBqfmYHY.d.ts} +5 -4
  127. package/dist/components/accordion.js +1 -1
  128. package/dist/components/alert-dialog.d.ts +1 -1
  129. package/dist/components/alert-dialog.js +4 -4
  130. package/dist/components/alert.d.ts +1 -1
  131. package/dist/components/alert.js +1 -1
  132. package/dist/components/autocomplete.d.ts +1 -1
  133. package/dist/components/autocomplete.js +5 -4
  134. package/dist/components/badge-button.d.ts +2 -0
  135. package/dist/components/{pill-button.js → badge-button.js} +13 -12
  136. package/dist/components/badge.d.ts +1 -1
  137. package/dist/components/badge.js +56 -37
  138. package/dist/components/bottom-sheet.d.ts +2 -2
  139. package/dist/components/bottom-sheet.js +2 -2
  140. package/dist/components/breadcrumbs.d.ts +1 -1
  141. package/dist/components/breadcrumbs.js +1 -1
  142. package/dist/components/button.d.ts +2 -2
  143. package/dist/components/button.js +1 -1
  144. package/dist/components/checkbox-group.d.ts +1 -1
  145. package/dist/components/checkbox-group.js +6 -6
  146. package/dist/components/checkbox.d.ts +1 -1
  147. package/dist/components/checkbox.js +1 -1
  148. package/dist/components/date-picker.d.ts +1 -1
  149. package/dist/components/date-picker.js +1 -1
  150. package/dist/components/date-range-picker.d.ts +1 -1
  151. package/dist/components/date-range-picker.js +1 -1
  152. package/dist/components/date-time-picker.d.ts +1 -1
  153. package/dist/components/date-time-picker.js +1 -1
  154. package/dist/components/dialog.d.ts +1 -1
  155. package/dist/components/dialog.js +1 -1
  156. package/dist/components/drawer.js +3 -3
  157. package/dist/components/dropdown-menu.d.ts +2 -2
  158. package/dist/components/dropdown-menu.js +2 -2
  159. package/dist/components/file-input.d.ts +1 -1
  160. package/dist/components/file-input.js +1 -1
  161. package/dist/components/file-upload-container.d.ts +2 -2
  162. package/dist/components/file-upload-container.js +1 -1
  163. package/dist/components/file-upload.d.ts +2 -2
  164. package/dist/components/file-upload.js +1 -1
  165. package/dist/components/form-field.d.ts +1 -1
  166. package/dist/components/form-field.js +1 -1
  167. package/dist/components/icon-button.d.ts +1 -1
  168. package/dist/components/icon-button.js +2 -2
  169. package/dist/components/icon-slot.d.ts +2 -0
  170. package/dist/components/icon-slot.js +2 -0
  171. package/dist/components/inline-icon-button.d.ts +1 -1
  172. package/dist/components/inline-icon-button.js +1 -1
  173. package/dist/components/input.d.ts +1 -1
  174. package/dist/components/input.js +7 -7
  175. package/dist/components/link.d.ts +1 -1
  176. package/dist/components/link.js +32 -1
  177. package/dist/components/number-field.d.ts +1 -1
  178. package/dist/components/number-field.js +10 -9
  179. package/dist/components/number-range-input.d.ts +1 -1
  180. package/dist/components/number-range-input.js +1 -1
  181. package/dist/components/pagination-list.d.ts +1 -1
  182. package/dist/components/pagination-list.js +1 -1
  183. package/dist/components/pagination.d.ts +1 -1
  184. package/dist/components/pagination.js +34 -30
  185. package/dist/components/password-input.d.ts +1 -1
  186. package/dist/components/popover.d.ts +1 -1
  187. package/dist/components/popover.js +6 -5
  188. package/dist/components/progress.d.ts +1 -1
  189. package/dist/components/progress.js +1 -1
  190. package/dist/components/query-autocomplete.d.ts +2 -2
  191. package/dist/components/query-autocomplete.js +10 -5
  192. package/dist/components/query-select.d.ts +1 -1
  193. package/dist/components/query-select.js +3 -3
  194. package/dist/components/radio-group.d.ts +1 -1
  195. package/dist/components/radio-group.js +1 -1
  196. package/dist/components/select.d.ts +2 -2
  197. package/dist/components/select.js +1 -1
  198. package/dist/components/slider.d.ts +1 -1
  199. package/dist/components/slider.js +1 -1
  200. package/dist/components/spinner.d.ts +1 -1
  201. package/dist/components/spinner.js +1 -1
  202. package/dist/components/split-button.d.ts +1 -1
  203. package/dist/components/split-button.js +3 -3
  204. package/dist/components/stepper.d.ts +1 -1
  205. package/dist/components/stepper.js +1 -1
  206. package/dist/components/switch.d.ts +1 -1
  207. package/dist/components/switch.js +1 -1
  208. package/dist/components/tag.d.ts +1 -1
  209. package/dist/components/tag.js +1 -1
  210. package/dist/components/text-area.d.ts +1 -1
  211. package/dist/components/text-area.js +1 -1
  212. package/dist/components/text-button.d.ts +1 -1
  213. package/dist/components/text-button.js +1 -1
  214. package/dist/components/time-picker.d.ts +1 -1
  215. package/dist/components/time-picker.js +1 -1
  216. package/dist/components/toast.d.ts +2 -2
  217. package/dist/components/toast.js +2 -2
  218. package/dist/components/toggle-button.d.ts +1 -1
  219. package/dist/components/toggle-button.js +1 -1
  220. package/dist/components/toggle-group.d.ts +2 -2
  221. package/dist/components/toggle-group.js +1 -1
  222. package/dist/components/tooltip-ellipsis.js +1 -1
  223. package/dist/components/tooltip.d.ts +1 -1
  224. package/dist/components/tooltip.js +1 -1
  225. package/dist/components/typography.d.ts +2 -2
  226. package/dist/components/typography.js +1 -1
  227. package/dist/components/use-toast.d.ts +1 -1
  228. package/dist/components/use-toast.js +2 -2
  229. package/dist/config/app-canvas-tanstack.d.ts +23 -0
  230. package/dist/config/app-canvas-tanstack.js +62 -0
  231. package/dist/config/app-canvas.d.ts +12 -0
  232. package/dist/config/app-canvas.js +2 -0
  233. package/dist/config/confirmation.d.ts +1 -1
  234. package/dist/config/link-context.d.ts +2 -2
  235. package/dist/config/ui-config.d.ts +2 -2
  236. package/dist/config/ui-config.js +1 -1
  237. package/dist/config/ui-configurator-theme.d.ts +2 -0
  238. package/dist/config/ui-configurator-theme.js +2 -0
  239. package/dist/config/ui-configurator-vite.d.ts +10 -0
  240. package/dist/config/ui-configurator-vite.js +174 -0
  241. package/dist/config/ui-configurator.d.ts +15 -0
  242. package/dist/config/ui-configurator.js +3 -0
  243. package/dist/config/ui-overrides.d.ts +1 -1
  244. package/dist/config/ui-overrides.js +1 -1
  245. package/dist/config/ui-router.js +1 -1
  246. package/dist/configuration.context-qdjDwQJj.d.ts +938 -0
  247. package/dist/{confirmation.context-DPAKsLYl.d.ts → confirmation.context-BOeEVczb.d.ts} +1 -1
  248. package/dist/{date-picker-BYFWSbN8.d.ts → date-picker-BhIA01qs.d.ts} +1 -1
  249. package/dist/{date-range-picker-BaaXOObm.d.ts → date-range-picker-BsuZ2h_3.d.ts} +1 -1
  250. package/dist/{date-time-picker-D42cTCgx.d.ts → date-time-picker-Bi-qW6vO.d.ts} +1 -1
  251. package/dist/datePickerInput.cva-Cd7UUN61.js +14 -0
  252. package/dist/{datePickerValue.utils-CFCY-fRJ.js → datePickerValue.utils-QWR2q5Vv.js} +9 -9
  253. package/dist/{dialog.cva---xiOXMQ.js → dialog.cva-COhDZaVl.js} +4 -4
  254. package/dist/{dist-B8h0VT0E.js → dist-CAdwxJbe.js} +1 -208
  255. package/dist/{dom.utils-DjuRTR6U.js → dom.utils-D1AopHx9.js} +1 -1
  256. package/dist/dropdownMenu.cva-DvEmX0bs.js +34 -0
  257. package/dist/{dynamicInputs-wEEikYeg.d.ts → dynamicInputs-DdcsSoYu.d.ts} +102 -100
  258. package/dist/{fieldAdapter-C0lCFmf0.js → fieldAdapter-DjYls12j.js} +1 -1
  259. package/dist/{file-input-C56GXRwz.d.ts → file-input-BTYsGgr7.d.ts} +1 -1
  260. package/dist/{file-upload-Bx0X534g.d.ts → file-upload-CqGdt1Ue.d.ts} +2 -2
  261. package/dist/fileUpload.cva-ujmStxB1.js +42 -0
  262. package/dist/{fileUpload.types-DWuQKA2l.d.ts → fileUpload.types-rIGu4MgY.d.ts} +2 -2
  263. package/dist/groups-oQmSeqXn.js +18 -0
  264. package/dist/hooks/use-filters.js +1 -1
  265. package/dist/iconSlot.cva-CnpFzAOR.d.ts +21 -0
  266. package/dist/icons.d.ts +2 -1
  267. package/dist/icons.js +2 -1
  268. package/dist/index.d.ts +87 -86
  269. package/dist/index.js +57 -46
  270. package/dist/info-iUmX3uDk.js +32 -0
  271. package/dist/{input-D2kGX0hW.d.ts → input-CqNMORk8.d.ts} +1 -1
  272. package/dist/{input.cva-BhDJxc7r.d.ts → input.cva-CQPV5gW7.d.ts} +3 -2
  273. package/dist/{input.cva-BcXyC1vZ.js → input.cva-CbMTwuQU.js} +58 -39
  274. package/dist/{link.context-CDZn6oL2.d.ts → link.context-D5qyz9Rf.d.ts} +1 -1
  275. package/dist/link.cva-DMTHZiJG.js +12 -0
  276. package/dist/{number-field-Bw2GKr0s.d.ts → number-field-BcMnahI8.d.ts} +1 -1
  277. package/dist/{number-range-input-Dqe6x2dR.d.ts → number-range-input-CLfuacKv.d.ts} +1 -1
  278. package/dist/numberStatic.utils-BX50PSee.js +421 -0
  279. package/dist/{password-input-DepKyhh3.d.ts → password-input-BV1Amdc8.d.ts} +1 -1
  280. package/dist/{popover.cva-BJSkLndY.js → popover.cva-Bhud1wnp.js} +1 -1
  281. package/dist/popoverAnimation-DEZSvKP8.js +4 -0
  282. package/dist/{query-autocomplete-BSpHin_R.d.ts → query-autocomplete-CJSJeSXW.d.ts} +2 -2
  283. package/dist/{query-select-m1DCp4UF.d.ts → query-select-B-VLz1PW.d.ts} +2 -2
  284. package/dist/{queryAutocomplete.types-CrbVUmvl.d.ts → queryAutocomplete.types-D2w1_hau.d.ts} +2 -2
  285. package/dist/{radio-group-Civ3Fb70.d.ts → radio-group-DZZdQMub.d.ts} +1 -1
  286. package/dist/{radio.cva-BlOrmxzf.d.ts → radio.cva-DN9VQ3Kb.d.ts} +4 -3
  287. package/dist/rhf/autocomplete.d.ts +2 -2
  288. package/dist/rhf/autocomplete.js +1 -1
  289. package/dist/rhf/checkbox-group.d.ts +2 -2
  290. package/dist/rhf/checkbox-group.js +1 -1
  291. package/dist/rhf/checkbox.d.ts +2 -2
  292. package/dist/rhf/checkbox.js +2 -2
  293. package/dist/rhf/date-picker.d.ts +2 -2
  294. package/dist/rhf/date-picker.js +2 -2
  295. package/dist/rhf/date-range-picker.d.ts +2 -2
  296. package/dist/rhf/date-range-picker.js +2 -2
  297. package/dist/rhf/date-time-picker.d.ts +2 -2
  298. package/dist/rhf/date-time-picker.js +2 -2
  299. package/dist/rhf/file-input.d.ts +2 -2
  300. package/dist/rhf/file-input.js +2 -2
  301. package/dist/rhf/file-upload.d.ts +2 -2
  302. package/dist/rhf/file-upload.js +2 -2
  303. package/dist/rhf/input.d.ts +2 -2
  304. package/dist/rhf/input.js +1 -1
  305. package/dist/rhf/inputs.d.ts +2 -2
  306. package/dist/rhf/number-field.d.ts +2 -2
  307. package/dist/rhf/number-field.js +1 -1
  308. package/dist/rhf/number-range-input.d.ts +2 -2
  309. package/dist/rhf/number-range-input.js +2 -2
  310. package/dist/rhf/password-input.d.ts +2 -2
  311. package/dist/rhf/password-input.js +1 -1
  312. package/dist/rhf/query-autocomplete.d.ts +1 -1
  313. package/dist/rhf/query-autocomplete.js +1 -1
  314. package/dist/rhf/query-select.d.ts +1 -1
  315. package/dist/rhf/query-select.js +1 -1
  316. package/dist/rhf/radio-group.d.ts +2 -2
  317. package/dist/rhf/radio-group.js +2 -2
  318. package/dist/rhf/rich-text-editor.d.ts +2 -2
  319. package/dist/rhf/rich-text-editor.js +2 -2
  320. package/dist/rhf/select.d.ts +2 -2
  321. package/dist/rhf/select.js +2 -2
  322. package/dist/rhf/slider.d.ts +2 -2
  323. package/dist/rhf/slider.js +2 -2
  324. package/dist/rhf/switch.d.ts +2 -2
  325. package/dist/rhf/switch.js +2 -2
  326. package/dist/rhf/text-area.d.ts +2 -2
  327. package/dist/rhf/text-area.js +2 -2
  328. package/dist/rhf/time-picker.d.ts +2 -2
  329. package/dist/rhf/time-picker.js +2 -2
  330. package/dist/rhf/toggle-group.d.ts +2 -2
  331. package/dist/rhf/toggle-group.js +2 -2
  332. package/dist/{rhf-D8B7mLO1.js → rhf-t348TCCL.js} +1 -1
  333. package/dist/rhf.d.ts +87 -86
  334. package/dist/rhf.js +57 -46
  335. package/dist/{rich-text-editor-DvNEOIux.d.ts → rich-text-editor-Cp5dYHQI.d.ts} +1 -1
  336. package/dist/rich-text-editor.d.ts +1 -1
  337. package/dist/rich-text-editor.js +1 -1
  338. package/dist/{router.context-B0jTMtE0.js → router.context-B4FvsTim.js} +2 -2
  339. package/dist/{select-DY5QtwqI.d.ts → select-FjDx5oe4.d.ts} +2 -2
  340. package/dist/selectDesktop.cva-CHAMxhfO.js +69 -0
  341. package/dist/{slider-CrB-Gkcv.d.ts → slider-BVJiBswZ.d.ts} +1 -1
  342. package/dist/staticDateTimeSegments-BWea3HAt.js +1764 -0
  343. package/dist/{staticSelect.utils-Cm7MoDVG.js → staticSelect.utils-BfTCi26B.js} +34 -232
  344. package/dist/stepper.cva-CZ0Kj-s7.js +116 -0
  345. package/dist/style-merge.util-zLimKwt6.d.ts +40 -0
  346. package/dist/styles/app-canvas.css +832 -0
  347. package/dist/styles/color-utilities.css +13 -25
  348. package/dist/styles/configurator.css +3535 -0
  349. package/dist/styles/input.d.ts +1 -1
  350. package/dist/{switch-8WzXfTS8.d.ts → switch-C--iWnY8.d.ts} +1 -1
  351. package/dist/switch.cva-CWNzmdRc.d.ts +16 -0
  352. package/dist/table.cva-D5oQ-QvA.js +101 -0
  353. package/dist/tanstack/autocomplete.d.ts +1 -1
  354. package/dist/tanstack/checkbox-group.d.ts +1 -1
  355. package/dist/tanstack/checkbox.d.ts +1 -1
  356. package/dist/tanstack/checkbox.js +1 -1
  357. package/dist/tanstack/date-picker.d.ts +1 -1
  358. package/dist/tanstack/date-picker.js +1 -1
  359. package/dist/tanstack/date-range-picker.d.ts +1 -1
  360. package/dist/tanstack/date-range-picker.js +1 -1
  361. package/dist/tanstack/date-time-picker.d.ts +1 -1
  362. package/dist/tanstack/date-time-picker.js +1 -1
  363. package/dist/tanstack/file-input.d.ts +1 -1
  364. package/dist/tanstack/file-input.js +1 -1
  365. package/dist/tanstack/file-upload.d.ts +2 -2
  366. package/dist/tanstack/file-upload.js +1 -1
  367. package/dist/tanstack/form.d.ts +1 -1
  368. package/dist/tanstack/form.js +1 -1
  369. package/dist/tanstack/input.d.ts +1 -1
  370. package/dist/tanstack/inputs.d.ts +3 -3
  371. package/dist/tanstack/inputs.js +1 -1
  372. package/dist/tanstack/number-field.d.ts +1 -1
  373. package/dist/tanstack/number-range-input.d.ts +1 -1
  374. package/dist/tanstack/number-range-input.js +1 -1
  375. package/dist/tanstack/password-input.d.ts +1 -1
  376. package/dist/tanstack/query-select.d.ts +1 -1
  377. package/dist/tanstack/radio-group.d.ts +1 -1
  378. package/dist/tanstack/radio-group.js +1 -1
  379. package/dist/tanstack/rich-text-editor.d.ts +1 -1
  380. package/dist/tanstack/rich-text-editor.js +1 -1
  381. package/dist/tanstack/select.d.ts +1 -1
  382. package/dist/tanstack/select.js +1 -1
  383. package/dist/tanstack/slider.d.ts +1 -1
  384. package/dist/tanstack/slider.js +1 -1
  385. package/dist/tanstack/switch.d.ts +1 -1
  386. package/dist/tanstack/switch.js +1 -1
  387. package/dist/tanstack/table.d.ts +1 -1
  388. package/dist/tanstack/table.js +2 -1
  389. package/dist/tanstack/text-area.d.ts +1 -1
  390. package/dist/tanstack/text-area.js +1 -1
  391. package/dist/tanstack/time-picker.d.ts +1 -1
  392. package/dist/tanstack/time-picker.js +1 -1
  393. package/dist/tanstack/toggle-group.d.ts +2 -2
  394. package/dist/tanstack/toggle-group.js +1 -1
  395. package/dist/tanstack.d.ts +71 -70
  396. package/dist/tanstack.js +68 -55
  397. package/dist/{text-area-CqnKRWKq.d.ts → text-area-DhSVRB6X.d.ts} +1 -1
  398. package/dist/theme-model-DtTsIxou.js +408 -0
  399. package/dist/theme-model-T1zIdBg8.d.ts +12 -0
  400. package/dist/{time-picker-Cz1GIzpF.d.ts → time-picker-DhnDKh97.d.ts} +1 -1
  401. package/dist/{toast.cva-Cj6o2Rmu.d.ts → toast.cva-By5lvAfr.d.ts} +3 -2
  402. package/dist/toast.cva-C_L_RffH.js +163 -0
  403. package/dist/{toast.runtime-CIKvmkjo.js → toast.runtime-cxex9e4E.js} +2 -1
  404. package/dist/{toggle-group-CPkKHm1t.d.ts → toggle-group-C1nMDOwz.d.ts} +1 -1
  405. package/dist/toggleGroup.cva-MbpaEBg1.js +35 -0
  406. package/dist/{toggleGroup.types-DD6uRI5G.d.ts → toggleGroup.types-Bp43zbSQ.d.ts} +2 -1
  407. package/dist/tooltip.cva-BIzlOXHH.js +48 -0
  408. package/dist/{tooltipWrapper.cva-CUu8pI-a.js → tooltipWrapper.cva-BBQ4ic3D.js} +1 -1
  409. package/dist/{typography.cva-jtp6WWUH.d.ts → typography.cva-D1JOEYl-.d.ts} +2 -1
  410. package/dist/{typography.cva-CJZZSGXW.js → typography.cva-iD15k56p.js} +1 -1
  411. package/dist/{uiConfig.context-D2eUIPHn.js → uiConfig.context-BS3r_kTS.js} +1 -1
  412. package/dist/{uiConfig.context-aoarCLYX.d.ts → uiConfig.context-BqKWd_MO.d.ts} +8 -8
  413. package/dist/{uiOverrides.context-Bfm2n-n8.js → uiOverrides.context-BTCH9y5a.js} +2 -2
  414. package/dist/{uiOverrides.context-C3xb4Ttq.d.ts → uiOverrides.context-DEp139He.d.ts} +11 -44
  415. package/dist/underline-66hmELxa.js +81 -0
  416. package/dist/upload-CXU83BJ4.js +30 -0
  417. package/dist/{useBreakpoint-BOA-MyoT.js → useBreakpoint-DQoMN-BG.js} +1 -1
  418. package/dist/useControlledState-CzXkZCX8.js +30 -0
  419. package/dist/{useFieldAccessibility-D2_Qm26-.js → useFieldAccessibility-B-bjtrNw.js} +15 -8
  420. package/dist/{useFilters-kkEUFKmQ.js → useFilters-XNH27Md2.js} +1 -1
  421. package/dist/{useFormAutosave-BYFn3LH8.js → useFormAutosave-pmh35PXp.js} +2 -2
  422. package/dist/{useStaticInputHandoff-DB9PgioW.js → useStaticInputHandoff-B7DEm75m.js} +14 -11
  423. package/dist/useTableColumnConfig-6zn3zKl3.js +892 -0
  424. package/dist/{useTableNav-D9mICzNW.d.ts → useTableNav-Ckj5PBRk.d.ts} +3 -2
  425. package/dist/{useToast-DMSm59Y6.d.ts → useToast-yreVCUer.d.ts} +1 -1
  426. package/package.json +53 -6
  427. package/rulesync.jsonc +11 -0
  428. package/scripts/generate-rules.mjs +34 -0
  429. package/src/configurator/README.md +77 -0
  430. package/dist/Button-sn52l1Yv.js +0 -506
  431. package/dist/FocusScope-CO9oJ1sc.js +0 -343
  432. package/dist/FormFieldHeaderTooltip-Dl24v4_j.js +0 -45
  433. package/dist/Link-Btxj2gzg.js +0 -42
  434. package/dist/PillButton-DASBXLFB.d.ts +0 -15
  435. package/dist/Tag-Cch_68QO.d.ts +0 -43
  436. package/dist/chain-DIXr2VAT.js +0 -10
  437. package/dist/components/pill-button.d.ts +0 -2
  438. package/dist/focusSafely-DCGrr2bb.js +0 -447
  439. package/dist/getScrollParent-kSR7EtoT.js +0 -47
  440. package/dist/numberStatic.utils-BMgRzyd3.js +0 -902
  441. package/dist/openLink-CQhMhfzO.js +0 -121
  442. package/dist/pillButton.cva-BEWuu0qm.d.ts +0 -34
  443. package/dist/pillButton.cva-DlP5tOT5.js +0 -197
  444. package/dist/platform-BXNIIAfU.js +0 -42
  445. package/dist/staticDateTimeSegments-DR8bJw-F.js +0 -3605
  446. package/dist/switch.cva-8T0fw31t.d.ts +0 -15
  447. package/dist/useControlledState-DQxX6LMN.js +0 -189
  448. package/dist/useFocusable-Bd0UsrQ7.js +0 -63
  449. package/dist/useFormValidationState-D3z-gafz.js +0 -1341
  450. package/dist/useLayoutEffect-B2-1tbPJ.js +0 -83
  451. package/dist/useSyncRef-RGMv0rXK.js +0 -338
  452. package/dist/useTableColumnConfig-CcJxu14U.js +0 -1625
@@ -0,0 +1,2497 @@
1
+ import { t as createLucideIcon } from "./createLucideIcon-LcezOE4z.js";
2
+ import { a as getBoxHighlights, d as Pin, f as Moon, l as useUIConfiguration, o as HighlightOverlay, r as inspectElement, s as InspectorDetails, t as UIConfigurationModal, u as Sun } from "./UIConfigurator-C_2kgJtm.js";
3
+ import { t as ChevronDown } from "./chevron-down-B4Pr8bD3.js";
4
+ import { t as ChevronRight } from "./chevron-right-3nKJR5Bb.js";
5
+ import { i as Search } from "./selectDesktop.cva-CHAMxhfO.js";
6
+ import { t as Upload } from "./upload-CXU83BJ4.js";
7
+ import { t as X } from "./x-B6vfz8Ps.js";
8
+ import { c as isEditableToken } from "./theme-model-DtTsIxou.js";
9
+ import { t as componentArtboards } from "./groups-oQmSeqXn.js";
10
+ import { Suspense, lazy, memo, useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
11
+ import { c } from "react/compiler-runtime";
12
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/code-xml.mjs
14
+ /**
15
+ * @license lucide-react v1.43.0 - ISC
16
+ *
17
+ * This source code is licensed under the ISC license.
18
+ * See the LICENSE file in the root directory of this source tree.
19
+ */
20
+ const __iconData$9 = {
21
+ name: "code-xml",
22
+ size: 24,
23
+ node: [
24
+ ["path", {
25
+ d: "m18 16 4-4-4-4",
26
+ key: "1inbqp"
27
+ }],
28
+ ["path", {
29
+ d: "m6 8-4 4 4 4",
30
+ key: "15zrgr"
31
+ }],
32
+ ["path", {
33
+ d: "m14.5 4-5 16",
34
+ key: "e7oirm"
35
+ }]
36
+ ],
37
+ aliases: ["code-2"]
38
+ };
39
+ __iconData$9.node;
40
+ const CodeXml = createLucideIcon(__iconData$9);
41
+ //#endregion
42
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/download.mjs
43
+ /**
44
+ * @license lucide-react v1.43.0 - ISC
45
+ *
46
+ * This source code is licensed under the ISC license.
47
+ * See the LICENSE file in the root directory of this source tree.
48
+ */
49
+ const __iconData$8 = {
50
+ name: "download",
51
+ size: 24,
52
+ node: [
53
+ ["path", {
54
+ d: "M12 15V3",
55
+ key: "m9g1x1"
56
+ }],
57
+ ["path", {
58
+ d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",
59
+ key: "ih7n3h"
60
+ }],
61
+ ["path", {
62
+ d: "m7 10 5 5 5-5",
63
+ key: "brsn70"
64
+ }]
65
+ ]
66
+ };
67
+ __iconData$8.node;
68
+ const Download = createLucideIcon(__iconData$8);
69
+ //#endregion
70
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/frame.mjs
71
+ /**
72
+ * @license lucide-react v1.43.0 - ISC
73
+ *
74
+ * This source code is licensed under the ISC license.
75
+ * See the LICENSE file in the root directory of this source tree.
76
+ */
77
+ const __iconData$7 = {
78
+ name: "frame",
79
+ size: 24,
80
+ node: [
81
+ ["line", {
82
+ x1: "22",
83
+ x2: "2",
84
+ y1: "6",
85
+ y2: "6",
86
+ key: "15w7dq"
87
+ }],
88
+ ["line", {
89
+ x1: "22",
90
+ x2: "2",
91
+ y1: "18",
92
+ y2: "18",
93
+ key: "1ip48p"
94
+ }],
95
+ ["line", {
96
+ x1: "6",
97
+ x2: "6",
98
+ y1: "2",
99
+ y2: "22",
100
+ key: "a2lnyx"
101
+ }],
102
+ ["line", {
103
+ x1: "18",
104
+ x2: "18",
105
+ y1: "2",
106
+ y2: "22",
107
+ key: "8vb6jd"
108
+ }]
109
+ ]
110
+ };
111
+ __iconData$7.node;
112
+ const Frame = createLucideIcon(__iconData$7);
113
+ //#endregion
114
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/hand.mjs
115
+ /**
116
+ * @license lucide-react v1.43.0 - ISC
117
+ *
118
+ * This source code is licensed under the ISC license.
119
+ * See the LICENSE file in the root directory of this source tree.
120
+ */
121
+ const __iconData$6 = {
122
+ name: "hand",
123
+ size: 24,
124
+ node: [
125
+ ["path", {
126
+ d: "M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2",
127
+ key: "1fvzgz"
128
+ }],
129
+ ["path", {
130
+ d: "M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2",
131
+ key: "1kc0my"
132
+ }],
133
+ ["path", {
134
+ d: "M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8",
135
+ key: "10h0bg"
136
+ }],
137
+ ["path", {
138
+ d: "M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15",
139
+ key: "1s1gnw"
140
+ }]
141
+ ]
142
+ };
143
+ __iconData$6.node;
144
+ const Hand = createLucideIcon(__iconData$6);
145
+ //#endregion
146
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/monitor.mjs
147
+ /**
148
+ * @license lucide-react v1.43.0 - ISC
149
+ *
150
+ * This source code is licensed under the ISC license.
151
+ * See the LICENSE file in the root directory of this source tree.
152
+ */
153
+ const __iconData$5 = {
154
+ name: "monitor",
155
+ size: 24,
156
+ node: [
157
+ ["rect", {
158
+ width: "20",
159
+ height: "14",
160
+ x: "2",
161
+ y: "3",
162
+ rx: "2",
163
+ key: "48i651"
164
+ }],
165
+ ["line", {
166
+ x1: "8",
167
+ x2: "16",
168
+ y1: "21",
169
+ y2: "21",
170
+ key: "1svkeh"
171
+ }],
172
+ ["line", {
173
+ x1: "12",
174
+ x2: "12",
175
+ y1: "17",
176
+ y2: "21",
177
+ key: "vw1qmm"
178
+ }]
179
+ ]
180
+ };
181
+ __iconData$5.node;
182
+ const Monitor = createLucideIcon(__iconData$5);
183
+ //#endregion
184
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/mouse-pointer-2.mjs
185
+ /**
186
+ * @license lucide-react v1.43.0 - ISC
187
+ *
188
+ * This source code is licensed under the ISC license.
189
+ * See the LICENSE file in the root directory of this source tree.
190
+ */
191
+ const __iconData$4 = {
192
+ name: "mouse-pointer-2",
193
+ size: 24,
194
+ node: [["path", {
195
+ d: "M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z",
196
+ key: "edeuup"
197
+ }]]
198
+ };
199
+ __iconData$4.node;
200
+ const MousePointer2 = createLucideIcon(__iconData$4);
201
+ //#endregion
202
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/panel-left.mjs
203
+ /**
204
+ * @license lucide-react v1.43.0 - ISC
205
+ *
206
+ * This source code is licensed under the ISC license.
207
+ * See the LICENSE file in the root directory of this source tree.
208
+ */
209
+ const __iconData$3 = {
210
+ name: "panel-left",
211
+ size: 24,
212
+ node: [["rect", {
213
+ width: "18",
214
+ height: "18",
215
+ x: "3",
216
+ y: "3",
217
+ rx: "2",
218
+ key: "afitv7"
219
+ }], ["path", {
220
+ d: "M9 3v18",
221
+ key: "fh3hqa"
222
+ }]],
223
+ aliases: ["sidebar"]
224
+ };
225
+ __iconData$3.node;
226
+ const PanelLeft = createLucideIcon(__iconData$3);
227
+ //#endregion
228
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/panels-top-left.mjs
229
+ /**
230
+ * @license lucide-react v1.43.0 - ISC
231
+ *
232
+ * This source code is licensed under the ISC license.
233
+ * See the LICENSE file in the root directory of this source tree.
234
+ */
235
+ const __iconData$2 = {
236
+ name: "panels-top-left",
237
+ size: 24,
238
+ node: [
239
+ ["rect", {
240
+ width: "18",
241
+ height: "18",
242
+ x: "3",
243
+ y: "3",
244
+ rx: "2",
245
+ key: "afitv7"
246
+ }],
247
+ ["path", {
248
+ d: "M3 9h18",
249
+ key: "1pudct"
250
+ }],
251
+ ["path", {
252
+ d: "M9 21V9",
253
+ key: "1oto5p"
254
+ }]
255
+ ],
256
+ aliases: ["layout"]
257
+ };
258
+ __iconData$2.node;
259
+ const PanelsTopLeft = createLucideIcon(__iconData$2);
260
+ //#endregion
261
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/scan-line.mjs
262
+ /**
263
+ * @license lucide-react v1.43.0 - ISC
264
+ *
265
+ * This source code is licensed under the ISC license.
266
+ * See the LICENSE file in the root directory of this source tree.
267
+ */
268
+ const __iconData$1 = {
269
+ name: "scan-line",
270
+ size: 24,
271
+ node: [
272
+ ["path", {
273
+ d: "M3 7V5a2 2 0 0 1 2-2h2",
274
+ key: "aa7l1z"
275
+ }],
276
+ ["path", {
277
+ d: "M17 3h2a2 2 0 0 1 2 2v2",
278
+ key: "4qcy5o"
279
+ }],
280
+ ["path", {
281
+ d: "M21 17v2a2 2 0 0 1-2 2h-2",
282
+ key: "6vwrx8"
283
+ }],
284
+ ["path", {
285
+ d: "M7 21H5a2 2 0 0 1-2-2v-2",
286
+ key: "ioqczr"
287
+ }],
288
+ ["path", {
289
+ d: "M7 12h10",
290
+ key: "b7w52i"
291
+ }]
292
+ ]
293
+ };
294
+ __iconData$1.node;
295
+ const ScanLine = createLucideIcon(__iconData$1);
296
+ //#endregion
297
+ //#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/settings-2.mjs
298
+ /**
299
+ * @license lucide-react v1.43.0 - ISC
300
+ *
301
+ * This source code is licensed under the ISC license.
302
+ * See the LICENSE file in the root directory of this source tree.
303
+ */
304
+ const __iconData = {
305
+ name: "settings-2",
306
+ size: 24,
307
+ node: [
308
+ ["path", {
309
+ d: "M14 17H5",
310
+ key: "gfn3mx"
311
+ }],
312
+ ["path", {
313
+ d: "M19 7h-9",
314
+ key: "6i9tg"
315
+ }],
316
+ ["circle", {
317
+ cx: "17",
318
+ cy: "17",
319
+ r: "3",
320
+ key: "18b49y"
321
+ }],
322
+ ["circle", {
323
+ cx: "7",
324
+ cy: "7",
325
+ r: "3",
326
+ key: "dfmy0x"
327
+ }]
328
+ ]
329
+ };
330
+ __iconData.node;
331
+ const Settings2 = createLucideIcon(__iconData);
332
+ //#endregion
333
+ //#region src/app-canvas/useFrameStartup.ts
334
+ /** Bound concurrent bootstraps, without unloading any admitted page. */
335
+ function useFrameStartup(keys, concurrency = 2) {
336
+ const [admitted, setAdmitted] = useState(() => /* @__PURE__ */ new Set());
337
+ const state = useRef({
338
+ keys: [],
339
+ admitted: /* @__PURE__ */ new Set(),
340
+ pending: /* @__PURE__ */ new Map()
341
+ });
342
+ const pumpRef = useRef(() => {});
343
+ const pump = useCallback(() => {
344
+ const current = state.current;
345
+ let changed = false;
346
+ for (const key of current.keys) {
347
+ if (current.pending.size >= concurrency) break;
348
+ if (current.admitted.has(key)) continue;
349
+ current.admitted.add(key);
350
+ changed = true;
351
+ current.pending.set(key, setTimeout(() => {
352
+ current.pending.delete(key);
353
+ pumpRef.current();
354
+ }, 3e4));
355
+ }
356
+ if (changed) setAdmitted(new Set(current.admitted));
357
+ }, [concurrency]);
358
+ pumpRef.current = pump;
359
+ const signature = JSON.stringify(keys);
360
+ useEffect(() => {
361
+ const next = JSON.parse(signature);
362
+ const wanted = new Set(next);
363
+ const current_0 = state.current;
364
+ current_0.keys = next;
365
+ let changed_0 = false;
366
+ for (const key_0 of current_0.admitted) {
367
+ if (wanted.has(key_0)) continue;
368
+ current_0.admitted.delete(key_0);
369
+ const timer = current_0.pending.get(key_0);
370
+ if (timer !== void 0) clearTimeout(timer);
371
+ current_0.pending.delete(key_0);
372
+ changed_0 = true;
373
+ }
374
+ if (changed_0) setAdmitted(new Set(current_0.admitted));
375
+ pump();
376
+ }, [signature, pump]);
377
+ useEffect(() => () => {
378
+ for (const timer_0 of state.current.pending.values()) clearTimeout(timer_0);
379
+ state.current.pending.clear();
380
+ state.current.admitted.clear();
381
+ }, []);
382
+ return {
383
+ admitted,
384
+ complete: useCallback((key_1) => {
385
+ if (!key_1) return;
386
+ const timer_1 = state.current.pending.get(key_1);
387
+ if (timer_1 === void 0) return;
388
+ clearTimeout(timer_1);
389
+ state.current.pending.delete(key_1);
390
+ pumpRef.current();
391
+ }, [])
392
+ };
393
+ }
394
+ //#endregion
395
+ //#region src/app-canvas/PageLayers.tsx
396
+ const excluded = /* @__PURE__ */ new Set([
397
+ "SCRIPT",
398
+ "STYLE",
399
+ "LINK",
400
+ "META",
401
+ "NOSCRIPT",
402
+ "TEMPLATE"
403
+ ]);
404
+ function childrenOf(element) {
405
+ return Array.from(element.children).filter((child) => child.namespaceURI === "http://www.w3.org/1999/xhtml" && !excluded.has(child.tagName) && !child.hidden && child.getClientRects().length > 0);
406
+ }
407
+ function labelOf(element) {
408
+ return (element.getAttribute("aria-label") || element.getAttribute("alt") || (!element.children.length ? element.textContent?.trim().replace(/\s+/g, " ") : ""))?.slice(0, 48) || (element.id ? `#${element.id}` : "");
409
+ }
410
+ /** Only expanded branches are read and rendered; large pages do not create a second full DOM tree. */
411
+ function PageLayers({ frame, title, selected, onSelect }) {
412
+ const [root, setRoot] = useState(null);
413
+ const [, refresh] = useReducer((value) => value + 1, 0);
414
+ const expanded = useRef(/* @__PURE__ */ new WeakSet());
415
+ const collapsed = useRef(/* @__PURE__ */ new WeakSet());
416
+ const ids = useRef(/* @__PURE__ */ new WeakMap());
417
+ const nextId = useRef(0);
418
+ const [limit, setLimit] = useState(300);
419
+ useEffect(() => {
420
+ if (!frame) return;
421
+ let observer;
422
+ let scheduled = null;
423
+ const update = () => {
424
+ scheduled = null;
425
+ refresh();
426
+ };
427
+ const attach = () => {
428
+ observer?.disconnect();
429
+ try {
430
+ const doc = frame.contentDocument;
431
+ const element = doc?.querySelector("#storybook-root, #app, #root") ?? doc?.body ?? null;
432
+ setRoot(element);
433
+ if (element) {
434
+ observer = new MutationObserver(() => {
435
+ if (scheduled === null) scheduled = requestAnimationFrame(update);
436
+ });
437
+ observer.observe(element, {
438
+ childList: true,
439
+ subtree: true,
440
+ attributes: true,
441
+ characterData: true
442
+ });
443
+ }
444
+ } catch {
445
+ setRoot(null);
446
+ }
447
+ };
448
+ attach();
449
+ frame.addEventListener("load", attach);
450
+ return () => {
451
+ observer?.disconnect();
452
+ frame.removeEventListener("load", attach);
453
+ if (scheduled !== null) cancelAnimationFrame(scheduled);
454
+ };
455
+ }, [frame]);
456
+ useEffect(() => {
457
+ if (!root || !selected || !root.contains(selected)) return;
458
+ for (let parent = selected.parentElement; parent && parent !== root; parent = parent.parentElement) {
459
+ expanded.current.add(parent);
460
+ collapsed.current.delete(parent);
461
+ }
462
+ refresh();
463
+ }, [root, selected]);
464
+ const toggle = (element_0, open) => {
465
+ if (open) {
466
+ expanded.current.delete(element_0);
467
+ collapsed.current.add(element_0);
468
+ } else {
469
+ expanded.current.add(element_0);
470
+ collapsed.current.delete(element_0);
471
+ }
472
+ refresh();
473
+ };
474
+ let count = 0;
475
+ let truncated = false;
476
+ const render = (element_1, depth) => {
477
+ if (++count > limit || depth > 60) {
478
+ truncated = true;
479
+ return null;
480
+ }
481
+ if (!ids.current.has(element_1)) ids.current.set(element_1, ++nextId.current);
482
+ const children = childrenOf(element_1);
483
+ const open_0 = !collapsed.current.has(element_1) && (depth < 2 || expanded.current.has(element_1));
484
+ const label = labelOf(element_1);
485
+ return /* @__PURE__ */ jsxs("div", {
486
+ role: "treeitem",
487
+ "aria-label": `${element_1.localName}${label ? ` ${label}` : ""}`,
488
+ "aria-level": depth + 1,
489
+ "aria-selected": element_1 === selected,
490
+ "aria-expanded": children.length ? open_0 : void 0,
491
+ children: [/* @__PURE__ */ jsxs("div", {
492
+ className: "povio-canvas-layer-row",
493
+ style: { paddingLeft: 8 + depth * 12 },
494
+ children: [children.length ? /* @__PURE__ */ jsx("button", {
495
+ className: "povio-canvas-layer-toggle",
496
+ "aria-label": `${open_0 ? "Collapse" : "Expand"} ${element_1.localName}${label ? ` ${label}` : ""}`,
497
+ onClick: () => toggle(element_1, open_0),
498
+ children: open_0 ? /* @__PURE__ */ jsx(ChevronDown, { size: 12 }) : /* @__PURE__ */ jsx(ChevronRight, { size: 12 })
499
+ }) : /* @__PURE__ */ jsx("span", { className: "povio-canvas-layer-spacer" }), /* @__PURE__ */ jsxs("button", {
500
+ className: "povio-canvas-layer-select",
501
+ title: `${element_1.localName}${label ? ` · ${label}` : ""}`,
502
+ onClick: () => onSelect(element_1),
503
+ onKeyDown: (event) => {
504
+ if (event.key === "ArrowRight" && children.length && !open_0) {
505
+ event.preventDefault();
506
+ toggle(element_1, false);
507
+ }
508
+ if (event.key === "ArrowLeft" && open_0) {
509
+ event.preventDefault();
510
+ toggle(element_1, true);
511
+ }
512
+ },
513
+ children: [/* @__PURE__ */ jsx("code", { children: element_1.localName }), label && /* @__PURE__ */ jsx("span", { children: label })]
514
+ })]
515
+ }), open_0 && !!children.length && /* @__PURE__ */ jsx("div", {
516
+ role: "group",
517
+ children: children.map((child) => render(child, depth + 1))
518
+ })]
519
+ }, ids.current.get(element_1));
520
+ };
521
+ const content = root ? childrenOf(root).map((element_2) => render(element_2, 0)) : null;
522
+ return /* @__PURE__ */ jsxs("section", {
523
+ className: "povio-canvas-layers",
524
+ "aria-label": `Layers for ${title}`,
525
+ children: [
526
+ /* @__PURE__ */ jsxs("header", { children: [
527
+ /* @__PURE__ */ jsx(CodeXml, { size: 14 }),
528
+ /* @__PURE__ */ jsx("strong", { children: "Layers" }),
529
+ /* @__PURE__ */ jsx("span", { children: title })
530
+ ] }),
531
+ /* @__PURE__ */ jsx("div", {
532
+ role: "tree",
533
+ "aria-label": "HTML layers",
534
+ children: content
535
+ }),
536
+ !root && /* @__PURE__ */ jsx("p", { children: "Waiting for the page…" }),
537
+ truncated && /* @__PURE__ */ jsx("button", {
538
+ className: "povio-canvas-more-layers",
539
+ onClick: () => setLimit((value_0) => value_0 + 300),
540
+ children: "Show more layers"
541
+ })
542
+ ]
543
+ });
544
+ }
545
+ //#endregion
546
+ //#region src/app-canvas/CanvasInspector.tsx
547
+ /** Inspect the live iframe DOM using its own, unscaled viewport coordinates. */
548
+ function useCanvasInspector(enabled, generation, isKnown) {
549
+ const [selection, setSelection] = useState(null);
550
+ const [measurement, setMeasurement] = useState(null);
551
+ const [pinned, setPinned] = useState(false);
552
+ const [highlightKey, setHighlightKey] = useState(null);
553
+ const hoverFrame = useRef(null);
554
+ const pending = useRef(null);
555
+ const clear = useCallback(() => {
556
+ if (hoverFrame.current !== null) cancelAnimationFrame(hoverFrame.current);
557
+ hoverFrame.current = null;
558
+ pending.current = null;
559
+ setSelection(null);
560
+ setMeasurement(null);
561
+ setPinned(false);
562
+ setHighlightKey(null);
563
+ }, []);
564
+ useEffect(() => {
565
+ if (!enabled) clear();
566
+ }, [enabled, clear]);
567
+ useEffect(() => {
568
+ clear();
569
+ }, [generation, clear]);
570
+ useEffect(() => () => {
571
+ if (hoverFrame.current !== null) cancelAnimationFrame(hoverFrame.current);
572
+ }, []);
573
+ const pick = useCallback((pageId, frame, clientX, clientY, pin) => {
574
+ if (!enabled || pinned && !pin) return;
575
+ const bounds = frame.getBoundingClientRect();
576
+ if (!bounds.width || !bounds.height) return;
577
+ try {
578
+ const doc = frame.contentDocument;
579
+ if (!doc) return;
580
+ const x = (clientX - bounds.left) * frame.clientWidth / bounds.width;
581
+ const y = (clientY - bounds.top) * frame.clientHeight / bounds.height;
582
+ const hit = doc.elementFromPoint(x, y);
583
+ const element = hit?.closest("button,input,textarea,select,a,label,[role],h1,h2,h3,h4,h5,h6,p") ?? hit;
584
+ if (!element || element === doc.documentElement || element === doc.body || element.namespaceURI !== "http://www.w3.org/1999/xhtml") return;
585
+ const target = element;
586
+ setSelection((current) => current?.element === target ? current : {
587
+ pageId,
588
+ element: target
589
+ });
590
+ setHighlightKey(null);
591
+ if (pin) setPinned((current_0) => !(current_0 && selection?.element === target));
592
+ } catch {
593
+ clear();
594
+ }
595
+ }, [
596
+ enabled,
597
+ pinned,
598
+ selection,
599
+ clear
600
+ ]);
601
+ const hover = useCallback((pageId_0, frame_0, x_0, y_0) => {
602
+ if (!enabled || pinned) return;
603
+ pending.current = () => pick(pageId_0, frame_0, x_0, y_0, false);
604
+ if (hoverFrame.current !== null) return;
605
+ hoverFrame.current = requestAnimationFrame(() => {
606
+ hoverFrame.current = null;
607
+ pending.current?.();
608
+ pending.current = null;
609
+ });
610
+ }, [
611
+ enabled,
612
+ pinned,
613
+ pick
614
+ ]);
615
+ const select = useCallback((pageId_1, frame_1, x_1, y_1) => {
616
+ if (hoverFrame.current !== null) cancelAnimationFrame(hoverFrame.current);
617
+ hoverFrame.current = null;
618
+ pending.current = null;
619
+ pick(pageId_1, frame_1, x_1, y_1, true);
620
+ }, [pick]);
621
+ useEffect(() => {
622
+ if (!enabled || !selection) return;
623
+ const { element: element_0 } = selection;
624
+ const doc_0 = element_0.ownerDocument;
625
+ const owner = doc_0.defaultView;
626
+ if (!owner) return;
627
+ let scheduled = null;
628
+ const measure = () => {
629
+ scheduled = null;
630
+ if (!element_0.isConnected) {
631
+ clear();
632
+ return;
633
+ }
634
+ const rect = element_0.getBoundingClientRect();
635
+ const snapshot = inspectElement(element_0, isKnown);
636
+ const details = highlightKey ? getBoxHighlights(element_0, highlightKey) : null;
637
+ const spacing = highlightKey ? [] : [
638
+ "padding.top",
639
+ "padding.right",
640
+ "padding.bottom",
641
+ "padding.left",
642
+ "margin.top",
643
+ "margin.right",
644
+ "margin.bottom",
645
+ "margin.left",
646
+ "gap.row",
647
+ "gap.column"
648
+ ].flatMap((key) => {
649
+ const [kind, side] = key.split(".");
650
+ const raw = kind === "padding" ? snapshot.box.padding[side] : kind === "margin" ? snapshot.box.margin[side] : snapshot.box.gap[side];
651
+ if (!(Math.abs(Number.parseFloat(raw)) > 0)) return [];
652
+ const details_0 = getBoxHighlights(element_0, key);
653
+ const regions = details_0.regions.filter((region) => region.width > 0 && region.height > 0);
654
+ return regions.length ? [{
655
+ key,
656
+ label: details_0.label,
657
+ regions
658
+ }] : [];
659
+ });
660
+ if (!highlightKey) {
661
+ const seen = new Set(spacing.flatMap((item) => item.regions.map((region_0) => `${item.key}:${region_0.left}:${region_0.top}:${region_0.width}:${region_0.height}`)));
662
+ for (const child of Array.from(element_0.children).slice(0, 80)) {
663
+ if (child.namespaceURI !== "http://www.w3.org/1999/xhtml" || !child.getClientRects().length) continue;
664
+ const style = owner.getComputedStyle(child);
665
+ if (style.display === "none" || style.visibility === "hidden" || /^(absolute|fixed)$/.test(style.position)) continue;
666
+ for (const side_0 of [
667
+ "top",
668
+ "right",
669
+ "bottom",
670
+ "left"
671
+ ]) {
672
+ if (!(Math.abs(Number.parseFloat(style.getPropertyValue(`margin-${side_0}`))) > 0)) continue;
673
+ const key_0 = `margin.${side_0}`;
674
+ const details_1 = getBoxHighlights(child, key_0);
675
+ const regions_0 = details_1.regions.filter((region_1) => {
676
+ const id = `${key_0}:${region_1.left}:${region_1.top}:${region_1.width}:${region_1.height}`;
677
+ if (seen.has(id)) return false;
678
+ seen.add(id);
679
+ return region_1.width > 0 && region_1.height > 0;
680
+ });
681
+ if (regions_0.length) spacing.push({
682
+ key: key_0,
683
+ label: details_1.label,
684
+ regions: regions_0
685
+ });
686
+ }
687
+ }
688
+ }
689
+ const next = {
690
+ snapshot,
691
+ spacing,
692
+ outline: {
693
+ left: rect.left,
694
+ top: rect.top,
695
+ width: rect.width,
696
+ height: rect.height
697
+ },
698
+ highlight: details && highlightKey ? {
699
+ key: highlightKey,
700
+ ...details
701
+ } : null
702
+ };
703
+ setMeasurement((current_1) => JSON.stringify(current_1) === JSON.stringify(next) ? current_1 : next);
704
+ };
705
+ const schedule = () => {
706
+ if (scheduled === null) scheduled = requestAnimationFrame(measure);
707
+ };
708
+ const mutations = new MutationObserver(schedule);
709
+ mutations.observe(doc_0.documentElement, {
710
+ subtree: true,
711
+ childList: true,
712
+ attributes: true,
713
+ characterData: true
714
+ });
715
+ const resize = new ResizeObserver(schedule);
716
+ resize.observe(element_0);
717
+ owner.addEventListener("scroll", schedule, true);
718
+ measure();
719
+ return () => {
720
+ mutations.disconnect();
721
+ resize.disconnect();
722
+ owner.removeEventListener("scroll", schedule, true);
723
+ if (scheduled !== null) cancelAnimationFrame(scheduled);
724
+ };
725
+ }, [
726
+ enabled,
727
+ selection,
728
+ highlightKey,
729
+ clear,
730
+ isKnown
731
+ ]);
732
+ return {
733
+ selection,
734
+ selectElement: (pageId_2, element_1) => {
735
+ setSelection({
736
+ pageId: pageId_2,
737
+ element: element_1
738
+ });
739
+ setPinned(true);
740
+ setHighlightKey(null);
741
+ },
742
+ measurement,
743
+ pinned,
744
+ hover,
745
+ select,
746
+ clear,
747
+ highlight: setHighlightKey,
748
+ togglePin: () => setPinned((value) => !value)
749
+ };
750
+ }
751
+ function CanvasInspectorPanel(t0) {
752
+ const $ = c(22);
753
+ const { inspector, onClose, onSelectToken } = t0;
754
+ let t1;
755
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
756
+ t1 = /* @__PURE__ */ jsx("strong", { children: "Inspector view" });
757
+ $[0] = t1;
758
+ } else t1 = $[0];
759
+ const t2 = !inspector.selection;
760
+ let t3;
761
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
762
+ t3 = /* @__PURE__ */ jsx(Pin, { size: 14 });
763
+ $[1] = t3;
764
+ } else t3 = $[1];
765
+ let t4;
766
+ if ($[2] !== inspector.pinned || $[3] !== inspector.togglePin || $[4] !== t2) {
767
+ t4 = /* @__PURE__ */ jsx("button", {
768
+ "aria-label": "Pin inspected element",
769
+ "aria-pressed": inspector.pinned,
770
+ disabled: t2,
771
+ onClick: inspector.togglePin,
772
+ children: t3
773
+ });
774
+ $[2] = inspector.pinned;
775
+ $[3] = inspector.togglePin;
776
+ $[4] = t2;
777
+ $[5] = t4;
778
+ } else t4 = $[5];
779
+ let t5;
780
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
781
+ t5 = /* @__PURE__ */ jsx(X, { size: 15 });
782
+ $[6] = t5;
783
+ } else t5 = $[6];
784
+ let t6;
785
+ if ($[7] !== onClose) {
786
+ t6 = /* @__PURE__ */ jsx("button", {
787
+ "aria-label": "Close inspector view",
788
+ onClick: onClose,
789
+ children: t5
790
+ });
791
+ $[7] = onClose;
792
+ $[8] = t6;
793
+ } else t6 = $[8];
794
+ let t7;
795
+ if ($[9] !== t4 || $[10] !== t6) {
796
+ t7 = /* @__PURE__ */ jsxs("header", { children: [
797
+ t1,
798
+ t4,
799
+ t6
800
+ ] });
801
+ $[9] = t4;
802
+ $[10] = t6;
803
+ $[11] = t7;
804
+ } else t7 = $[11];
805
+ const t8 = inspector.pinned ? "Selection pinned · click it again to unpin" : "Hover a component · click to pin";
806
+ let t9;
807
+ if ($[12] !== t8) {
808
+ t9 = /* @__PURE__ */ jsx("p", {
809
+ className: "povio-canvas-inspect-hint",
810
+ children: t8
811
+ });
812
+ $[12] = t8;
813
+ $[13] = t9;
814
+ } else t9 = $[13];
815
+ let t10;
816
+ if ($[14] !== inspector.highlight || $[15] !== inspector.measurement || $[16] !== onSelectToken) {
817
+ t10 = inspector.measurement ? /* @__PURE__ */ jsx(InspectorDetails, {
818
+ snapshot: inspector.measurement.snapshot,
819
+ onSelect: onSelectToken,
820
+ onHighlight: inspector.highlight
821
+ }) : /* @__PURE__ */ jsx("p", {
822
+ className: "povio-canvas-inspect-hint",
823
+ children: "Inspect a live page to see its padding, margins, borders, radii and gaps."
824
+ });
825
+ $[14] = inspector.highlight;
826
+ $[15] = inspector.measurement;
827
+ $[16] = onSelectToken;
828
+ $[17] = t10;
829
+ } else t10 = $[17];
830
+ let t11;
831
+ if ($[18] !== t10 || $[19] !== t7 || $[20] !== t9) {
832
+ t11 = /* @__PURE__ */ jsxs("aside", {
833
+ className: "studio-inspector-panel povio-canvas-inspector",
834
+ "aria-label": "Inspector view",
835
+ children: [
836
+ t7,
837
+ t9,
838
+ t10
839
+ ]
840
+ });
841
+ $[18] = t10;
842
+ $[19] = t7;
843
+ $[20] = t9;
844
+ $[21] = t11;
845
+ } else t11 = $[21];
846
+ return t11;
847
+ }
848
+ function CanvasInspectionOverlay(t0) {
849
+ const $ = c(9);
850
+ const { measurement, width } = t0;
851
+ let t1;
852
+ if ($[0] !== measurement.outline) {
853
+ t1 = /* @__PURE__ */ jsx("div", {
854
+ className: "studio-hover-outline",
855
+ style: measurement.outline
856
+ });
857
+ $[0] = measurement.outline;
858
+ $[1] = t1;
859
+ } else t1 = $[1];
860
+ let t2;
861
+ if ($[2] !== measurement.highlight || $[3] !== measurement.spacing || $[4] !== width) {
862
+ t2 = measurement.highlight ? /* @__PURE__ */ jsx(HighlightOverlay, {
863
+ highlight: measurement.highlight,
864
+ width
865
+ }) : measurement.spacing.map((highlight) => /* @__PURE__ */ jsxs("div", {
866
+ className: "povio-canvas-auto-spacing",
867
+ children: [/* @__PURE__ */ jsx(HighlightOverlay, {
868
+ highlight,
869
+ width
870
+ }), highlight.regions.map((region) => /* @__PURE__ */ jsx("span", {
871
+ className: "povio-canvas-spacing-value",
872
+ style: {
873
+ left: region.left + region.width / 2,
874
+ top: region.top + region.height / 2
875
+ },
876
+ children: highlight.label.split(": ")[1]
877
+ }, `${region.left}:${region.top}:${region.width}:${region.height}`))]
878
+ }, `${highlight.key}:${highlight.label}:${highlight.regions[0]?.left}:${highlight.regions[0]?.top}`));
879
+ $[2] = measurement.highlight;
880
+ $[3] = measurement.spacing;
881
+ $[4] = width;
882
+ $[5] = t2;
883
+ } else t2 = $[5];
884
+ let t3;
885
+ if ($[6] !== t1 || $[7] !== t2) {
886
+ t3 = /* @__PURE__ */ jsxs("div", {
887
+ className: "povio-canvas-inspection-overlay",
888
+ "aria-hidden": "true",
889
+ children: [t1, t2]
890
+ });
891
+ $[6] = t1;
892
+ $[7] = t2;
893
+ $[8] = t3;
894
+ } else t3 = $[8];
895
+ return t3;
896
+ }
897
+ //#endregion
898
+ //#region src/app-canvas/route-model.ts
899
+ function joinPath(parent, path) {
900
+ return `${parent.replace(/\/$/, "")}/${path.replace(/^\//, "")}`.replace(/\/{2,}/g, "/") || "/";
901
+ }
902
+ function resolvePath(path, params) {
903
+ const missingParams = /* @__PURE__ */ new Set();
904
+ const value = (key, optional = false) => {
905
+ const actualKey = key || "_splat";
906
+ const raw = params[actualKey];
907
+ if (raw === void 0 || !optional && raw === "") {
908
+ if (!optional) missingParams.add(actualKey);
909
+ return "";
910
+ }
911
+ return actualKey === "_splat" ? raw.split("/").map(encodeURIComponent).join("/") : encodeURIComponent(raw);
912
+ };
913
+ return {
914
+ href: `/${path.split("/").map((segment) => {
915
+ if (segment.includes("{")) return segment.replace(/\{(-?)\$([^}]*)\}/g, (_, optional, key) => value(key, optional === "-"));
916
+ return segment.startsWith("$") ? value(segment.slice(1)) : segment;
917
+ }).filter(Boolean).join("/")}`,
918
+ missingParams: [...missingParams]
919
+ };
920
+ }
921
+ /** Catalog route destinations without executing loaders or needing every dynamic parameter. */
922
+ function discoverCanvasPages(router, options = {}) {
923
+ const records = [];
924
+ const visited = /* @__PURE__ */ new Set();
925
+ function visit(route, parentPath, ancestors, root = false) {
926
+ if (visited.has(route)) return;
927
+ visited.add(route);
928
+ const localPath = route.path ?? route.options?.path;
929
+ const path = route.fullPath ?? (localPath ? joinPath(parentPath, localPath) : parentPath);
930
+ const id = route.id ?? route.options?.id ?? path;
931
+ const children = Object.values(route.children ?? {});
932
+ if (!root && localPath !== void 0 && !options.exclude?.includes(id) && !options.excludePaths?.some((excluded) => (excluded.replace(/\/$/, "") || "/") === (path.replace(/\/$/, "") || "/"))) records.push({
933
+ route,
934
+ id,
935
+ path,
936
+ ancestors,
937
+ index: localPath === "/"
938
+ });
939
+ for (const child of children) visit(child, path, [...ancestors, id]);
940
+ }
941
+ visit(router.routeTree, "/", [], true);
942
+ for (const route of Object.values(router.routesById ?? {})) if (!visited.has(route)) visit(route, "/", []);
943
+ const byPath = /* @__PURE__ */ new Map();
944
+ for (const record of records) {
945
+ const key = record.path.replace(/\/$/, "") || "/";
946
+ const existing = byPath.get(key);
947
+ if (!existing || record.index || record.ancestors.length > existing.ancestors.length) byPath.set(key, record);
948
+ }
949
+ const selectedIds = new Set([...byPath.values()].map(({ id }) => id));
950
+ const destinationIds = new Map(records.map((record) => [record.id, byPath.get(record.path.replace(/\/$/, "") || "/")?.id]));
951
+ return [...byPath.values()].map(({ id, path, ancestors }) => {
952
+ const example = options.examples?.[id];
953
+ const resolved = resolvePath(path, example?.params ?? {});
954
+ const query = new URLSearchParams();
955
+ for (const [key, value] of Object.entries(example?.search ?? {})) if (value !== void 0) query.set(key, typeof value === "string" ? value : JSON.stringify(value));
956
+ const queryString = query.toString();
957
+ return {
958
+ id,
959
+ path,
960
+ title: example?.title ?? (path === "/" ? "Home" : path),
961
+ href: resolved.missingParams.length ? void 0 : `${resolved.href}${queryString ? `?${queryString}` : ""}`,
962
+ parentId: [...ancestors].reverse().map((ancestor) => destinationIds.get(ancestor) ?? ancestor).find((ancestor) => ancestor !== id && selectedIds.has(ancestor)),
963
+ missingParams: resolved.missingParams,
964
+ kind: resolved.missingParams.length ? "unresolved" : "page"
965
+ };
966
+ });
967
+ }
968
+ /** Deterministic masonry placement. Full measured heights (including 20,000px pages) are never capped. */
969
+ function layoutCanvasPages(pages, width, heights, positions = {}) {
970
+ const pageWidth = Number.isFinite(width) && width > 0 ? width : 1440;
971
+ const columns = Math.min(3, Math.max(1, pages.length));
972
+ const bottoms = Array.from({ length: columns }, () => 0);
973
+ for (const page of pages) {
974
+ const saved = positions[page.id];
975
+ if (!saved || !Number.isFinite(saved.x) || !Number.isFinite(saved.y)) continue;
976
+ const measured = heights[page.id];
977
+ const height = Number.isFinite(measured) && measured > 0 ? measured : 900;
978
+ for (let i = 0; i < columns; i++) {
979
+ const x = i * (pageWidth + 80);
980
+ if (saved.x < x + pageWidth && saved.x + pageWidth > x) bottoms[i] = Math.max(bottoms[i], saved.y + height + 128);
981
+ }
982
+ }
983
+ const result = [];
984
+ for (const page of pages) {
985
+ const measured = heights[page.id];
986
+ const height = Number.isFinite(measured) && measured > 0 ? measured : 900;
987
+ const column = bottoms.indexOf(Math.min(...bottoms));
988
+ const saved = positions[page.id];
989
+ const position = saved && Number.isFinite(saved.x) && Number.isFinite(saved.y) ? saved : {
990
+ x: column * (pageWidth + 80),
991
+ y: bottoms[column]
992
+ };
993
+ result.push({
994
+ ...page,
995
+ ...position,
996
+ width: pageWidth,
997
+ height
998
+ });
999
+ for (let i = 0; i < columns; i++) {
1000
+ const x = i * (pageWidth + 80);
1001
+ if (position.x < x + pageWidth && position.x + pageWidth > x) bottoms[i] = Math.max(bottoms[i], position.y + height + 128);
1002
+ }
1003
+ }
1004
+ return result;
1005
+ }
1006
+ /** Match observed navigation back to a catalog destination, including optional and splat routes. */
1007
+ function matchCanvasPageHref(pages, href, base = "http://canvas.local/") {
1008
+ let pathname;
1009
+ try {
1010
+ pathname = new URL(href, base).pathname.replace(/\/$/, "") || "/";
1011
+ } catch {
1012
+ return;
1013
+ }
1014
+ const exact = pages.find((page) => {
1015
+ if (!page.href) return false;
1016
+ try {
1017
+ return (new URL(page.href, base).pathname.replace(/\/$/, "") || "/") === pathname;
1018
+ } catch {
1019
+ return false;
1020
+ }
1021
+ });
1022
+ if (exact) return exact;
1023
+ const escape = (part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1024
+ for (const page of pages) {
1025
+ const pattern = page.path.split("/").filter(Boolean).map((part) => {
1026
+ if (part === "$") return "/.+";
1027
+ if (part.startsWith("$")) return "/[^/]+";
1028
+ let text = "", cursor = 0;
1029
+ let optional = false;
1030
+ for (const match of part.matchAll(/\{(-?)\$([^}]*)\}/g)) {
1031
+ text += escape(part.slice(cursor, match.index)) + (match[2] ? "[^/]+" : ".+");
1032
+ cursor = match.index + match[0].length;
1033
+ optional ||= match[1] === "-";
1034
+ }
1035
+ text += escape(part.slice(cursor));
1036
+ return optional ? `(?:/${text})?` : `/${text}`;
1037
+ }).join("");
1038
+ if (new RegExp(`^${pattern || "/"}$`).test(pathname)) return page;
1039
+ }
1040
+ }
1041
+ //#endregion
1042
+ //#region src/app-canvas/protocol.ts
1043
+ const canvasProtocol = "povio-app-canvas-v1";
1044
+ function canvasFrameIdentity() {
1045
+ if (typeof window === "undefined" || window.parent === window) return null;
1046
+ try {
1047
+ const query = new URLSearchParams(window.location.search);
1048
+ const name = window.name.startsWith(`povio-app-canvas-v1:`) ? JSON.parse(window.name.slice(20)) : null;
1049
+ const id = query.get("__povio_canvas_frame") ?? name?.id;
1050
+ const token = query.get("__povio_canvas_token") ?? name?.token;
1051
+ const height = Number(query.get("__povio_canvas_height") ?? name?.viewportHeight ?? 900);
1052
+ return typeof id === "string" && typeof token === "string" && token.length > 10 ? {
1053
+ id,
1054
+ token,
1055
+ viewportHeight: Math.max(240, Math.min(4e3, height || 900))
1056
+ } : null;
1057
+ } catch {
1058
+ return null;
1059
+ }
1060
+ }
1061
+ const isAppCanvasFrame = () => !!canvasFrameIdentity();
1062
+ function validConfiguration(value) {
1063
+ if (!value || typeof value !== "object") return false;
1064
+ const config = value;
1065
+ return !!config.theme && [
1066
+ "light",
1067
+ "dark",
1068
+ "theme"
1069
+ ].every((key) => {
1070
+ const tokens = config.theme[key];
1071
+ return tokens && typeof tokens === "object" && Object.values(tokens).every((v) => typeof v === "string");
1072
+ }) && !!config.config && typeof config.config === "object";
1073
+ }
1074
+ //#endregion
1075
+ //#region src/app-canvas/manifest.ts
1076
+ function createCanvasManifest() {
1077
+ return {
1078
+ version: 1,
1079
+ positions: {},
1080
+ examples: {},
1081
+ manualEdges: [],
1082
+ hiddenEdges: [],
1083
+ breakpoint: "desktop"
1084
+ };
1085
+ }
1086
+ function isRecord(value) {
1087
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1088
+ }
1089
+ function isJSON(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
1090
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
1091
+ if (typeof value === "number") return Number.isFinite(value);
1092
+ if (typeof value !== "object" || depth > 30 || ancestors.has(value)) return false;
1093
+ ancestors.add(value);
1094
+ const valid = Object.values(value).every((child) => isJSON(child, ancestors, depth + 1));
1095
+ ancestors.delete(value);
1096
+ return valid;
1097
+ }
1098
+ /** Sanitize either stored JSON text or an imported value, retaining valid v1 entries. */
1099
+ function parseCanvasManifest(input) {
1100
+ const fallback = createCanvasManifest();
1101
+ let value = input;
1102
+ if (typeof value === "string") try {
1103
+ value = JSON.parse(value);
1104
+ } catch {
1105
+ return fallback;
1106
+ }
1107
+ if (!isRecord(value) || value.version !== 1) return fallback;
1108
+ const positions = Object.fromEntries(Object.entries(isRecord(value.positions) ? value.positions : {}).flatMap(([breakpoint, entries]) => {
1109
+ if (!isRecord(entries)) return [];
1110
+ return [[breakpoint, Object.fromEntries(Object.entries(entries).flatMap(([id, point]) => isRecord(point) && typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y) ? [[id, {
1111
+ x: point.x,
1112
+ y: point.y
1113
+ }]] : []))]];
1114
+ }));
1115
+ const examples = Object.fromEntries(Object.entries(isRecord(value.examples) ? value.examples : {}).flatMap(([id, example]) => {
1116
+ if (!isRecord(example)) return [];
1117
+ const clean = {};
1118
+ if (typeof example.title === "string") clean.title = example.title;
1119
+ if (isRecord(example.params)) clean.params = Object.fromEntries(Object.entries(example.params).filter((entry) => typeof entry[1] === "string"));
1120
+ if (isRecord(example.search)) clean.search = Object.fromEntries(Object.entries(example.search).filter(([, item]) => isJSON(item)));
1121
+ return [[id, clean]];
1122
+ }));
1123
+ const manualEdges = (Array.isArray(value.manualEdges) ? value.manualEdges : []).flatMap((edge) => isRecord(edge) && typeof edge.from === "string" && edge.from.length > 0 && typeof edge.to === "string" && edge.to.length > 0 ? [{
1124
+ from: edge.from,
1125
+ to: edge.to
1126
+ }] : []);
1127
+ return {
1128
+ version: 1,
1129
+ positions,
1130
+ examples,
1131
+ manualEdges: [...new Map(manualEdges.map((edge) => [JSON.stringify(edge), edge])).values()],
1132
+ hiddenEdges: [...new Set((Array.isArray(value.hiddenEdges) ? value.hiddenEdges : []).filter((edge) => typeof edge === "string"))],
1133
+ breakpoint: typeof value.breakpoint === "string" && value.breakpoint.length > 0 ? value.breakpoint : fallback.breakpoint
1134
+ };
1135
+ }
1136
+ //#endregion
1137
+ //#region src/app-canvas/AppCanvas.tsx
1138
+ const defaultCanvasBreakpoints = [
1139
+ {
1140
+ id: "mobile",
1141
+ label: "Mobile",
1142
+ width: 390,
1143
+ height: 844
1144
+ },
1145
+ {
1146
+ id: "tablet",
1147
+ label: "Tablet",
1148
+ width: 768,
1149
+ height: 1024
1150
+ },
1151
+ {
1152
+ id: "desktop",
1153
+ label: "Desktop",
1154
+ width: 1440,
1155
+ height: 900
1156
+ }
1157
+ ];
1158
+ const emptyExamples = {};
1159
+ const emptyExclude = [];
1160
+ /** Zoom per wheel pixel, and the largest delta one wheel event may contribute. */
1161
+ const ZOOM_SENSITIVITY = .006;
1162
+ const ZOOM_DELTA_LIMIT = 40;
1163
+ function readManifest(key) {
1164
+ if (typeof window === "undefined") return createCanvasManifest();
1165
+ try {
1166
+ return parseCanvasManifest(localStorage.getItem(key));
1167
+ } catch {
1168
+ return createCanvasManifest();
1169
+ }
1170
+ }
1171
+ const PageFrame = memo(function PageFrame(t0) {
1172
+ const $ = c(16);
1173
+ const { id, src, width, height, name, interact, inspect, onLoad, register } = t0;
1174
+ let t1;
1175
+ if ($[0] !== id || $[1] !== register) {
1176
+ t1 = (element) => register(id, element);
1177
+ $[0] = id;
1178
+ $[1] = register;
1179
+ $[2] = t1;
1180
+ } else t1 = $[2];
1181
+ const t2 = !interact && !inspect;
1182
+ const t3 = interact ? 0 : -1;
1183
+ const t4 = `Page ${id}`;
1184
+ let t5;
1185
+ if ($[3] !== id || $[4] !== onLoad) {
1186
+ t5 = (event) => onLoad(id, event.currentTarget);
1187
+ $[3] = id;
1188
+ $[4] = onLoad;
1189
+ $[5] = t5;
1190
+ } else t5 = $[5];
1191
+ let t6;
1192
+ if ($[6] !== height || $[7] !== name || $[8] !== src || $[9] !== t1 || $[10] !== t2 || $[11] !== t3 || $[12] !== t4 || $[13] !== t5 || $[14] !== width) {
1193
+ t6 = /* @__PURE__ */ jsx("iframe", {
1194
+ ref: t1,
1195
+ inert: t2,
1196
+ tabIndex: t3,
1197
+ title: t4,
1198
+ name,
1199
+ src,
1200
+ width,
1201
+ height,
1202
+ className: "povio-canvas-frame",
1203
+ onLoad: t5
1204
+ });
1205
+ $[6] = height;
1206
+ $[7] = name;
1207
+ $[8] = src;
1208
+ $[9] = t1;
1209
+ $[10] = t2;
1210
+ $[11] = t3;
1211
+ $[12] = t4;
1212
+ $[13] = t5;
1213
+ $[14] = width;
1214
+ $[15] = t6;
1215
+ } else t6 = $[15];
1216
+ return t6;
1217
+ });
1218
+ /** Live route artboards. The camera transforms only the canvas, never the iframe viewport width. */
1219
+ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, excludePaths = emptyExclude, breakpoints = defaultCanvasBreakpoints, storageKey = "povio-app-canvas", frameUrl, componentsHref }) {
1220
+ const configuration = useUIConfiguration();
1221
+ const [manifest, setManifest] = useState(() => readManifest(storageKey));
1222
+ const [runtime, setRuntime] = useState({});
1223
+ const [selected, setSelected] = useState(null);
1224
+ const [interact, setInteract] = useState(false);
1225
+ const [inspectMode, setInspectMode] = useState(false);
1226
+ const [dark, setDark] = useState(false);
1227
+ /** The canvas shows either the app's pages or the component gallery's sections, as artboards either way. */
1228
+ const [content, setContent] = useState("pages");
1229
+ const [mobilePanel, setMobilePanel] = useState(null);
1230
+ const [query, setQuery] = useState("");
1231
+ const [notice, setNotice] = useState("");
1232
+ const [documentGeneration, setDocumentGeneration] = useState(0);
1233
+ const [reload, setReload] = useState({});
1234
+ const zoomOutput = useRef(null);
1235
+ const importInput = useRef(null);
1236
+ const viewport = useRef(null), world = useRef(null);
1237
+ const frames = useRef(/* @__PURE__ */ new Map());
1238
+ const [token] = useState(() => crypto.randomUUID());
1239
+ const revision = useRef(0), camera = useRef({
1240
+ x: 40,
1241
+ y: 40,
1242
+ zoom: .25
1243
+ }), pendingCamera = useRef(null);
1244
+ const pointer = useRef(null);
1245
+ const cameraRevision = useRef(0);
1246
+ const bp = breakpoints.find((item) => item.id === manifest.breakpoint) ?? breakpoints[breakpoints.length - 1] ?? defaultCanvasBreakpoints[2];
1247
+ const isKnownToken = useCallback((name) => isEditableToken(name, configuration.defaults), [configuration.defaults]);
1248
+ const { hostComponents } = configuration;
1249
+ useEffect(() => hostComponents(), [hostComponents]);
1250
+ const inspector = useCanvasInspector(inspectMode, `${content}:${bp.id}:${documentGeneration}:${JSON.stringify(reload)}`, isKnownToken);
1251
+ const pageCatalog = useMemo(() => discoverCanvasPages(router, {
1252
+ examples: {
1253
+ ...examples,
1254
+ ...manifest.examples
1255
+ },
1256
+ exclude,
1257
+ excludePaths
1258
+ }), [
1259
+ router,
1260
+ examples,
1261
+ manifest.examples,
1262
+ exclude,
1263
+ excludePaths
1264
+ ]);
1265
+ const componentCatalog = useMemo(() => componentsHref ? componentArtboards.map((group) => ({
1266
+ id: `components:${group.toLowerCase()}`,
1267
+ title: group,
1268
+ path: group,
1269
+ href: componentsHref(group),
1270
+ missingParams: [],
1271
+ kind: "page"
1272
+ })) : [], [componentsHref]);
1273
+ const catalog = content === "components" && componentCatalog.length ? componentCatalog : pageCatalog;
1274
+ const startupKeys = useMemo(() => new Map(catalog.filter((page) => page.href).map((page_0) => [page_0.id, `${documentGeneration}:${bp.id}:${page_0.id}:${page_0.href}:${reload[page_0.id] ?? 0}`])), [
1275
+ catalog,
1276
+ documentGeneration,
1277
+ bp.id,
1278
+ reload
1279
+ ]);
1280
+ const startup = useFrameStartup([...startupKeys.values()]);
1281
+ const startupRef = useRef({
1282
+ keys: startupKeys,
1283
+ complete: startup.complete
1284
+ });
1285
+ startupRef.current = {
1286
+ keys: startupKeys,
1287
+ complete: startup.complete
1288
+ };
1289
+ const heights = useMemo(() => Object.fromEntries(catalog.map((page_1) => [page_1.id, runtime[`${bp.id}:${page_1.id}:${page_1.href ?? ""}`]?.height ?? bp.height])), [
1290
+ catalog,
1291
+ runtime,
1292
+ bp
1293
+ ]);
1294
+ const nodes = useMemo(() => layoutCanvasPages(catalog, bp.width, heights, manifest.positions[bp.id] ?? {}), [
1295
+ catalog,
1296
+ bp,
1297
+ heights,
1298
+ manifest.positions
1299
+ ]);
1300
+ const nodeMap = useMemo(() => new Map(nodes.map((node) => [node.id, node])), [nodes]);
1301
+ const latest = useRef({
1302
+ configuration: configuration.active,
1303
+ dark,
1304
+ interact,
1305
+ bp,
1306
+ catalog,
1307
+ frameUrl
1308
+ });
1309
+ latest.current = {
1310
+ configuration: configuration.active,
1311
+ dark,
1312
+ interact,
1313
+ bp,
1314
+ catalog,
1315
+ frameUrl
1316
+ };
1317
+ const register = useCallback((id, frame) => {
1318
+ if (frame) frames.current.set(id, frame);
1319
+ else frames.current.delete(id);
1320
+ }, []);
1321
+ const paint = useCallback(() => {
1322
+ if (world.current) {
1323
+ world.current.style.transform = `translate3d(${camera.current.x}px,${camera.current.y}px,0) scale(${camera.current.zoom})`;
1324
+ const zoom = String(camera.current.zoom);
1325
+ if (world.current.style.getPropertyValue("--canvas-zoom") !== zoom) world.current.style.setProperty("--canvas-zoom", zoom);
1326
+ }
1327
+ if (zoomOutput.current) zoomOutput.current.textContent = `${Math.round(camera.current.zoom * 1e3) / 10}%`;
1328
+ const canvas = viewport.current?.closest(".povio-app-canvas");
1329
+ if (canvas) canvas.setAttribute("data-camera-revision", String(++cameraRevision.current));
1330
+ }, []);
1331
+ const schedulePaint = useCallback(() => {
1332
+ if (pendingCamera.current !== null) return;
1333
+ pendingCamera.current = requestAnimationFrame(() => {
1334
+ pendingCamera.current = null;
1335
+ paint();
1336
+ });
1337
+ }, [paint]);
1338
+ const send = useCallback((id_0, type = "configuration") => {
1339
+ const frame_0 = frames.current.get(id_0);
1340
+ if (!frame_0?.contentWindow) return;
1341
+ const current = latest.current;
1342
+ try {
1343
+ frame_0.contentWindow.postMessage({
1344
+ protocol: canvasProtocol,
1345
+ id: id_0,
1346
+ token,
1347
+ viewportHeight: current.bp.height,
1348
+ type,
1349
+ configuration: current.configuration,
1350
+ revision: revision.current,
1351
+ dark: current.dark,
1352
+ interact: current.interact
1353
+ }, new URL(frame_0.src).origin);
1354
+ } catch {
1355
+ setNotice("This configuration could not be sent to the page. Check for non-serializable values.");
1356
+ }
1357
+ }, [token]);
1358
+ const focusPage = useCallback((id_1) => {
1359
+ const node_0 = nodeMap.get(id_1), view = viewport.current;
1360
+ if (!node_0 || !view) return;
1361
+ setSelected(id_1);
1362
+ camera.current.zoom = Math.min(1, Math.max(.08, (view.clientWidth - 100) / node_0.width));
1363
+ camera.current.x = 40 - node_0.x * camera.current.zoom;
1364
+ camera.current.y = 40 - node_0.y * camera.current.zoom;
1365
+ paint();
1366
+ }, [nodeMap, paint]);
1367
+ const focusRef = useRef(focusPage);
1368
+ focusRef.current = focusPage;
1369
+ const matchHref = useCallback((href) => matchCanvasPageHref(latest.current.catalog, href, window.location.href), []);
1370
+ useEffect(() => {
1371
+ const queue = /* @__PURE__ */ new Map();
1372
+ let batch = 0;
1373
+ const flush = () => {
1374
+ batch = 0;
1375
+ const changes = Array.from(queue);
1376
+ queue.clear();
1377
+ setRuntime((current_0) => {
1378
+ const next = { ...current_0 };
1379
+ let changed = false;
1380
+ for (const [key, item_0] of changes) {
1381
+ if (frames.current.get(item_0.id) !== item_0.frame || item_0.frame.contentWindow !== item_0.source) continue;
1382
+ next[key] = {
1383
+ ...next[key],
1384
+ ...item_0.change
1385
+ };
1386
+ changed = true;
1387
+ }
1388
+ return changed ? next : current_0;
1389
+ });
1390
+ };
1391
+ const receive = (event) => {
1392
+ const packet = event.data;
1393
+ if (packet?.protocol !== "povio-app-canvas-v1" || packet.token !== token || typeof packet.id !== "string") return;
1394
+ const frame_1 = frames.current.get(packet.id);
1395
+ if (!frame_1 || event.source !== frame_1.contentWindow || event.origin !== new URL(frame_1.src).origin) return;
1396
+ const key_0 = `${latest.current.bp.id}:${packet.id}:${latest.current.catalog.find((page_2) => page_2.id === packet.id)?.href ?? ""}`;
1397
+ let change = {};
1398
+ if (packet.type === "ready") {
1399
+ startupRef.current.complete(startupRef.current.keys.get(packet.id));
1400
+ change = {
1401
+ ready: true,
1402
+ href: packet.href,
1403
+ timedOut: false
1404
+ };
1405
+ send(packet.id);
1406
+ send(packet.id, "mode");
1407
+ }
1408
+ if (packet.type === "height" && typeof packet.height === "number" && Number.isFinite(packet.height) && packet.height > 0) change.height = packet.height;
1409
+ if (packet.type === "warning" && typeof packet.warning === "string") change.warning = packet.warning;
1410
+ if (packet.type === "ack" && typeof packet.revision === "number") change.revision = packet.revision;
1411
+ if (packet.type === "navigate" && typeof packet.href === "string") {
1412
+ const target = matchHref(packet.href);
1413
+ if (target) focusRef.current(target.id);
1414
+ else setNotice(`Navigation target is not in this canvas: ${packet.href}`);
1415
+ return;
1416
+ }
1417
+ if (!Object.keys(change).length) return;
1418
+ const pending = queue.get(key_0);
1419
+ const previous = pending?.frame === frame_1 && pending.source === event.source ? pending.change : {};
1420
+ queue.set(key_0, {
1421
+ id: packet.id,
1422
+ frame: frame_1,
1423
+ source: event.source,
1424
+ change: {
1425
+ ...previous,
1426
+ ...change
1427
+ }
1428
+ });
1429
+ if (!batch) batch = requestAnimationFrame(flush);
1430
+ };
1431
+ window.addEventListener("message", receive);
1432
+ return () => {
1433
+ window.removeEventListener("message", receive);
1434
+ cancelAnimationFrame(batch);
1435
+ };
1436
+ }, [
1437
+ token,
1438
+ send,
1439
+ matchHref
1440
+ ]);
1441
+ useEffect(() => {
1442
+ const frame_2 = requestAnimationFrame(() => {
1443
+ revision.current++;
1444
+ for (const id_2 of frames.current.keys()) send(id_2);
1445
+ });
1446
+ return () => cancelAnimationFrame(frame_2);
1447
+ }, [
1448
+ configuration.active,
1449
+ dark,
1450
+ send
1451
+ ]);
1452
+ useEffect(() => {
1453
+ for (const id_3 of frames.current.keys()) send(id_3, "mode");
1454
+ }, [interact, send]);
1455
+ useEffect(() => {
1456
+ try {
1457
+ localStorage.setItem(storageKey, JSON.stringify(manifest));
1458
+ } catch {
1459
+ setNotice("Browser storage is unavailable; use Export layout to save this canvas.");
1460
+ }
1461
+ }, [manifest, storageKey]);
1462
+ useEffect(() => {
1463
+ paint();
1464
+ const element = viewport.current;
1465
+ if (!element) return;
1466
+ const wheel = (event_0) => {
1467
+ event_0.preventDefault();
1468
+ if (event_0.ctrlKey || event_0.metaKey) {
1469
+ const box = element.getBoundingClientRect();
1470
+ const x = event_0.clientX - box.left, y = event_0.clientY - box.top;
1471
+ const previous_0 = camera.current.zoom;
1472
+ const unit = event_0.deltaMode === 1 ? 16 : event_0.deltaMode === 2 ? element.clientHeight : 1;
1473
+ const delta = Math.max(-40, Math.min(ZOOM_DELTA_LIMIT, event_0.deltaY * unit));
1474
+ const next_0 = Math.max(.005, Math.min(2, previous_0 * Math.exp(-delta * ZOOM_SENSITIVITY)));
1475
+ camera.current.x = x - (x - camera.current.x) * next_0 / previous_0;
1476
+ camera.current.y = y - (y - camera.current.y) * next_0 / previous_0;
1477
+ camera.current.zoom = next_0;
1478
+ } else {
1479
+ camera.current.x -= event_0.deltaX;
1480
+ camera.current.y -= event_0.deltaY;
1481
+ }
1482
+ schedulePaint();
1483
+ };
1484
+ const unscroll = () => {
1485
+ if (element.scrollTop || element.scrollLeft) element.scrollTo(0, 0);
1486
+ };
1487
+ element.addEventListener("wheel", wheel, { passive: false });
1488
+ element.addEventListener("scroll", unscroll);
1489
+ return () => {
1490
+ element.removeEventListener("wheel", wheel);
1491
+ element.removeEventListener("scroll", unscroll);
1492
+ if (pendingCamera.current !== null) cancelAnimationFrame(pendingCamera.current);
1493
+ pendingCamera.current = null;
1494
+ };
1495
+ }, [paint, schedulePaint]);
1496
+ const fit = () => {
1497
+ if (!nodes.length || !viewport.current) return;
1498
+ const left = Math.min(...nodes.map((n) => n.x)), top = Math.min(...nodes.map((n_0) => n_0.y));
1499
+ const width = Math.max(...nodes.map((n_1) => n_1.x + n_1.width)) - left, height = Math.max(...nodes.map((n_2) => n_2.y + n_2.height + 48)) - top;
1500
+ camera.current.zoom = Math.max(.005, Math.min(1, (viewport.current.clientWidth - 80) / width, (viewport.current.clientHeight - 80) / height));
1501
+ camera.current.x = 40 - left * camera.current.zoom;
1502
+ camera.current.y = 40 - top * camera.current.zoom;
1503
+ paint();
1504
+ };
1505
+ const fitRef = useRef(fit);
1506
+ fitRef.current = fit;
1507
+ const switchContent = (next_1) => {
1508
+ if (next_1 === content) return;
1509
+ setContent(next_1);
1510
+ setSelected(null);
1511
+ setQuery("");
1512
+ requestAnimationFrame(() => fitRef.current());
1513
+ };
1514
+ const zoomTo = (value) => {
1515
+ const view_0 = viewport.current;
1516
+ if (!view_0) return;
1517
+ const previous_1 = camera.current.zoom, next_2 = Math.max(.005, Math.min(2, value));
1518
+ camera.current.x = view_0.clientWidth / 2 - (view_0.clientWidth / 2 - camera.current.x) * next_2 / previous_1;
1519
+ camera.current.y = view_0.clientHeight / 2 - (view_0.clientHeight / 2 - camera.current.y) * next_2 / previous_1;
1520
+ camera.current.zoom = next_2;
1521
+ paint();
1522
+ };
1523
+ const stepZoom = (direction) => {
1524
+ const stops = [
1525
+ .005,
1526
+ .01,
1527
+ .02,
1528
+ .05,
1529
+ .1,
1530
+ .25,
1531
+ .5,
1532
+ .75,
1533
+ 1,
1534
+ 1.5,
1535
+ 2
1536
+ ];
1537
+ const current_1 = camera.current.zoom;
1538
+ const next_3 = direction === 1 ? stops.find((value_0) => value_0 > current_1 + 1e-4) : [...stops].reverse().find((value_1) => value_1 < current_1 - 1e-4);
1539
+ if (next_3 !== void 0) zoomTo(next_3);
1540
+ };
1541
+ const startPan = (event_1) => {
1542
+ if (inspectMode && event_1.target.closest(".povio-canvas-frame-cover")) return;
1543
+ if (event_1.button !== 0 || event_1.target.closest("button:not(.povio-canvas-frame-cover),input,select,.povio-canvas-node-header")) return;
1544
+ event_1.currentTarget.setPointerCapture(event_1.pointerId);
1545
+ pointer.current = {
1546
+ id: event_1.pointerId,
1547
+ x: event_1.clientX,
1548
+ y: event_1.clientY,
1549
+ startX: camera.current.x,
1550
+ startY: camera.current.y
1551
+ };
1552
+ };
1553
+ const move = (event_2) => {
1554
+ const current_2 = pointer.current;
1555
+ if (!current_2 || current_2.id !== event_2.pointerId) return;
1556
+ const dx = event_2.clientX - current_2.x, dy = event_2.clientY - current_2.y;
1557
+ if (current_2.node) {
1558
+ const element_0 = world.current?.querySelector(`[data-node-index="${nodes.findIndex((n_3) => n_3.id === current_2.node)}"]`);
1559
+ if (element_0) {
1560
+ element_0.style.left = `${current_2.nodeX + dx / camera.current.zoom}px`;
1561
+ element_0.style.top = `${current_2.nodeY + dy / camera.current.zoom}px`;
1562
+ }
1563
+ } else {
1564
+ camera.current.x = current_2.startX + dx;
1565
+ camera.current.y = current_2.startY + dy;
1566
+ schedulePaint();
1567
+ }
1568
+ };
1569
+ const end = (event_3) => {
1570
+ const current_3 = pointer.current;
1571
+ if (!current_3 || current_3.id !== event_3.pointerId) return;
1572
+ if (current_3.node) {
1573
+ const position = {
1574
+ x: current_3.nodeX + (event_3.clientX - current_3.x) / camera.current.zoom,
1575
+ y: current_3.nodeY + (event_3.clientY - current_3.y) / camera.current.zoom
1576
+ };
1577
+ setManifest((m) => ({
1578
+ ...m,
1579
+ positions: {
1580
+ ...m.positions,
1581
+ [bp.id]: {
1582
+ ...m.positions[bp.id],
1583
+ [current_3.node]: position
1584
+ }
1585
+ }
1586
+ }));
1587
+ }
1588
+ pointer.current = null;
1589
+ if (event_3.currentTarget.hasPointerCapture(event_3.pointerId)) event_3.currentTarget.releasePointerCapture(event_3.pointerId);
1590
+ };
1591
+ const onLoad = useCallback((id_4, frame_3) => {
1592
+ if (frames.current.get(id_4) !== frame_3) return;
1593
+ startupRef.current.complete(startupRef.current.keys.get(id_4));
1594
+ send(id_4);
1595
+ send(id_4, "mode");
1596
+ }, [send]);
1597
+ useEffect(() => {
1598
+ const timer = setTimeout(() => setRuntime((current_4) => {
1599
+ const next_4 = { ...current_4 };
1600
+ for (const page_3 of latest.current.catalog) {
1601
+ const key_1 = `${latest.current.bp.id}:${page_3.id}:${page_3.href ?? ""}`;
1602
+ if (page_3.href && frames.current.has(page_3.id) && !next_4[key_1]?.ready) next_4[key_1] = {
1603
+ ...next_4[key_1],
1604
+ timedOut: true
1605
+ };
1606
+ }
1607
+ return next_4;
1608
+ }), 15e3);
1609
+ return () => clearTimeout(timer);
1610
+ }, [
1611
+ bp.id,
1612
+ catalog,
1613
+ reload,
1614
+ startup.admitted
1615
+ ]);
1616
+ const exportLayout = () => {
1617
+ const url = URL.createObjectURL(new Blob([JSON.stringify(manifest, null, 2)], { type: "application/json" }));
1618
+ const a = document.createElement("a");
1619
+ a.href = url;
1620
+ a.download = "povio-app-canvas.json";
1621
+ a.click();
1622
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
1623
+ };
1624
+ const width_0 = Math.max(1, ...nodes.map((n_4) => n_4.x + n_4.width + 80)), height_0 = Math.max(1, ...nodes.map((n_5) => n_5.y + n_5.height + 128));
1625
+ const ready = nodes.filter((n_6) => runtime[`${bp.id}:${n_6.id}:${n_6.href ?? ""}`]?.ready).length;
1626
+ return /* @__PURE__ */ jsxs("section", {
1627
+ className: "povio-app-canvas",
1628
+ "data-mobile-panel": mobilePanel ?? "none",
1629
+ "data-inspecting": inspectMode,
1630
+ "aria-label": "App canvas",
1631
+ "data-ready-count": ready,
1632
+ "data-page-count": nodes.length,
1633
+ "data-camera-revision": "0",
1634
+ children: [
1635
+ /* @__PURE__ */ jsx("input", {
1636
+ ref: importInput,
1637
+ type: "file",
1638
+ accept: "application/json,.json",
1639
+ hidden: true,
1640
+ "aria-label": "Import canvas layout",
1641
+ onChange: async (event_4) => {
1642
+ const file = event_4.currentTarget.files?.[0];
1643
+ event_4.currentTarget.value = "";
1644
+ if (!file) return;
1645
+ try {
1646
+ const raw = JSON.parse(await file.text());
1647
+ if (raw?.version !== 1) throw new Error("version");
1648
+ setManifest(parseCanvasManifest(raw));
1649
+ setRuntime({});
1650
+ setDocumentGeneration((value_2) => value_2 + 1);
1651
+ setNotice("Layout imported.");
1652
+ } catch {
1653
+ setNotice("Choose a valid version 1 canvas layout JSON file.");
1654
+ }
1655
+ }
1656
+ }),
1657
+ /* @__PURE__ */ jsxs("div", {
1658
+ className: "povio-canvas-body",
1659
+ children: [
1660
+ /* @__PURE__ */ jsxs("aside", {
1661
+ className: "povio-canvas-catalog",
1662
+ "aria-label": "Page catalog",
1663
+ children: [
1664
+ /* @__PURE__ */ jsxs("div", {
1665
+ className: "povio-canvas-brand povio-canvas-content-switch",
1666
+ role: "group",
1667
+ "aria-label": "Canvas content",
1668
+ children: [/* @__PURE__ */ jsxs("button", {
1669
+ "aria-pressed": content === "pages",
1670
+ onClick: () => switchContent("pages"),
1671
+ children: ["Pages", /* @__PURE__ */ jsx("span", {
1672
+ className: "povio-canvas-page-count",
1673
+ children: pageCatalog.length
1674
+ })]
1675
+ }), !!componentCatalog.length && /* @__PURE__ */ jsxs("button", {
1676
+ "aria-pressed": content === "components",
1677
+ onClick: () => switchContent("components"),
1678
+ children: ["Components", /* @__PURE__ */ jsx("span", {
1679
+ className: "povio-canvas-page-count",
1680
+ children: componentCatalog.length
1681
+ })]
1682
+ })]
1683
+ }),
1684
+ /* @__PURE__ */ jsxs("div", {
1685
+ className: "povio-canvas-search",
1686
+ children: [
1687
+ /* @__PURE__ */ jsx(Search, { size: 14 }),
1688
+ /* @__PURE__ */ jsx("input", {
1689
+ "aria-label": content === "components" ? "Find component section" : "Find page",
1690
+ placeholder: content === "components" ? "Find section…" : "Find page…",
1691
+ value: query,
1692
+ onChange: (event_5) => setQuery(event_5.target.value)
1693
+ }),
1694
+ /* @__PURE__ */ jsx("button", {
1695
+ className: "povio-canvas-panel-close",
1696
+ "aria-label": "Close pages panel",
1697
+ onClick: () => setMobilePanel(null),
1698
+ children: /* @__PURE__ */ jsx(X, { size: 16 })
1699
+ })
1700
+ ]
1701
+ }),
1702
+ /* @__PURE__ */ jsxs("div", {
1703
+ className: "povio-canvas-page-list",
1704
+ children: [nodes.filter((node_1) => `${node_1.title} ${node_1.path}`.toLowerCase().includes(query.toLowerCase())).map((node_2) => /* @__PURE__ */ jsxs("button", {
1705
+ "aria-pressed": selected === node_2.id,
1706
+ onClick: () => {
1707
+ focusPage(node_2.id);
1708
+ setMobilePanel(null);
1709
+ },
1710
+ children: [/* @__PURE__ */ jsx(Frame, { size: 15 }), /* @__PURE__ */ jsxs("span", {
1711
+ className: "povio-canvas-page-label",
1712
+ children: [/* @__PURE__ */ jsx("strong", { children: node_2.title }), node_2.kind === "unresolved" && /* @__PURE__ */ jsx("small", { children: "Needs parameters" })]
1713
+ })]
1714
+ }, node_2.id)), selected && nodeMap.get(selected)?.href && /* @__PURE__ */ jsx(PageLayers, {
1715
+ frame: frames.current.get(selected) ?? null,
1716
+ title: nodeMap.get(selected).title,
1717
+ selected: inspector.selection?.pageId === selected ? inspector.selection.element : void 0,
1718
+ onSelect: (element_1) => {
1719
+ setInteract(false);
1720
+ setInspectMode(true);
1721
+ inspector.selectElement(selected, element_1);
1722
+ setMobilePanel(null);
1723
+ requestAnimationFrame(() => {
1724
+ const node_3 = nodeMap.get(selected), view_1 = viewport.current;
1725
+ if (!node_3 || !view_1 || !element_1.isConnected) return;
1726
+ const rect = element_1.getBoundingClientRect();
1727
+ camera.current.x = view_1.clientWidth / 2 - (node_3.x + rect.left + rect.width / 2) * camera.current.zoom;
1728
+ camera.current.y = view_1.clientHeight / 2 - (node_3.y + 48 + rect.top + rect.height / 2) * camera.current.zoom;
1729
+ paint();
1730
+ });
1731
+ }
1732
+ }, `${bp.id}:${documentGeneration}:${reload[selected] ?? 0}:${selected}:${nodeMap.get(selected)?.href}`)]
1733
+ }),
1734
+ /* @__PURE__ */ jsxs("div", {
1735
+ className: "povio-canvas-sidebar-actions",
1736
+ children: [
1737
+ /* @__PURE__ */ jsx("button", {
1738
+ className: "povio-canvas-file-action",
1739
+ onClick: exportLayout,
1740
+ "aria-label": "Export layout",
1741
+ title: "Export layout",
1742
+ children: /* @__PURE__ */ jsx(Download, { size: 16 })
1743
+ }),
1744
+ /* @__PURE__ */ jsx("button", {
1745
+ className: "povio-canvas-file-action",
1746
+ onClick: () => importInput.current?.click(),
1747
+ "aria-label": "Import layout",
1748
+ title: "Import layout",
1749
+ children: /* @__PURE__ */ jsx(Upload, { size: 16 })
1750
+ }),
1751
+ /* @__PURE__ */ jsxs("span", {
1752
+ className: "povio-canvas-ready",
1753
+ role: "status",
1754
+ children: [
1755
+ /* @__PURE__ */ jsx("i", {}),
1756
+ ready,
1757
+ "/",
1758
+ nodes.length,
1759
+ " ",
1760
+ content === "components" ? "sections" : "pages",
1761
+ " ready"
1762
+ ]
1763
+ })
1764
+ ]
1765
+ })
1766
+ ]
1767
+ }),
1768
+ /* @__PURE__ */ jsxs("div", {
1769
+ ref: viewport,
1770
+ className: "povio-canvas-viewport",
1771
+ onKeyDownCapture: (event_6) => {
1772
+ if (inspectMode && event_6.key === "Escape") {
1773
+ event_6.preventDefault();
1774
+ inspector.clear();
1775
+ }
1776
+ },
1777
+ onPointerDown: startPan,
1778
+ onPointerMove: move,
1779
+ onPointerUp: end,
1780
+ onPointerCancel: (event_7) => {
1781
+ const current_5 = pointer.current;
1782
+ if (current_5?.node) {
1783
+ const element_2 = world.current?.querySelector(`[data-node-index="${nodes.findIndex((node_4) => node_4.id === current_5.node)}"]`);
1784
+ if (element_2) {
1785
+ element_2.style.left = `${current_5.nodeX}px`;
1786
+ element_2.style.top = `${current_5.nodeY}px`;
1787
+ }
1788
+ }
1789
+ pointer.current = null;
1790
+ if (event_7.currentTarget.hasPointerCapture(event_7.pointerId)) event_7.currentTarget.releasePointerCapture(event_7.pointerId);
1791
+ },
1792
+ children: [
1793
+ /* @__PURE__ */ jsx("div", {
1794
+ className: "povio-canvas-mobile-tools",
1795
+ children: /* @__PURE__ */ jsx("button", {
1796
+ "aria-label": "Toggle pages panel",
1797
+ "aria-pressed": mobilePanel === "pages",
1798
+ onClick: () => setMobilePanel(mobilePanel === "pages" ? null : "pages"),
1799
+ children: /* @__PURE__ */ jsx(PanelLeft, { size: 18 })
1800
+ })
1801
+ }),
1802
+ /* @__PURE__ */ jsx("div", {
1803
+ ref: world,
1804
+ className: "povio-canvas-world",
1805
+ style: {
1806
+ width: width_0,
1807
+ height: height_0
1808
+ },
1809
+ children: nodes.map((node_5, index) => {
1810
+ const state = runtime[`${bp.id}:${node_5.id}:${node_5.href ?? ""}`] ?? {};
1811
+ let source = "";
1812
+ let originError = false;
1813
+ if (node_5.href) try {
1814
+ const url_0 = new URL(frameUrl?.(node_5) ?? node_5.href, window.location.href);
1815
+ if (url_0.origin !== window.location.origin) throw new Error("same origin required");
1816
+ url_0.searchParams.delete("povioCanvas");
1817
+ url_0.searchParams.delete("__povio_canvas_frame");
1818
+ url_0.searchParams.delete("__povio_canvas_token");
1819
+ url_0.searchParams.delete("__povio_canvas_height");
1820
+ source = url_0.href;
1821
+ } catch {
1822
+ originError = true;
1823
+ }
1824
+ const redirected = state.href && node_5.href && new URL(state.href, window.location.href).pathname !== new URL(node_5.href, window.location.href).pathname;
1825
+ return /* @__PURE__ */ jsxs("article", {
1826
+ "data-node-index": index,
1827
+ "data-page-id": node_5.id,
1828
+ className: `povio-canvas-node${selected === node_5.id ? " is-selected" : ""}`,
1829
+ style: {
1830
+ left: node_5.x,
1831
+ top: node_5.y,
1832
+ width: node_5.width
1833
+ },
1834
+ children: [
1835
+ /* @__PURE__ */ jsxs("header", {
1836
+ className: "povio-canvas-node-header",
1837
+ onPointerDown: (event_8) => {
1838
+ if (event_8.button !== 0 || event_8.target.closest("button")) return;
1839
+ event_8.stopPropagation();
1840
+ viewport.current?.setPointerCapture(event_8.pointerId);
1841
+ pointer.current = {
1842
+ id: event_8.pointerId,
1843
+ x: event_8.clientX,
1844
+ y: event_8.clientY,
1845
+ startX: 0,
1846
+ startY: 0,
1847
+ node: node_5.id,
1848
+ nodeX: node_5.x,
1849
+ nodeY: node_5.y
1850
+ };
1851
+ setSelected(node_5.id);
1852
+ },
1853
+ children: [
1854
+ /* @__PURE__ */ jsx("strong", { children: node_5.title }),
1855
+ /* @__PURE__ */ jsxs("span", { children: [
1856
+ bp.width,
1857
+ " × ",
1858
+ Math.round(node_5.height).toLocaleString()
1859
+ ] }),
1860
+ /* @__PURE__ */ jsx("button", {
1861
+ "aria-label": `Focus ${node_5.title}`,
1862
+ onClick: () => focusPage(node_5.id),
1863
+ children: "↗"
1864
+ }),
1865
+ /* @__PURE__ */ jsx("button", {
1866
+ "aria-label": `Reload ${node_5.title}`,
1867
+ onClick: () => {
1868
+ setRuntime((r) => ({
1869
+ ...r,
1870
+ [`${bp.id}:${node_5.id}:${node_5.href ?? ""}`]: {}
1871
+ }));
1872
+ setReload((r_0) => ({
1873
+ ...r_0,
1874
+ [node_5.id]: (r_0[node_5.id] ?? 0) + 1
1875
+ }));
1876
+ },
1877
+ children: "↻"
1878
+ })
1879
+ ]
1880
+ }),
1881
+ !node_5.href ? /* @__PURE__ */ jsxs("form", {
1882
+ className: "povio-canvas-unresolved",
1883
+ onSubmit: (event_9) => {
1884
+ event_9.preventDefault();
1885
+ const form = new FormData(event_9.currentTarget);
1886
+ const enteredParams = Object.fromEntries(node_5.missingParams.map((key_2) => {
1887
+ const value_3 = form.get(key_2);
1888
+ return [key_2, typeof value_3 === "string" ? value_3 : ""];
1889
+ }));
1890
+ setManifest((m_0) => ({
1891
+ ...m_0,
1892
+ examples: {
1893
+ ...m_0.examples,
1894
+ [node_5.id]: {
1895
+ ...examples[node_5.id],
1896
+ ...m_0.examples[node_5.id],
1897
+ params: {
1898
+ ...examples[node_5.id]?.params,
1899
+ ...m_0.examples[node_5.id]?.params,
1900
+ ...enteredParams
1901
+ }
1902
+ }
1903
+ }
1904
+ }));
1905
+ },
1906
+ children: [
1907
+ /* @__PURE__ */ jsx("strong", { children: "Route needs parameters" }),
1908
+ /* @__PURE__ */ jsx("code", { children: node_5.path }),
1909
+ node_5.missingParams.map((key_3) => /* @__PURE__ */ jsxs("label", { children: [key_3, /* @__PURE__ */ jsx("input", {
1910
+ name: key_3,
1911
+ required: true
1912
+ })] }, key_3)),
1913
+ /* @__PURE__ */ jsx("button", { children: "Render page" })
1914
+ ]
1915
+ }) : originError ? /* @__PURE__ */ jsx("p", {
1916
+ className: "povio-canvas-unresolved",
1917
+ children: "Canvas pages must use the same origin."
1918
+ }) : !startup.admitted.has(startupKeys.get(node_5.id) ?? "") ? /* @__PURE__ */ jsx("div", {
1919
+ className: "povio-canvas-unresolved",
1920
+ role: "status",
1921
+ children: "Waiting to load page…"
1922
+ }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
1923
+ /* @__PURE__ */ jsx(PageFrame, {
1924
+ id: node_5.id,
1925
+ interact,
1926
+ inspect: inspectMode,
1927
+ src: source,
1928
+ width: bp.width,
1929
+ height: node_5.height,
1930
+ name: `${canvasProtocol}:${JSON.stringify({
1931
+ id: node_5.id,
1932
+ token,
1933
+ viewportHeight: bp.height
1934
+ })}`,
1935
+ onLoad,
1936
+ register
1937
+ }, `${documentGeneration}:${bp.id}:${source}:${reload[node_5.id] ?? 0}`),
1938
+ !interact && /* @__PURE__ */ jsx("button", {
1939
+ type: "button",
1940
+ className: "povio-canvas-frame-cover",
1941
+ tabIndex: 0,
1942
+ "aria-label": `Select ${node_5.title}`,
1943
+ onKeyDown: (event_10) => {
1944
+ if (event_10.key === "Enter" || event_10.key === " ") {
1945
+ event_10.preventDefault();
1946
+ setSelected(node_5.id);
1947
+ }
1948
+ },
1949
+ onPointerMove: (event_11) => {
1950
+ const frame_4 = frames.current.get(node_5.id);
1951
+ if (frame_4) inspector.hover(node_5.id, frame_4, event_11.clientX, event_11.clientY);
1952
+ },
1953
+ onPointerDown: (event_12) => {
1954
+ setSelected(node_5.id);
1955
+ if (inspectMode) {
1956
+ const frame_5 = frames.current.get(node_5.id);
1957
+ if (frame_5) inspector.select(node_5.id, frame_5, event_12.clientX, event_12.clientY);
1958
+ }
1959
+ },
1960
+ onClick: () => setSelected(node_5.id)
1961
+ }),
1962
+ inspectMode && inspector.selection?.pageId === node_5.id && inspector.measurement && /* @__PURE__ */ jsx(CanvasInspectionOverlay, {
1963
+ measurement: inspector.measurement,
1964
+ width: node_5.width
1965
+ })
1966
+ ] }),
1967
+ (redirected || state.warning || state.timedOut) && /* @__PURE__ */ jsxs("div", {
1968
+ className: "povio-canvas-page-note",
1969
+ children: [
1970
+ redirected ? `Rendered ${state.href} (route redirected). ` : "",
1971
+ state.warning,
1972
+ state.timedOut && !state.ready && startup.admitted.has(startupKeys.get(node_5.id) ?? "") ? " Frame bridge has not connected. Check access or page errors." : ""
1973
+ ]
1974
+ })
1975
+ ]
1976
+ }, node_5.id);
1977
+ })
1978
+ }),
1979
+ /* @__PURE__ */ jsxs("div", {
1980
+ className: "povio-canvas-tool-dock",
1981
+ children: [
1982
+ /* @__PURE__ */ jsxs("div", {
1983
+ className: "povio-canvas-mode-switch",
1984
+ role: "group",
1985
+ "aria-label": "Canvas mode",
1986
+ children: [
1987
+ /* @__PURE__ */ jsxs("button", {
1988
+ "aria-label": "Inspect layouts",
1989
+ title: "Inspect layouts",
1990
+ "aria-pressed": inspectMode,
1991
+ onClick: () => {
1992
+ setInteract(false);
1993
+ setInspectMode(true);
1994
+ },
1995
+ children: [/* @__PURE__ */ jsx(ScanLine, { size: 18 }), /* @__PURE__ */ jsx("span", { children: "Inspect" })]
1996
+ }),
1997
+ /* @__PURE__ */ jsxs("button", {
1998
+ "aria-label": "Pan",
1999
+ title: "Pan",
2000
+ "aria-pressed": !inspectMode && !interact,
2001
+ onClick: () => {
2002
+ setInspectMode(false);
2003
+ setInteract(false);
2004
+ },
2005
+ children: [/* @__PURE__ */ jsx(Hand, { size: 18 }), /* @__PURE__ */ jsx("span", { children: "Pan" })]
2006
+ }),
2007
+ /* @__PURE__ */ jsxs("button", {
2008
+ "aria-label": "Interact",
2009
+ title: "Interact with pages",
2010
+ "aria-pressed": interact,
2011
+ onClick: () => {
2012
+ setInspectMode(false);
2013
+ setInteract(true);
2014
+ },
2015
+ children: [/* @__PURE__ */ jsx(MousePointer2, { size: 18 }), /* @__PURE__ */ jsx("span", { children: "Interact" })]
2016
+ })
2017
+ ]
2018
+ }),
2019
+ /* @__PURE__ */ jsx("span", { className: "povio-canvas-dock-divider" }),
2020
+ /* @__PURE__ */ jsxs("button", {
2021
+ "aria-label": "Auto layout",
2022
+ onClick: () => setManifest((m_1) => ({
2023
+ ...m_1,
2024
+ positions: {
2025
+ ...m_1.positions,
2026
+ [bp.id]: {}
2027
+ }
2028
+ })),
2029
+ children: [/* @__PURE__ */ jsx(PanelsTopLeft, { size: 17 }), /* @__PURE__ */ jsx("span", { children: "Auto layout" })]
2030
+ })
2031
+ ]
2032
+ }),
2033
+ /* @__PURE__ */ jsxs("div", {
2034
+ className: "povio-canvas-camera",
2035
+ children: [
2036
+ /* @__PURE__ */ jsx("button", {
2037
+ className: "povio-canvas-configure",
2038
+ "aria-label": "Configure UI",
2039
+ title: "Configure UI",
2040
+ onClick: configuration.openFloating,
2041
+ children: /* @__PURE__ */ jsx(Settings2, { size: 16 })
2042
+ }),
2043
+ /* @__PURE__ */ jsx("button", {
2044
+ className: "povio-canvas-theme-toggle",
2045
+ onClick: () => setDark(!dark),
2046
+ "aria-pressed": dark,
2047
+ "aria-label": dark ? "Dark" : "Light",
2048
+ title: "Toggle page theme",
2049
+ children: dark ? /* @__PURE__ */ jsx(Moon, { size: 16 }) : /* @__PURE__ */ jsx(Sun, { size: 16 })
2050
+ }),
2051
+ /* @__PURE__ */ jsxs("div", {
2052
+ className: "povio-canvas-breakpoint",
2053
+ children: [/* @__PURE__ */ jsx(Monitor, { size: 15 }), /* @__PURE__ */ jsx("select", {
2054
+ "aria-label": "Canvas breakpoint",
2055
+ value: bp.id,
2056
+ onChange: (e) => {
2057
+ if (e.target.value === bp.id) return;
2058
+ setRuntime({});
2059
+ setManifest((m_2) => ({
2060
+ ...m_2,
2061
+ breakpoint: e.target.value
2062
+ }));
2063
+ },
2064
+ children: breakpoints.map((item_1) => /* @__PURE__ */ jsxs("option", {
2065
+ value: item_1.id,
2066
+ children: [
2067
+ item_1.label,
2068
+ " · ",
2069
+ item_1.width,
2070
+ "px"
2071
+ ]
2072
+ }, item_1.id))
2073
+ })]
2074
+ }),
2075
+ /* @__PURE__ */ jsx("span", { className: "povio-canvas-dock-divider" }),
2076
+ /* @__PURE__ */ jsx("button", {
2077
+ onClick: () => stepZoom(-1),
2078
+ "aria-label": "Zoom out",
2079
+ children: "−"
2080
+ }),
2081
+ /* @__PURE__ */ jsx("button", {
2082
+ className: "povio-canvas-zoom-reset",
2083
+ "aria-label": "Zoom to 100%",
2084
+ title: "Zoom to 100%",
2085
+ onClick: () => zoomTo(1),
2086
+ children: /* @__PURE__ */ jsx("output", {
2087
+ ref: zoomOutput,
2088
+ children: "25%"
2089
+ })
2090
+ }),
2091
+ /* @__PURE__ */ jsx("button", {
2092
+ onClick: () => stepZoom(1),
2093
+ "aria-label": "Zoom in",
2094
+ children: "+"
2095
+ }),
2096
+ /* @__PURE__ */ jsx("button", {
2097
+ onClick: fit,
2098
+ children: "Fit all"
2099
+ })
2100
+ ]
2101
+ })
2102
+ ]
2103
+ }),
2104
+ inspectMode && /* @__PURE__ */ jsx(CanvasInspectorPanel, {
2105
+ inspector,
2106
+ onClose: () => setInspectMode(false),
2107
+ onSelectToken: configuration.revealToken
2108
+ })
2109
+ ]
2110
+ }),
2111
+ notice && /* @__PURE__ */ jsxs("div", {
2112
+ className: "povio-canvas-notice",
2113
+ role: "status",
2114
+ children: [notice, /* @__PURE__ */ jsx("button", {
2115
+ onClick: () => setNotice(""),
2116
+ children: "Dismiss"
2117
+ })]
2118
+ })
2119
+ ]
2120
+ });
2121
+ }
2122
+ //#endregion
2123
+ //#region src/app-canvas/document-frame.ts
2124
+ /** Adapt a same-origin document to an uncropped, full-page canvas artboard. */
2125
+ function startCanvasDocument(doc, options) {
2126
+ const win = doc.defaultView;
2127
+ if (!win) throw new Error("Canvas document must belong to a window.");
2128
+ const viewportHeight = Math.max(1, options.viewportHeight);
2129
+ let interact = options.interact ?? false;
2130
+ let destroyed = false;
2131
+ let frame = 0;
2132
+ let lastHeight = 0;
2133
+ let lastLinks = "";
2134
+ const originals = /* @__PURE__ */ new Map();
2135
+ const mediaOriginals = /* @__PURE__ */ new Map();
2136
+ const liveStyles = /* @__PURE__ */ new Set();
2137
+ const liveMedia = /* @__PURE__ */ new Set();
2138
+ const warnedSheets = /* @__PURE__ */ new WeakSet();
2139
+ const positioned = /* @__PURE__ */ new WeakSet();
2140
+ const set = (style, property, value, priority = "important") => {
2141
+ liveStyles.add(style);
2142
+ if (style.getPropertyValue(property) === value && style.getPropertyPriority(property) === priority) return;
2143
+ let saved = originals.get(style);
2144
+ if (!saved) {
2145
+ saved = /* @__PURE__ */ new Map();
2146
+ originals.set(style, saved);
2147
+ }
2148
+ if (!saved.has(property)) saved.set(property, [style.getPropertyValue(property), style.getPropertyPriority(property)]);
2149
+ style.setProperty(property, value, priority);
2150
+ };
2151
+ const freezeUnits = (style) => {
2152
+ liveStyles.add(style);
2153
+ for (const property of Array.from(style)) {
2154
+ const value = style.getPropertyValue(property);
2155
+ const frozen = value.replace(/(-?(?:\d*\.)?\d+)(?:dvh|svh|lvh|vh)\b/gi, (_, amount) => `${Number(amount) * viewportHeight / 100}px`);
2156
+ if (value !== frozen) set(style, property, frozen, style.getPropertyPriority(property));
2157
+ }
2158
+ };
2159
+ const freezeMedia = (media) => {
2160
+ liveMedia.add(media);
2161
+ if (mediaOriginals.has(media)) return;
2162
+ const original = media.mediaText;
2163
+ const frozen = original.replace(/\([^()]*\b(?:height|orientation|aspect-ratio)\b[^()]*\)/gi, (predicate) => win.matchMedia(predicate).matches ? "(min-width: 0px)" : "(max-width: -1px)");
2164
+ if (frozen !== original) {
2165
+ mediaOriginals.set(media, original);
2166
+ media.mediaText = frozen;
2167
+ }
2168
+ };
2169
+ const visitRules = (rules) => {
2170
+ for (const rule of Array.from(rules)) {
2171
+ if ("style" in rule) freezeUnits(rule.style);
2172
+ if ("media" in rule) freezeMedia(rule.media);
2173
+ if ("cssRules" in rule) visitRules(rule.cssRules);
2174
+ if ("styleSheet" in rule && rule.styleSheet) visitSheet(rule.styleSheet);
2175
+ }
2176
+ };
2177
+ const visitSheet = (sheet) => {
2178
+ try {
2179
+ freezeMedia(sheet.media);
2180
+ visitRules(sheet.cssRules);
2181
+ } catch {
2182
+ if (!warnedSheets.has(sheet)) {
2183
+ warnedSheets.add(sheet);
2184
+ const message = `App canvas cannot normalize inaccessible stylesheet ${sheet.href ?? "(inline)"}. Serve its CSS from the app origin for accurate full-page dimensions.`;
2185
+ if (options.onWarning) options.onWarning(message);
2186
+ else win.console.warn(message);
2187
+ }
2188
+ }
2189
+ };
2190
+ const anchorURL = (anchor) => {
2191
+ try {
2192
+ const url = new URL(anchor.getAttribute("href") ?? "", doc.baseURI);
2193
+ return /^https?:$/.test(url.protocol) && url.origin === new URL(doc.baseURI).origin ? url.href : null;
2194
+ } catch {
2195
+ return null;
2196
+ }
2197
+ };
2198
+ const refresh = () => {
2199
+ if (destroyed) return;
2200
+ if (frame) {
2201
+ win.cancelAnimationFrame(frame);
2202
+ frame = 0;
2203
+ }
2204
+ observer.disconnect();
2205
+ liveStyles.clear();
2206
+ liveMedia.clear();
2207
+ for (const sheet of [...Array.from(doc.styleSheets), ...Array.from(doc.adoptedStyleSheets ?? [])]) visitSheet(sheet);
2208
+ const elements = Array.from(doc.querySelectorAll("*")).filter((el) => "style" in el);
2209
+ for (const el of elements) freezeUnits(el.style);
2210
+ const snapshots = elements.map((el) => ({
2211
+ el,
2212
+ css: win.getComputedStyle(el),
2213
+ rect: el.getBoundingClientRect()
2214
+ }));
2215
+ for (const { el, css, rect } of snapshots) {
2216
+ if (!positioned.has(el) && (css.position === "fixed" || css.position === "sticky")) {
2217
+ positioned.add(el);
2218
+ if (css.position === "sticky") set(el.style, "position", "static");
2219
+ else {
2220
+ set(el.style, "position", "absolute");
2221
+ const containingBlock = el.offsetParent;
2222
+ const parentRect = containingBlock?.getBoundingClientRect();
2223
+ const parentTop = containingBlock && containingBlock !== doc.body && containingBlock !== doc.documentElement ? (parentRect?.top ?? 0) + containingBlock.clientTop - containingBlock.scrollTop : -win.scrollY;
2224
+ const parentLeft = containingBlock && containingBlock !== doc.body && containingBlock !== doc.documentElement ? (parentRect?.left ?? 0) + containingBlock.clientLeft - containingBlock.scrollLeft : -win.scrollX;
2225
+ set(el.style, "top", `${rect.top - parentTop}px`);
2226
+ set(el.style, "left", `${rect.left - parentLeft}px`);
2227
+ set(el.style, "right", "auto");
2228
+ set(el.style, "bottom", "auto");
2229
+ set(el.style, "width", `${rect.width}px`);
2230
+ set(el.style, "height", `${rect.height}px`);
2231
+ }
2232
+ }
2233
+ if (/^(auto|scroll)$/.test(css.overflowY) && el.scrollHeight > el.clientHeight) {
2234
+ let ancestor = el;
2235
+ while (ancestor && ancestor !== doc.documentElement) {
2236
+ set(ancestor.style, "height", "auto");
2237
+ set(ancestor.style, "max-height", "none");
2238
+ set(ancestor.style, "overflow-y", "visible");
2239
+ set(ancestor.style, "flex-shrink", "0");
2240
+ ancestor = ancestor.parentElement;
2241
+ }
2242
+ }
2243
+ }
2244
+ set(doc.documentElement.style, "height", "auto");
2245
+ set(doc.documentElement.style, "min-height", "0px");
2246
+ set(doc.documentElement.style, "overflow-y", "hidden");
2247
+ if (doc.body) {
2248
+ set(doc.body.style, "height", "auto");
2249
+ set(doc.body.style, "min-height", "0px");
2250
+ }
2251
+ let bottom = 0;
2252
+ for (const el of elements) {
2253
+ if (el === doc.documentElement || el === doc.body || !el.getClientRects().length) continue;
2254
+ bottom = Math.max(bottom, el.getBoundingClientRect().bottom + win.scrollY);
2255
+ }
2256
+ if (doc.body) bottom = Math.max(bottom, doc.body.getBoundingClientRect().bottom + win.scrollY);
2257
+ const height = Math.max(viewportHeight, Math.ceil(bottom));
2258
+ if (height !== lastHeight) {
2259
+ lastHeight = height;
2260
+ options.onHeight(height);
2261
+ }
2262
+ if (options.onLinks) {
2263
+ const links = Array.from(doc.querySelectorAll("a[href]")).flatMap((anchor) => {
2264
+ const href = anchorURL(anchor);
2265
+ return href ? [{
2266
+ href,
2267
+ label: anchor.textContent?.trim() || anchor.getAttribute("aria-label") || href
2268
+ }] : [];
2269
+ });
2270
+ const signature = JSON.stringify(links);
2271
+ if (signature !== lastLinks) {
2272
+ lastLinks = signature;
2273
+ options.onLinks(links);
2274
+ }
2275
+ }
2276
+ for (const style of originals.keys()) if (!liveStyles.has(style)) originals.delete(style);
2277
+ for (const media of mediaOriginals.keys()) if (!liveMedia.has(media)) mediaOriginals.delete(media);
2278
+ liveStyles.clear();
2279
+ liveMedia.clear();
2280
+ observer.observe(doc.documentElement, {
2281
+ subtree: true,
2282
+ childList: true,
2283
+ attributes: true,
2284
+ characterData: true
2285
+ });
2286
+ };
2287
+ const schedule = () => {
2288
+ if (!destroyed && !frame) frame = win.requestAnimationFrame(refresh);
2289
+ };
2290
+ const observer = new win.MutationObserver(schedule);
2291
+ const resize = new win.ResizeObserver(schedule);
2292
+ resize.observe(doc.documentElement);
2293
+ if (doc.body) resize.observe(doc.body);
2294
+ const click = (event) => {
2295
+ const anchor = event.target?.closest?.("a[href]");
2296
+ if (interact && !anchor) return;
2297
+ event.preventDefault();
2298
+ event.stopImmediatePropagation();
2299
+ if (anchor) {
2300
+ const href = anchorURL(anchor);
2301
+ if (href) options.onNavigate(href);
2302
+ }
2303
+ };
2304
+ const submit = (event) => {
2305
+ if (!interact) {
2306
+ event.preventDefault();
2307
+ event.stopImmediatePropagation();
2308
+ }
2309
+ };
2310
+ win.addEventListener("click", click, true);
2311
+ win.addEventListener("submit", submit, true);
2312
+ win.addEventListener("resize", schedule);
2313
+ doc.addEventListener("load", schedule, true);
2314
+ doc.fonts?.ready.then(schedule);
2315
+ refresh();
2316
+ return {
2317
+ refresh,
2318
+ setInteract(value) {
2319
+ interact = value;
2320
+ },
2321
+ destroy() {
2322
+ destroyed = true;
2323
+ if (frame) win.cancelAnimationFrame(frame);
2324
+ observer.disconnect();
2325
+ resize.disconnect();
2326
+ win.removeEventListener("click", click, true);
2327
+ win.removeEventListener("submit", submit, true);
2328
+ win.removeEventListener("resize", schedule);
2329
+ doc.removeEventListener("load", schedule, true);
2330
+ for (const [media, value] of mediaOriginals) media.mediaText = value;
2331
+ for (const [style, values] of originals) for (const [property, [value, priority]] of values) if (value) style.setProperty(property, value, priority);
2332
+ else style.removeProperty(property);
2333
+ }
2334
+ };
2335
+ }
2336
+ //#endregion
2337
+ //#region src/app-canvas/AppCanvasFrameBridge.tsx
2338
+ /** Mount once inside the application's existing UIConfigurationProvider. No separate app copy or theme fork. */
2339
+ function AppCanvasFrameBridge({ href }) {
2340
+ const { setPreviewConfiguration } = useUIConfiguration();
2341
+ const [identity] = useState(canvasFrameIdentity);
2342
+ const currentHref = useRef(href);
2343
+ currentHref.current = href;
2344
+ useEffect(() => {
2345
+ if (!identity) return;
2346
+ const send = (data) => window.parent.postMessage({
2347
+ protocol: canvasProtocol,
2348
+ ...identity,
2349
+ ...data
2350
+ }, window.location.origin);
2351
+ const renderer = startCanvasDocument(document, {
2352
+ viewportHeight: identity.viewportHeight,
2353
+ onHeight: (height) => send({
2354
+ type: "height",
2355
+ height
2356
+ }),
2357
+ onNavigate: (url) => send({
2358
+ type: "navigate",
2359
+ href: url
2360
+ }),
2361
+ onWarning: (warning) => send({
2362
+ type: "warning",
2363
+ warning
2364
+ })
2365
+ });
2366
+ let ackFrame = 0;
2367
+ const receive = (event) => {
2368
+ const packet = event.data;
2369
+ if (event.source !== window.parent || event.origin !== window.location.origin || packet?.protocol !== "povio-app-canvas-v1" || packet.token !== identity.token || packet.id !== identity.id) return;
2370
+ if (packet.type === "mode") renderer.setInteract(!!packet.interact);
2371
+ if (packet.type === "configuration" && validConfiguration(packet.configuration)) {
2372
+ setPreviewConfiguration(packet.configuration);
2373
+ document.documentElement.classList.toggle("dark", !!packet.dark);
2374
+ cancelAnimationFrame(ackFrame);
2375
+ ackFrame = requestAnimationFrame(() => {
2376
+ send({
2377
+ type: "ack",
2378
+ revision: packet.revision
2379
+ });
2380
+ });
2381
+ }
2382
+ };
2383
+ window.addEventListener("message", receive);
2384
+ send({
2385
+ type: "ready",
2386
+ href: currentHref.current ?? window.location.href
2387
+ });
2388
+ return () => {
2389
+ cancelAnimationFrame(ackFrame);
2390
+ window.removeEventListener("message", receive);
2391
+ renderer.destroy();
2392
+ setPreviewConfiguration(null);
2393
+ };
2394
+ }, [identity, setPreviewConfiguration]);
2395
+ useEffect(() => {
2396
+ if (identity && href) window.parent.postMessage({
2397
+ protocol: canvasProtocol,
2398
+ ...identity,
2399
+ type: "ready",
2400
+ href
2401
+ }, window.location.origin);
2402
+ }, [href, identity]);
2403
+ return null;
2404
+ }
2405
+ //#endregion
2406
+ //#region src/app-canvas/AppCanvasPage.tsx
2407
+ const APP_CANVAS_PATH = "/_canvas";
2408
+ /** Must match `componentsFrameParam`; kept inline so the canvas page does not load the gallery eagerly. */
2409
+ const componentsParam = "povio-components";
2410
+ const CanvasComponentsFrame = lazy(() => import("./CanvasComponentsFrame-C0Sf9RcC.js"));
2411
+ /** Ready-made route page. Mount beneath the app's UIConfigurationProvider. */
2412
+ function AppCanvasPage(t0) {
2413
+ const $ = c(21);
2414
+ let excludePaths;
2415
+ let props;
2416
+ let t1;
2417
+ if ($[0] !== t0) {
2418
+ ({canvasPath: t1, excludePaths, ...props} = t0);
2419
+ $[0] = t0;
2420
+ $[1] = excludePaths;
2421
+ $[2] = props;
2422
+ $[3] = t1;
2423
+ } else {
2424
+ excludePaths = $[1];
2425
+ props = $[2];
2426
+ t1 = $[3];
2427
+ }
2428
+ const canvasPath = t1 === void 0 ? APP_CANVAS_PATH : t1;
2429
+ let t2;
2430
+ if ($[4] !== excludePaths) {
2431
+ t2 = excludePaths ?? [];
2432
+ $[4] = excludePaths;
2433
+ $[5] = t2;
2434
+ } else t2 = $[5];
2435
+ let t3;
2436
+ if ($[6] !== canvasPath || $[7] !== t2) {
2437
+ t3 = /* @__PURE__ */ new Set([...t2, canvasPath]);
2438
+ $[6] = canvasPath;
2439
+ $[7] = t2;
2440
+ $[8] = t3;
2441
+ } else t3 = $[8];
2442
+ let t4;
2443
+ if ($[9] !== t3) {
2444
+ t4 = [...t3];
2445
+ $[9] = t3;
2446
+ $[10] = t4;
2447
+ } else t4 = $[10];
2448
+ const exclusions = t4;
2449
+ if (isAppCanvasFrame()) {
2450
+ let t5;
2451
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
2452
+ const group = new URLSearchParams(window.location.search).get(componentsParam);
2453
+ t5 = group ? /* @__PURE__ */ jsx(Suspense, {
2454
+ fallback: null,
2455
+ children: /* @__PURE__ */ jsx(CanvasComponentsFrame, { group })
2456
+ }) : null;
2457
+ $[11] = t5;
2458
+ } else t5 = $[11];
2459
+ return t5;
2460
+ }
2461
+ let t5;
2462
+ if ($[12] !== canvasPath) {
2463
+ t5 = (group_0) => `${canvasPath}?${componentsParam}=${encodeURIComponent(group_0)}`;
2464
+ $[12] = canvasPath;
2465
+ $[13] = t5;
2466
+ } else t5 = $[13];
2467
+ let t6;
2468
+ if ($[14] !== exclusions || $[15] !== props || $[16] !== t5) {
2469
+ t6 = /* @__PURE__ */ jsx(AppCanvas, {
2470
+ ...props,
2471
+ excludePaths: exclusions,
2472
+ componentsHref: t5
2473
+ });
2474
+ $[14] = exclusions;
2475
+ $[15] = props;
2476
+ $[16] = t5;
2477
+ $[17] = t6;
2478
+ } else t6 = $[17];
2479
+ let t7;
2480
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
2481
+ t7 = /* @__PURE__ */ jsx(UIConfigurationModal, {});
2482
+ $[18] = t7;
2483
+ } else t7 = $[18];
2484
+ let t8;
2485
+ if ($[19] !== t6) {
2486
+ t8 = /* @__PURE__ */ jsxs("div", {
2487
+ className: "povio-app-canvas-page",
2488
+ "aria-label": "App canvas page",
2489
+ children: [t6, t7]
2490
+ });
2491
+ $[19] = t6;
2492
+ $[20] = t8;
2493
+ } else t8 = $[20];
2494
+ return t8;
2495
+ }
2496
+ //#endregion
2497
+ export { defaultCanvasBreakpoints as a, layoutCanvasPages as c, AppCanvas as i, AppCanvasPage as n, isAppCanvasFrame as o, AppCanvasFrameBridge as r, discoverCanvasPages as s, APP_CANVAS_PATH as t };