@crewlethq/ui 0.31.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +151 -5
  2. package/dist/AccessDeniedCard/AccessDeniedCard.d.ts +5 -0
  3. package/dist/AccessDeniedCard/index.js +1 -5
  4. package/dist/AccessDeniedCard-QVNDMT46.css +8 -0
  5. package/dist/AppShell/index.js +4 -4
  6. package/dist/{AppShell-GCM4TDVY.css → AppShell-JTSEOA57.css} +3 -1
  7. package/dist/ArrangeGroup/ArrangeGroup.d.ts +16 -1
  8. package/dist/ArrangeGroup/index.d.ts +1 -1
  9. package/dist/ArrangeGroup/index.js +1 -1
  10. package/dist/{ArrangeGroup-GY5YMP6E.css → ArrangeGroup-KRWWOJKR.css} +43 -0
  11. package/dist/ArrangeList/index.js +2 -2
  12. package/dist/ArtifactBar/index.js +12 -12
  13. package/dist/{ArtifactBar-MLMJHWY6.css → ArtifactBar-C462VD4C.css} +8 -3
  14. package/dist/ArtifactCard/ArtifactCard.d.ts +19 -1
  15. package/dist/ArtifactCard/index.d.ts +1 -1
  16. package/dist/ArtifactCard/index.js +4 -4
  17. package/dist/{ArtifactCard-EXVAEBV6.css → ArtifactCard-AS5Z4CVI.css} +17 -2
  18. package/dist/ArtifactCover/index.js +6 -6
  19. package/dist/ArtifactIcon/index.js +5 -5
  20. package/dist/ArtifactPanel/ArtifactPanel.d.ts +6 -2
  21. package/dist/ArtifactPanel/index.js +1 -1
  22. package/dist/{ArtifactPanel-YFXT5O77.css → ArtifactPanel-HW3SU7CP.css} +25 -7
  23. package/dist/Avatar/Avatar.d.ts +6 -4
  24. package/dist/Avatar/index.js +2 -2
  25. package/dist/AvatarPicker/index.js +8 -8
  26. package/dist/Callout/index.js +1 -1
  27. package/dist/{Callout-SXXK4B5R.css → Callout-ZAVG3P66.css} +46 -6
  28. package/dist/Canvas/Canvas.d.ts +81 -4
  29. package/dist/Canvas/ShortcutTip.d.ts +22 -0
  30. package/dist/Canvas/geometry.d.ts +13 -3
  31. package/dist/Canvas/index.d.ts +4 -2
  32. package/dist/Canvas/index.js +5 -3
  33. package/dist/{Canvas-YVXHMWLN.css → Canvas-VUG2HLZK.css} +62 -3
  34. package/dist/CanvasBoard/CanvasBoard.d.ts +110 -12
  35. package/dist/CanvasBoard/budget.d.ts +9 -3
  36. package/dist/CanvasBoard/index.d.ts +2 -2
  37. package/dist/CanvasBoard/index.js +9 -5
  38. package/dist/CanvasBoard-5NNSKY6A.css +462 -0
  39. package/dist/CanvasToolbar/CanvasToolbar.d.ts +48 -0
  40. package/dist/CanvasToolbar/index.d.ts +3 -0
  41. package/dist/CanvasToolbar/index.js +12 -0
  42. package/dist/CanvasToolbar-EM5EVZED.css +34 -0
  43. package/dist/ChangeMark/index.js +4 -4
  44. package/dist/CharacterPicker/index.js +2 -2
  45. package/dist/Charts/ActivityStrip.d.ts +16 -1
  46. package/dist/Charts/BarList.d.ts +6 -0
  47. package/dist/Charts/ChartEmpty.d.ts +33 -0
  48. package/dist/Charts/Legend.d.ts +6 -0
  49. package/dist/Charts/StackedBar.d.ts +4 -1
  50. package/dist/Charts/StackedColumns.d.ts +14 -3
  51. package/dist/Charts/TimeSeries.d.ts +11 -1
  52. package/dist/Charts/index.d.ts +2 -0
  53. package/dist/Charts/index.js +1 -1
  54. package/dist/{Charts-RY4JN5FC.css → Charts-MBJG72BS.css} +140 -16
  55. package/dist/Checkbox/index.js +1 -1
  56. package/dist/{Checkbox-5UORUG3F.css → Checkbox-ALWG3WV2.css} +11 -0
  57. package/dist/CommandPalette/index.js +3 -3
  58. package/dist/{CommandPalette-HBTNKHZQ.css → CommandPalette-7CFGVBND.css} +4 -0
  59. package/dist/CommentThread/index.js +5 -5
  60. package/dist/Container/index.js +1 -1
  61. package/dist/{Container-3TSKMGNI.css → Container-34BAKG7B.css} +3 -1
  62. package/dist/{DashboardCover-RMINBODB.css → DashboardCover-KYGYMRKW.css} +42 -9
  63. package/dist/DataTable/index.js +5 -5
  64. package/dist/{DataTable-WZK3V62B.css → DataTable-NL2YWAIA.css} +4 -1
  65. package/dist/DataView/index.js +9 -9
  66. package/dist/DateTimePicker/index.js +3 -3
  67. package/dist/DocTabsEditor/DocTabsEditor.d.ts +34 -21
  68. package/dist/DocTabsEditor/index.js +4 -1
  69. package/dist/DocTabsEditor-4M452LNS.css +189 -0
  70. package/dist/Document/Document.d.ts +18 -1
  71. package/dist/Document/index.d.ts +2 -2
  72. package/dist/Document/index.js +1 -1
  73. package/dist/{Document-G3YTZIUL.css → Document-JUGCSQ4L.css} +78 -5
  74. package/dist/EditingStatus/index.js +1 -1
  75. package/dist/{EditingStatus-L6THUAN7.css → EditingStatus-NNA2CKIL.css} +17 -4
  76. package/dist/{Editor-YZ7KG2RD.js → Editor-UUZ7XKCU.js} +5 -5
  77. package/dist/EntityChip/index.js +3 -3
  78. package/dist/FactList/index.js +3 -3
  79. package/dist/FollowBanner/index.js +3 -3
  80. package/dist/Fullscreen/index.d.ts +1 -0
  81. package/dist/Fullscreen/index.js +1 -1
  82. package/dist/Fullscreen/useIdle.d.ts +16 -0
  83. package/dist/HuePicker/index.js +3 -3
  84. package/dist/ImageUpload/index.js +3 -3
  85. package/dist/Layer/index.d.ts +1 -1
  86. package/dist/Layer/index.js +1 -1
  87. package/dist/Layer/place.d.ts +18 -0
  88. package/dist/LayersList/LayersList.d.ts +57 -0
  89. package/dist/LayersList/index.d.ts +3 -0
  90. package/dist/LayersList/index.js +3 -0
  91. package/dist/LayersList-NQZEIPZB.css +82 -0
  92. package/dist/LinkInterstitial/index.js +4 -4
  93. package/dist/ListInput/index.js +1 -1
  94. package/dist/Markdown/index.js +1 -1
  95. package/dist/MarkdownEditor/index.js +5 -5
  96. package/dist/MediaMatch/index.d.ts +1 -0
  97. package/dist/MediaMatch/index.js +1 -0
  98. package/dist/MediaMatch/useMediaMatch.d.ts +19 -0
  99. package/dist/Menu/index.js +2 -2
  100. package/dist/MergeConflicts/index.js +4 -4
  101. package/dist/Modal/index.js +2 -2
  102. package/dist/{Modal-XOSV6FAH.css → Modal-7MWRCWAI.css} +30 -0
  103. package/dist/Note/index.js +1 -1
  104. package/dist/{Note-ONSKKTOA.css → Note-WI5MLZOO.css} +13 -0
  105. package/dist/OrgLabel/index.js +3 -3
  106. package/dist/OrgNode/index.js +4 -4
  107. package/dist/OrgTable/index.js +7 -7
  108. package/dist/PeopleRail/index.js +3 -3
  109. package/dist/Popover/index.js +2 -2
  110. package/dist/PresenceStack/index.js +3 -3
  111. package/dist/{PresenceStack-QSXQJND5.css → PresenceStack-FJJQVH74.css} +11 -3
  112. package/dist/PresenterView/PresenterView.d.ts +3 -0
  113. package/dist/PresenterView/index.js +5 -3
  114. package/dist/PresenterView-T3EXIQ5S.css +147 -0
  115. package/dist/Principal/index.js +3 -3
  116. package/dist/PrincipalPicker/index.js +4 -4
  117. package/dist/RichEditor/index.js +5 -5
  118. package/dist/RichEditor/schema.d.ts +1 -1
  119. package/dist/RichEditorMarkdown/index.js +3 -3
  120. package/dist/SandboxedFrame/SandboxedFrame.d.ts +44 -2
  121. package/dist/SandboxedFrame/index.d.ts +2 -2
  122. package/dist/SandboxedFrame/index.js +3 -3
  123. package/dist/SandboxedFrame-P5NASXB7.css +72 -0
  124. package/dist/Section/index.js +1 -1
  125. package/dist/{Section-QR3ILQVK.css → Section-O5AHGSOG.css} +28 -5
  126. package/dist/SegmentedControl/index.js +3 -3
  127. package/dist/Select/index.js +2 -2
  128. package/dist/ShareDialog/ShareDialog.d.ts +10 -0
  129. package/dist/ShareDialog/index.js +9 -9
  130. package/dist/{ShareDialog-YZ4F37MW.css → ShareDialog-4QDCBWMH.css} +12 -0
  131. package/dist/SheetGrid/SheetGrid.d.ts +3 -1
  132. package/dist/SheetGrid/index.js +10 -10
  133. package/dist/{SheetGrid-J3TKKXZL.css → SheetGrid-AKPUCK67.css} +106 -7
  134. package/dist/SheetModel/fit.d.ts +34 -0
  135. package/dist/SheetModel/index.d.ts +1 -0
  136. package/dist/SheetModel/index.js +1 -1
  137. package/dist/Shortcut/index.js +1 -1
  138. package/dist/Skeleton/Skeleton.d.ts +2 -1
  139. package/dist/Skeleton/index.js +1 -1
  140. package/dist/SlideCompare/SlideCompare.d.ts +6 -1
  141. package/dist/SlideCompare/index.js +3 -3
  142. package/dist/{SlideCompare-MGM3U2ME.css → SlideCompare-HTCMPQFY.css} +36 -3
  143. package/dist/SlideFilmstrip/SlideFilmstrip.d.ts +14 -3
  144. package/dist/SlideFilmstrip/index.js +3 -3
  145. package/dist/{SlideFilmstrip-BCLNAHFX.css → SlideFilmstrip-5U6Z55GS.css} +63 -2
  146. package/dist/SlideGrid/index.js +3 -3
  147. package/dist/{SlideGrid-RT6QEQEE.css → SlideGrid-S4LTJ4UU.css} +9 -5
  148. package/dist/SlideNav/SlideNav.d.ts +49 -0
  149. package/dist/SlideNav/index.d.ts +3 -0
  150. package/dist/SlideNav/index.js +4 -0
  151. package/dist/SlideNav-BLFJF6AH.css +53 -0
  152. package/dist/SlideStage/SlideStage.d.ts +14 -1
  153. package/dist/SlideStage/index.js +2 -2
  154. package/dist/{SlideStage-KGRRALXR.css → SlideStage-S2FISF4C.css} +23 -0
  155. package/dist/StatCard/StatCard.d.ts +16 -1
  156. package/dist/StatCard/index.js +1 -1
  157. package/dist/{StatCard-KPAFD4E2.css → StatCard-4T7TMWMN.css} +40 -13
  158. package/dist/Switcher/index.js +6 -6
  159. package/dist/TableCells/index.js +3 -3
  160. package/dist/Tabs/Tabs.d.ts +21 -4
  161. package/dist/Tabs/index.js +1 -1
  162. package/dist/{Tabs-CJGO35BH.css → Tabs-MMZXV5EF.css} +9 -8
  163. package/dist/TagsInput/index.js +1 -1
  164. package/dist/ThemeSwitcher/index.js +4 -4
  165. package/dist/TimeWindowPicker/index.js +4 -4
  166. package/dist/Toaster/index.js +2 -2
  167. package/dist/{Toaster-EOOOTSJT.css → Toaster-C6BQ7L6I.css} +10 -1
  168. package/dist/Toolbar/index.js +1 -1
  169. package/dist/Tooltip/index.js +2 -2
  170. package/dist/TreeCanvas/index.js +6 -4
  171. package/dist/TreeGrid/index.js +3 -3
  172. package/dist/VersionCompare/index.js +4 -4
  173. package/dist/VersionTimeline/index.js +4 -4
  174. package/dist/WidgetFrame/WidgetFrame.d.ts +8 -1
  175. package/dist/WidgetFrame/index.js +2 -2
  176. package/dist/{WidgetFrame-LRZIL62O.css → WidgetFrame-BTFW3CRK.css} +49 -5
  177. package/dist/{chunk-OJ45PPCV.js → chunk-22UEIXZE.js} +127 -32
  178. package/dist/{chunk-UZ6MA2V6.js → chunk-2DHMVB5J.js} +2 -2
  179. package/dist/{chunk-WJDQ7XQA.js → chunk-2QEDJSJC.js} +1 -1
  180. package/dist/{chunk-2HIOJ4YZ.js → chunk-3EB2AV3H.js} +2 -3
  181. package/dist/{chunk-ODT5H4MN.js → chunk-3LYWD3BO.js} +2 -2
  182. package/dist/{chunk-FAQGGX2Z.js → chunk-3TFDQLW3.js} +1 -1
  183. package/dist/{chunk-VYDFB6PJ.js → chunk-3U7S6ZUN.js} +50 -17
  184. package/dist/{chunk-A4E5YLXO.js → chunk-4B6LSFDS.js} +1 -1
  185. package/dist/{chunk-S6VG5ZFZ.js → chunk-4IJS5CPF.js} +1 -1
  186. package/dist/{chunk-UAN5NE7M.js → chunk-5AQBPHZD.js} +1 -1
  187. package/dist/{chunk-QWOPX2MN.js → chunk-5FYPE5GL.js} +2 -3
  188. package/dist/{chunk-CJKMURZO.js → chunk-5SZGKSGL.js} +1 -1
  189. package/dist/chunk-6VOS2GMB.js +54 -0
  190. package/dist/{chunk-RODMM35O.js → chunk-7Q7WDXHG.js} +5 -5
  191. package/dist/{chunk-JI5AVQLA.js → chunk-7WHDPLVJ.js} +1 -1
  192. package/dist/{chunk-QH3AKP2N.js → chunk-AC22RZKC.js} +2 -2
  193. package/dist/{chunk-ZITJKF6Z.js → chunk-AYB6AYNH.js} +1 -1
  194. package/dist/{chunk-Y5NQ2LMS.js → chunk-BY4N65PM.js} +1 -1
  195. package/dist/{chunk-YFW4MTK4.js → chunk-C7DKX453.js} +1 -1
  196. package/dist/{chunk-RCQXUT5K.js → chunk-CCAXYHQS.js} +1 -1
  197. package/dist/{chunk-4KP4RC3O.js → chunk-CI3VPIJN.js} +1 -1
  198. package/dist/{chunk-7T42VQQT.js → chunk-CPEPST4S.js} +1 -1
  199. package/dist/{chunk-AAOH2P6Y.js → chunk-DFK5EQTU.js} +5 -3
  200. package/dist/{chunk-GOSQXEZU.js → chunk-DFZMYB5X.js} +16 -10
  201. package/dist/{chunk-TGYDROIB.js → chunk-EBCHVFCS.js} +4 -4
  202. package/dist/{chunk-YDBC4DNW.js → chunk-FWYHRU7M.js} +1 -1
  203. package/dist/{chunk-CT4EZF62.js → chunk-G4ZW7A2W.js} +125 -33
  204. package/dist/chunk-GLSOD5Z4.js +33 -0
  205. package/dist/{chunk-LIXSV5YI.js → chunk-GPHWCK7M.js} +1 -1
  206. package/dist/{chunk-UQHKFF2N.js → chunk-GPWJCP3U.js} +1 -1
  207. package/dist/{chunk-77DRMDXR.js → chunk-HG5VF3TZ.js} +192 -67
  208. package/dist/{chunk-4JUKWWUD.js → chunk-HH2GKAAE.js} +1 -1
  209. package/dist/{chunk-QVE4GJAT.js → chunk-HJO4WCH6.js} +1 -1
  210. package/dist/{chunk-I3BSQUKN.js → chunk-HUVG2FFT.js} +1 -1
  211. package/dist/{chunk-3C3BRIMY.js → chunk-ILAEBSLJ.js} +3 -3
  212. package/dist/{chunk-GR55WT4R.js → chunk-IYO2N5ZH.js} +2 -2
  213. package/dist/{chunk-RWA4H2TV.js → chunk-J6ON5SYE.js} +1 -1
  214. package/dist/{chunk-NHBP2XS5.js → chunk-J6ZSH3F5.js} +49 -1
  215. package/dist/{chunk-AMNN4WDX.js → chunk-JBUMD6DS.js} +2 -2
  216. package/dist/{chunk-BWRGFKJP.js → chunk-K3IJQNB7.js} +2 -3
  217. package/dist/{chunk-LFNUH4GY.js → chunk-K4VP6ZKE.js} +1 -1
  218. package/dist/{chunk-ZR5VN5IV.js → chunk-KD2IRYCT.js} +2 -2
  219. package/dist/{chunk-SKOYC2CF.js → chunk-KK5OYNAF.js} +2 -1
  220. package/dist/{chunk-UB7TJEKZ.js → chunk-KV3ODJXH.js} +6 -7
  221. package/dist/chunk-LL5AFXU7.js +96 -0
  222. package/dist/{chunk-VYOKRN2I.js → chunk-LM3ISVJA.js} +1 -1
  223. package/dist/{chunk-O63MWA4G.js → chunk-LV4APO72.js} +10 -3
  224. package/dist/{chunk-B4EBHPK3.js → chunk-M5KZX5JE.js} +9 -2
  225. package/dist/{chunk-JODJS7MR.js → chunk-MDNVHIB2.js} +276 -47
  226. package/dist/{chunk-VOX3YRFO.js → chunk-MTMKIUWF.js} +4 -4
  227. package/dist/{chunk-HVNTQ36V.js → chunk-O37AQNLK.js} +4 -4
  228. package/dist/{chunk-HMPFGIWM.js → chunk-OMV5W53A.js} +10 -1
  229. package/dist/chunk-ONL54WMH.js +55 -0
  230. package/dist/{chunk-AKEZ3G5V.js → chunk-ONQKKHON.js} +1 -1
  231. package/dist/{chunk-LZHLSQYK.js → chunk-OOWPSBIS.js} +2 -2
  232. package/dist/{chunk-JQLTG4KH.js → chunk-ORT5IKHP.js} +62 -51
  233. package/dist/{chunk-4KWOKX2B.js → chunk-OSKJZNBT.js} +1 -1
  234. package/dist/{chunk-EHQTPVV4.js → chunk-PLTCDSTU.js} +1 -1
  235. package/dist/{chunk-5OM447RW.js → chunk-PZKHBB7D.js} +1 -1
  236. package/dist/{chunk-VEB5ERRE.js → chunk-QWNVSR6G.js} +2 -2
  237. package/dist/{chunk-IG75YMUN.js → chunk-RTPQDNW3.js} +1 -1
  238. package/dist/{chunk-SVSCLHHI.js → chunk-SZZRIHGT.js} +1 -1
  239. package/dist/{chunk-EBNI36UQ.js → chunk-T46NR3WP.js} +3 -3
  240. package/dist/{chunk-FPS3JIPQ.js → chunk-TC7DJTXI.js} +1 -1
  241. package/dist/{chunk-W5J7R5EB.js → chunk-TEUQWOWZ.js} +1 -1
  242. package/dist/chunk-THROPJZC.js +115 -0
  243. package/dist/{chunk-IDBHX5SR.js → chunk-TRQCHF2F.js} +1 -1
  244. package/dist/{chunk-M3LUNN7F.js → chunk-TYKQ33CL.js} +13 -2
  245. package/dist/{chunk-VVRL27HM.js → chunk-ULPL26BU.js} +2 -2
  246. package/dist/{chunk-6AH2XJ3Q.js → chunk-UNXLTJU7.js} +3 -3
  247. package/dist/{chunk-FC4YTTFJ.js → chunk-UQGFHNDI.js} +2 -3
  248. package/dist/{chunk-EBJREOKS.js → chunk-UXXJDIYE.js} +4 -4
  249. package/dist/{chunk-5LUI3WQP.js → chunk-V43UVX4H.js} +1 -1
  250. package/dist/{chunk-W4XYY73O.js → chunk-VHZ3AXJD.js} +1 -1
  251. package/dist/{chunk-HJEVSQN6.js → chunk-VL6CUNSX.js} +11 -5
  252. package/dist/{chunk-XDTYBF2F.js → chunk-W5XCNEZC.js} +39 -1
  253. package/dist/{chunk-LDJ3J4TQ.js → chunk-WGD2HX2A.js} +1 -1
  254. package/dist/{chunk-FQCLKD7U.js → chunk-WKEPORNM.js} +1 -1
  255. package/dist/{chunk-I3KKZ2O3.js → chunk-XEGZHHRH.js} +45 -36
  256. package/dist/{chunk-IKB6HFGK.js → chunk-XO7PUL4F.js} +6 -4
  257. package/dist/chunk-XV32RKQZ.js +142 -0
  258. package/dist/{chunk-TBMDMXEX.js → chunk-YA3AWELW.js} +1 -1
  259. package/dist/{chunk-HVIX5ECM.js → chunk-YEVG2X5R.js} +1 -1
  260. package/dist/chunk-YZFLH463.js +215 -0
  261. package/dist/{chunk-P4BOXB6E.js → chunk-Z6GFMI2Z.js} +6 -7
  262. package/dist/{chunk-YEKYVJQR.js → chunk-ZNBLFCQS.js} +2 -2
  263. package/dist/generated/index.d.ts +4 -0
  264. package/dist/generated/index.js +107 -104
  265. package/dist/index.js +107 -104
  266. package/dist/styles.css +1648 -235
  267. package/package.json +3 -3
  268. package/dist/AccessDeniedCard-WXM5DBDZ.css +0 -8
  269. package/dist/CanvasBoard-ZLPDINSM.css +0 -236
  270. package/dist/DocTabsEditor-RCOWHX5J.css +0 -78
  271. package/dist/PresenterView-T2C6ZZ3N.css +0 -103
  272. package/dist/SandboxedFrame-L6HBQZCD.css +0 -50
  273. package/dist/chunk-ALMSY7RL.js +0 -74
  274. package/dist/chunk-LR5QTFOE.js +0 -105
  275. package/dist/chunk-OGAAHVF6.js +0 -107
  276. package/dist/chunk-UZ7ZUSLH.js +0 -179
  277. package/dist/utils/useMediaMatch.d.ts +0 -12
  278. /package/dist/{chunk-OC46246T.js → chunk-2JJIN6JN.js} +0 -0
@@ -1,15 +1,16 @@
1
- import { Note } from './chunk-CJKMURZO.js';
2
- import { IDENTITY_VIEW, Canvas } from './chunk-OJ45PPCV.js';
1
+ import { Note } from './chunk-5SZGKSGL.js';
2
+ import { CanvasToolbar, toolForKey } from './chunk-GLSOD5Z4.js';
3
+ import { IDENTITY_VIEW, Canvas } from './chunk-22UEIXZE.js';
3
4
  import { IconButton } from './chunk-4FQT6ZAY.js';
4
5
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './CanvasBoard-ZLPDINSM.css';
6
- import { useState, useCallback, useMemo, useRef } from 'react';
7
- import { MaximizeGlyph, PencilGlyph, TrashGlyph } from '@crewlethq/icons/glyphs';
6
+ import './CanvasBoard-5NNSKY6A.css';
7
+ import { useState, useRef, useImperativeHandle, useCallback, useMemo, useEffect } from 'react';
8
+ import { MaximizeGlyph, PencilGlyph, TrashGlyph, MousePointer2Glyph, HandGlyph, TypeGlyph, StickyNoteGlyph } from '@crewlethq/icons/glyphs';
8
9
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
10
 
10
11
  // src/CanvasBoard/budget.ts
11
12
  var CANVAS_BOARD_MAX_LIVE = 12;
12
- var CANVAS_BOARD_MIN_LIVE_WIDTH = 160;
13
+ var CANVAS_BOARD_MIN_LIVE_WIDTH = 96;
13
14
  function liveBoards(boards, view, viewport, max = CANVAS_BOARD_MAX_LIVE, minWidth = CANVAS_BOARD_MIN_LIVE_WIDTH) {
14
15
  if (max <= 0 || viewport.width <= 0 || viewport.height <= 0) return [];
15
16
  const ranked = [];
@@ -41,6 +42,11 @@ var NOTE_TONES = {
41
42
  green: "green",
42
43
  purple: "purple"
43
44
  };
45
+ function titleSize(note) {
46
+ const chars = Math.max(1, Array.from(note.text.trim()).length);
47
+ return Math.max(1, Math.min(note.h * 0.6, note.w / (chars * TITLE_GLYPH_EM)));
48
+ }
49
+ var TITLE_GLYPH_EM = 0.58;
44
50
  function noteName(note) {
45
51
  const words = note.text.trim().replace(/\s+/g, " ");
46
52
  return words.length > 40 ? `${words.slice(0, 39)}\u2026` : words;
@@ -54,8 +60,21 @@ var LABELS = {
54
60
  removeNote: "Delete note",
55
61
  noteText: "Note text",
56
62
  paused: "Zoom in to run this board",
57
- active: "Press Escape to return to the canvas"
63
+ active: "Press Escape to return to the canvas",
64
+ interact: "Double-click to use this board",
65
+ tools: "Tools",
66
+ moveTool: "Move",
67
+ handTool: "Hand",
68
+ textTool: "Text",
69
+ stickyTool: "Sticky note"
70
+ };
71
+ var TOOL_CURSOR = {
72
+ move: "pointer",
73
+ hand: "hand",
74
+ text: "text",
75
+ sticky: "crosshair"
58
76
  };
77
+ var CANVAS_BOARD_MIN_ZOOM = 0.02;
59
78
  var KEY_STEP = 8;
60
79
  var KEY_STEP_LARGE = 64;
61
80
  var CONTENT_MARGIN = 160;
@@ -80,23 +99,37 @@ function contentOf(boards, notes) {
80
99
  };
81
100
  }
82
101
  var clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
102
+ var CONTROL = "button, a[href], input, select, textarea, [contenteditable='true']";
103
+ var POINTER_CORNERS = ["resize-nw", "resize-ne", "resize-sw"];
83
104
  function useFrameGestures(zoom, minSide, maxSide, commit) {
84
105
  const [preview, setPreview] = useState(null);
85
106
  const drag = useRef(null);
86
107
  const next = useCallback(
87
- (d, dx, dy) => d.mode === "move" ? { ...d.from, x: Math.round(d.from.x + dx), y: Math.round(d.from.y + dy) } : {
88
- ...d.from,
89
- w: clamp(Math.round(d.from.w + dx), minSide, maxSide),
90
- h: clamp(Math.round(d.from.h + dy), minSide, maxSide)
108
+ (d, dx, dy) => {
109
+ const { from } = d;
110
+ if (d.mode === "move") return { ...from, x: Math.round(from.x + dx), y: Math.round(from.y + dy) };
111
+ const west = d.mode === "resize-nw" || d.mode === "resize-sw";
112
+ const north = d.mode === "resize-nw" || d.mode === "resize-ne";
113
+ const w = clamp(Math.round(from.w + (west ? -dx : dx)), minSide, maxSide);
114
+ const h = clamp(Math.round(from.h + (north ? -dy : dy)), minSide, maxSide);
115
+ return {
116
+ x: west ? from.x + from.w - w : from.x,
117
+ y: north ? from.y + from.h - h : from.y,
118
+ w,
119
+ h
120
+ };
91
121
  },
92
122
  [minSide, maxSide]
93
123
  );
94
- const handle = (id, mode, item) => {
124
+ const pointer = (id, mode, item) => {
95
125
  const from = { x: item.x, y: item.y, w: item.w, h: item.h };
96
126
  return {
97
127
  onPointerDown: (event) => {
98
128
  if (event.pointerType === "mouse" && event.button !== 0) return;
129
+ const control = event.target instanceof Element ? event.target.closest(CONTROL) : null;
130
+ if (control !== null && control !== event.currentTarget) return;
99
131
  event.preventDefault();
132
+ event.stopPropagation();
100
133
  try {
101
134
  event.currentTarget.setPointerCapture(event.pointerId);
102
135
  } catch {
@@ -135,7 +168,12 @@ function useFrameGestures(zoom, minSide, maxSide, commit) {
135
168
  onPointerCancel: () => {
136
169
  drag.current = null;
137
170
  setPreview(null);
138
- },
171
+ }
172
+ };
173
+ };
174
+ const keys = (id, mode, item) => {
175
+ const from = { x: item.x, y: item.y, w: item.w, h: item.h };
176
+ return {
139
177
  onKeyDown: (event) => {
140
178
  const step = event.shiftKey ? KEY_STEP_LARGE : KEY_STEP;
141
179
  const delta = {
@@ -159,8 +197,23 @@ function useFrameGestures(zoom, minSide, maxSide, commit) {
159
197
  }
160
198
  };
161
199
  };
162
- return { preview, handle };
200
+ const handle = (id, mode, item) => ({
201
+ ...pointer(id, mode, item),
202
+ ...keys(id, mode, item)
203
+ });
204
+ return { preview, handle, pointer };
205
+ }
206
+ var sameSelection = (a, b) => a === b || a !== null && b !== null && a.kind === b.kind && a.id === b.id;
207
+ function boardRoom(width, height) {
208
+ const title = width >= BOARD_TITLE_MIN_WIDTH;
209
+ if (width >= PLACEHOLDER_FULL.width && height >= PLACEHOLDER_FULL.height) return { title, lines: 2 };
210
+ if (width >= PLACEHOLDER_SIZE.width && height >= PLACEHOLDER_SIZE.height) return { title, lines: 1 };
211
+ return { title, lines: 0 };
163
212
  }
213
+ var BOARD_TITLE_MIN_WIDTH = 40;
214
+ var PLACEHOLDER_SIZE = { width: 96, height: 32 };
215
+ var PLACEHOLDER_FULL = { width: 200, height: 64 };
216
+ var TYPING = "input, textarea, select, [contenteditable='true']";
164
217
  function CanvasBoard({
165
218
  label,
166
219
  boards,
@@ -174,9 +227,13 @@ function CanvasBoard({
174
227
  onBoardChange,
175
228
  onNoteChange,
176
229
  onNoteRemove,
230
+ onNoteCreate,
177
231
  onOpen,
178
232
  onActivate,
233
+ selected: heldSelection,
234
+ onSelectedChange,
179
235
  controlsExtra,
236
+ toolbar = true,
180
237
  labels,
181
238
  canvasLabels,
182
239
  canvasRef,
@@ -187,6 +244,28 @@ function CanvasBoard({
187
244
  const [viewport, setViewport] = useState({ width: 0, height: 0 });
188
245
  const [active, setActive] = useState(null);
189
246
  const [editing, setEditing] = useState(null);
247
+ const [ownSelection, setOwnSelection] = useState(null);
248
+ const selected = heldSelection !== void 0 ? heldSelection : ownSelection;
249
+ const setSelected = (next) => {
250
+ if (sameSelection(next, selected)) return;
251
+ if (heldSelection === void 0) setOwnSelection(next);
252
+ onSelectedChange?.(next);
253
+ };
254
+ const [chosenTool, setTool] = useState("move");
255
+ const [spaceHeld, setSpaceHeld] = useState(false);
256
+ const canvas = useRef(null);
257
+ useImperativeHandle(canvasRef, () => canvas.current, []);
258
+ const creates = editable && onNoteCreate !== void 0;
259
+ const tools = [
260
+ { id: "move", label: text.moveTool, icon: /* @__PURE__ */ jsx(MousePointer2Glyph, {}), shortcut: "V" },
261
+ { id: "hand", label: text.handTool, icon: /* @__PURE__ */ jsx(HandGlyph, {}), shortcut: "H" },
262
+ ...creates ? [
263
+ { id: "text", label: text.textTool, icon: /* @__PURE__ */ jsx(TypeGlyph, {}), shortcut: "T" },
264
+ { id: "sticky", label: text.stickyTool, icon: /* @__PURE__ */ jsx(StickyNoteGlyph, {}), shortcut: "S" }
265
+ ] : []
266
+ ];
267
+ const tool = tools.some((t) => t.id === chosenTool) ? chosenTool : "move";
268
+ const acting = spaceHeld ? "hand" : tool;
190
269
  const activate = (id) => {
191
270
  setActive(id);
192
271
  onActivate?.(id);
@@ -215,15 +294,77 @@ function CanvasBoard({
215
294
  );
216
295
  const largest = boards.reduce((w, b) => Math.max(w, b.w), 0);
217
296
  const live = new Set(liveBoards(drawnBoards, view, viewport, maxLive, minLiveWidth));
297
+ const shownSelection = selected !== null && (selected.kind === "board" ? boards : notes).some((item) => item.id === selected.id) ? selected : null;
298
+ const isSelected = (kind, id) => shownSelection?.kind === kind && shownSelection.id === id;
299
+ useEffect(() => {
300
+ if (!spaceHeld) return;
301
+ const release = (event) => {
302
+ if (event instanceof KeyboardEvent && event.key !== " ") return;
303
+ setSpaceHeld(false);
304
+ };
305
+ window.addEventListener("keyup", release);
306
+ window.addEventListener("blur", release);
307
+ return () => {
308
+ window.removeEventListener("keyup", release);
309
+ window.removeEventListener("blur", release);
310
+ };
311
+ }, [spaceHeld]);
218
312
  const onKeyDown = (event) => {
219
- if (event.key === "Escape" && active !== null) {
220
- event.stopPropagation();
221
- activate(null);
313
+ const target = event.target instanceof Element ? event.target : null;
314
+ if (event.key === "Escape") {
315
+ if (active !== null) {
316
+ event.stopPropagation();
317
+ activate(null);
318
+ } else if (shownSelection !== null) {
319
+ event.stopPropagation();
320
+ setSelected(null);
321
+ }
322
+ return;
323
+ }
324
+ if (event.defaultPrevented || target?.closest(TYPING)) return;
325
+ if (event.key === " ") {
326
+ if (target?.closest(CONTROL)) return;
327
+ event.preventDefault();
328
+ if (!event.repeat) setSpaceHeld(true);
329
+ return;
330
+ }
331
+ if ((event.key === "Delete" || event.key === "Backspace") && editable && shownSelection?.kind === "note") {
332
+ event.preventDefault();
333
+ onNoteRemove?.(shownSelection.id);
334
+ setSelected(null);
335
+ return;
336
+ }
337
+ const picked = toolForKey(tools, event);
338
+ if (picked !== void 0) {
339
+ event.preventDefault();
340
+ setTool(picked);
222
341
  }
223
342
  };
343
+ const onClick = (event) => {
344
+ const target = event.target instanceof Element ? event.target : null;
345
+ if (!target?.closest(".crewlet-canvas__viewport")) return;
346
+ if (target.closest(".crewlet-canvas-board__board, .crewlet-canvas-board__note")) return;
347
+ if ((acting === "text" || acting === "sticky") && onNoteCreate && canvas.current) {
348
+ const at = canvas.current.worldAt({ x: event.clientX, y: event.clientY });
349
+ const id = onNoteCreate(acting === "text" ? "title" : "sticky", {
350
+ x: Math.round(at.x),
351
+ y: Math.round(at.y)
352
+ });
353
+ setTool("move");
354
+ if (id !== void 0) {
355
+ setSelected({ kind: "note", id });
356
+ setEditing(id);
357
+ }
358
+ return;
359
+ }
360
+ if (acting === "move") setSelected(null);
361
+ };
224
362
  const zoomVar = { "--crewlet-canvas-board-zoom": String(view.k) };
363
+ const activeBoard = boards.find((b) => b.id === active && live.has(b.id));
364
+ const chosenBoard = shownSelection?.kind === "board" ? shownSelection.id : null;
365
+ const hint = !editable && activeBoard ? text.active : !editable && chosenBoard !== null && live.has(chosenBoard) ? text.interact : "";
225
366
  return (
226
- // The wrapper only hears Escape bubbling from inside the canvas; the
367
+ // The wrapper hears keys and clicks bubbling from inside the canvas; the
227
368
  // canvas's own viewport is the focusable, labelled control.
228
369
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
229
370
  /* @__PURE__ */ jsx(
@@ -231,31 +372,43 @@ function CanvasBoard({
231
372
  {
232
373
  className: cx("crewlet-canvas-board", className),
233
374
  "data-editable": editable || void 0,
375
+ "data-tool": acting,
234
376
  onKeyDown,
377
+ onClick,
235
378
  children: /* @__PURE__ */ jsx(
236
379
  Canvas,
237
380
  {
238
381
  label,
239
382
  content,
240
383
  largestItemWidth: largest || void 0,
241
- ground: "dotted",
384
+ ground: "grid",
385
+ cursor: TOOL_CURSOR[acting],
386
+ minZoom: CANVAS_BOARD_MIN_ZOOM,
387
+ refitOnResize: true,
388
+ controlsActualSize: true,
242
389
  controlsExtra,
390
+ hint,
243
391
  labels: canvasLabels,
392
+ overlay: toolbar ? /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__tools", children: /* @__PURE__ */ jsx(CanvasToolbar, { label: text.tools, tools, value: tool, onChange: setTool }) }) : void 0,
244
393
  onViewChange: (nextView, size) => {
245
394
  setView(nextView);
246
395
  setViewport(size);
247
396
  },
248
- ref: canvasRef,
397
+ ref: canvas,
249
398
  children: /* @__PURE__ */ jsxs("div", { className: "crewlet-canvas-board__layer", style: zoomVar, children: [
250
399
  drawnBoards.map((b) => {
251
400
  const isLive = live.has(b.id);
252
401
  const isActive = !editable && active === b.id && isLive;
402
+ const chosen = isSelected("board", b.id);
403
+ const room = boardRoom(b.w * view.k, b.h * view.k);
253
404
  return /* @__PURE__ */ jsxs(
254
405
  "section",
255
406
  {
256
407
  className: "crewlet-canvas-board__board",
408
+ "data-untitled": !room.title || void 0,
257
409
  "data-live": isLive || void 0,
258
410
  "data-active": isActive || void 0,
411
+ "data-selected": chosen || void 0,
259
412
  "aria-label": `${b.title}, ${text.size(b.w, b.h)}`,
260
413
  style: { left: b.x, top: b.y, width: b.w, height: b.h },
261
414
  children: [
@@ -266,15 +419,31 @@ function CanvasBoard({
266
419
  type: "button",
267
420
  className: "crewlet-canvas-board__title crewlet-canvas-board__handle",
268
421
  "aria-label": text.move(b.title),
422
+ "aria-pressed": chosen,
423
+ onFocus: () => setSelected({ kind: "board", id: b.id }),
269
424
  ...boardGestures.handle(b.id, "move", b),
270
425
  children: b.title
271
426
  }
272
- ) : /* @__PURE__ */ jsx("span", { className: "crewlet-canvas-board__title", children: b.title }),
427
+ ) : (
428
+ // The name selects its board, as a press on the board
429
+ // does; the board's keyboard route is its own page and
430
+ // its open control, so the name is pointer only.
431
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
432
+ /* @__PURE__ */ jsx(
433
+ "span",
434
+ {
435
+ className: "crewlet-canvas-board__title",
436
+ onClick: () => setSelected({ kind: "board", id: b.id }),
437
+ children: b.title
438
+ }
439
+ )
440
+ ),
273
441
  onOpen && /* @__PURE__ */ jsx(
274
442
  IconButton,
275
443
  {
276
444
  size: "sm",
277
445
  variant: "ghost",
446
+ className: "crewlet-canvas-board__open",
278
447
  label: text.open(b.title),
279
448
  icon: /* @__PURE__ */ jsx(MaximizeGlyph, {}),
280
449
  onClick: () => onOpen(b.id)
@@ -282,32 +451,38 @@ function CanvasBoard({
282
451
  )
283
452
  ] }),
284
453
  /* @__PURE__ */ jsxs("div", { className: "crewlet-canvas-board__body", children: [
285
- isLive ? renderBoard(b) : /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__placeholder", children: /* @__PURE__ */ jsxs("span", { className: "crewlet-canvas-board__placeholder-text", children: [
286
- /* @__PURE__ */ jsx("span", { className: "crewlet-canvas-board__placeholder-title", children: b.title }),
287
- /* @__PURE__ */ jsx("span", { children: text.size(b.w, b.h) }),
288
- /* @__PURE__ */ jsx("span", { children: text.paused })
289
- ] }) }),
290
- isLive && !isActive && // A press here pans the canvas like the field around it;
291
- // a click without a drag hands this board the pointer.
292
- // The board's page stays reachable by keyboard through
293
- // its own frame, so the shield is pointer only.
294
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events
454
+ isLive ? renderBoard(b) : (
455
+ // NAMED BY ITS TITLE ABOVE IT, as a live board is, so it
456
+ // says only what a running board does not: its size and
457
+ // why it is not running, as much of that as fits.
458
+ /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__placeholder", children: room.lines > 0 && /* @__PURE__ */ jsxs("span", { className: "crewlet-canvas-board__placeholder-text", children: [
459
+ /* @__PURE__ */ jsx("span", { className: "crewlet-canvas-board__placeholder-size", children: text.size(b.w, b.h) }),
460
+ room.lines > 1 && /* @__PURE__ */ jsx("span", { children: text.paused })
461
+ ] }) })
462
+ ),
463
+ !isActive && // A press here pans the canvas like the field around it;
464
+ // a click selects the board and a double-click hands a
465
+ // live board the pointer. The board's page stays
466
+ // reachable by keyboard through its own frame, so the
467
+ // shield is pointer only.
468
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
295
469
  /* @__PURE__ */ jsx(
296
470
  "div",
297
471
  {
298
472
  className: "crewlet-canvas-board__shield",
299
- onClick: editable ? void 0 : () => activate(b.id)
473
+ onClick: () => setSelected({ kind: "board", id: b.id }),
474
+ onDoubleClick: editable || !isLive ? void 0 : () => activate(b.id)
300
475
  }
301
476
  )
302
477
  ] }),
303
- isActive && /* @__PURE__ */ jsx("p", { className: "crewlet-canvas-board__hint", children: text.active }),
304
478
  editable && /* @__PURE__ */ jsx(
305
- "button",
479
+ Corners,
306
480
  {
307
- type: "button",
308
- className: "crewlet-canvas-board__resize",
309
- "aria-label": text.resize(b.title),
310
- ...boardGestures.handle(b.id, "resize", b)
481
+ title: b.title,
482
+ selected: chosen,
483
+ text,
484
+ keyed: boardGestures.handle(b.id, "resize-se", b),
485
+ pointer: (mode) => boardGestures.pointer(b.id, mode, b)
311
486
  }
312
487
  )
313
488
  ]
@@ -321,9 +496,13 @@ function CanvasBoard({
321
496
  note: n,
322
497
  editable,
323
498
  editing: editing === n.id,
499
+ selected: isSelected("note", n.id),
324
500
  text,
325
501
  moveHandle: noteGestures.handle(n.id, "move", n),
326
- resizeHandle: noteGestures.handle(n.id, "resize", n),
502
+ dragPaper: noteGestures.pointer(n.id, "move", n),
503
+ resizeHandle: noteGestures.handle(n.id, "resize-se", n),
504
+ resizePointer: (mode) => noteGestures.pointer(n.id, mode, n),
505
+ onSelect: () => setSelected({ kind: "note", id: n.id }),
327
506
  onEdit: () => setEditing(n.id),
328
507
  onDone: (value) => {
329
508
  setEditing(null);
@@ -345,13 +524,47 @@ function CanvasBoard({
345
524
  )
346
525
  );
347
526
  }
527
+ function Corners({
528
+ title,
529
+ selected,
530
+ text,
531
+ keyed,
532
+ pointer
533
+ }) {
534
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
535
+ selected && POINTER_CORNERS.map((mode) => /* @__PURE__ */ jsx(
536
+ "span",
537
+ {
538
+ "aria-hidden": true,
539
+ className: "crewlet-canvas-board__resize",
540
+ "data-corner": mode,
541
+ ...pointer(mode)
542
+ },
543
+ mode
544
+ )),
545
+ /* @__PURE__ */ jsx(
546
+ "button",
547
+ {
548
+ type: "button",
549
+ className: "crewlet-canvas-board__resize",
550
+ "data-corner": "resize-se",
551
+ "aria-label": text.resize(title),
552
+ ...keyed
553
+ }
554
+ )
555
+ ] });
556
+ }
348
557
  function NoteView({
349
558
  note,
350
559
  editable,
351
560
  editing,
561
+ selected,
352
562
  text,
353
563
  moveHandle,
564
+ dragPaper,
354
565
  resizeHandle,
566
+ resizePointer,
567
+ onSelect,
355
568
  onEdit,
356
569
  onDone,
357
570
  onCancel,
@@ -365,6 +578,7 @@ function NoteView({
365
578
  "aria-label": text.noteText,
366
579
  defaultValue: note.text,
367
580
  autoFocus: true,
581
+ onFocus: (event) => event.currentTarget.select(),
368
582
  onBlur: (event) => onDone(event.currentTarget.value),
369
583
  onKeyDown: (event) => {
370
584
  if (event.key === "Escape") {
@@ -377,7 +591,14 @@ function NoteView({
377
591
  }
378
592
  }
379
593
  }
380
- ) : /* @__PURE__ */ jsx("p", { className: "crewlet-canvas-board__note-text", children: note.text }),
594
+ ) : /* @__PURE__ */ jsx(
595
+ "p",
596
+ {
597
+ className: "crewlet-canvas-board__note-text",
598
+ style: note.kind === "title" ? { fontSize: titleSize(note) } : void 0,
599
+ children: note.text
600
+ }
601
+ ),
381
602
  editable && !editing && /* @__PURE__ */ jsxs("div", { className: "crewlet-canvas-board__note-tools", children: [
382
603
  /* @__PURE__ */ jsx(
383
604
  "button",
@@ -385,6 +606,7 @@ function NoteView({
385
606
  type: "button",
386
607
  className: "crewlet-canvas-board__handle crewlet-canvas-board__note-move",
387
608
  "aria-label": text.move(noteName(note)),
609
+ onFocus: onSelect,
388
610
  ...moveHandle
389
611
  }
390
612
  ),
@@ -410,16 +632,22 @@ function NoteView({
410
632
  )
411
633
  ] }),
412
634
  editable && !editing && /* @__PURE__ */ jsx(
413
- "button",
635
+ Corners,
414
636
  {
415
- type: "button",
416
- className: "crewlet-canvas-board__resize",
417
- "aria-label": text.resize(noteName(note)),
418
- ...resizeHandle
637
+ title: noteName(note),
638
+ selected,
639
+ text,
640
+ keyed: resizeHandle,
641
+ pointer: resizePointer
419
642
  }
420
643
  )
421
644
  ] });
422
645
  const frame = { left: note.x, top: note.y, width: note.w, height: note.h };
646
+ const paper = {
647
+ "data-selected": selected || void 0,
648
+ onClick: onSelect,
649
+ ...editable && !editing ? { ...dragPaper, onDoubleClick: onEdit } : {}
650
+ };
423
651
  if (note.kind === "sticky") {
424
652
  return /* @__PURE__ */ jsx(
425
653
  Note,
@@ -428,11 +656,12 @@ function NoteView({
428
656
  className: "crewlet-canvas-board__note",
429
657
  "data-kind": "sticky",
430
658
  style: frame,
659
+ ...paper,
431
660
  children: body
432
661
  }
433
662
  );
434
663
  }
435
- return /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__note", "data-kind": "title", style: frame, children: body });
664
+ return /* @__PURE__ */ jsx("div", { className: "crewlet-canvas-board__note", "data-kind": "title", style: frame, ...paper, children: body });
436
665
  }
437
666
 
438
- export { CANVAS_BOARD_MAX_LIVE, CANVAS_BOARD_MIN_LIVE_WIDTH, CANVAS_NOTE_COLORS, CanvasBoard, liveBoards };
667
+ export { BOARD_TITLE_MIN_WIDTH, CANVAS_BOARD_MAX_LIVE, CANVAS_BOARD_MIN_LIVE_WIDTH, CANVAS_BOARD_MIN_ZOOM, CANVAS_NOTE_COLORS, CanvasBoard, TITLE_GLYPH_EM, boardRoom, liveBoards, titleSize };
@@ -1,6 +1,6 @@
1
- import { richEditorLabels } from './chunk-A4E5YLXO.js';
2
- import { Skeleton } from './chunk-W5J7R5EB.js';
3
- import { Callout } from './chunk-SVSCLHHI.js';
1
+ import { richEditorLabels } from './chunk-4B6LSFDS.js';
2
+ import { Skeleton } from './chunk-TEUQWOWZ.js';
3
+ import { Callout } from './chunk-SZZRIHGT.js';
4
4
  import { Button } from './chunk-OG6CL3EB.js';
5
5
  import './RichEditor-NPD2KAPS.css';
6
6
  import { forwardRef, useState, useEffect } from 'react';
@@ -9,7 +9,7 @@ import { jsx } from 'react/jsx-runtime';
9
9
  var engine = null;
10
10
  var loading = null;
11
11
  function loadEngine() {
12
- loading ??= import('./Editor-YZ7KG2RD.js').then(
12
+ loading ??= import('./Editor-UUZ7XKCU.js').then(
13
13
  (module) => {
14
14
  engine = module.Editor;
15
15
  return engine;
@@ -1,10 +1,10 @@
1
- import { Skeleton } from './chunk-W5J7R5EB.js';
2
- import { Modal } from './chunk-I3KKZ2O3.js';
1
+ import { Skeleton } from './chunk-TEUQWOWZ.js';
2
+ import { Modal } from './chunk-XEGZHHRH.js';
3
3
  import { useListbox, useOptionKeys } from './chunk-F73MC7EZ.js';
4
- import { Popover } from './chunk-BWRGFKJP.js';
4
+ import { Popover } from './chunk-K3IJQNB7.js';
5
5
  import { KeyChip, highlightMatch } from './chunk-FYTIJM2T.js';
6
6
  import { Input } from './chunk-6QFAK2WV.js';
7
- import { useMediaMatch } from './chunk-IG75YMUN.js';
7
+ import { useMediaMatch } from './chunk-RTPQDNW3.js';
8
8
  import { focusables, isComposing } from './chunk-R25RGPUB.js';
9
9
  import { announce } from './chunk-RSAQOKH3.js';
10
10
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
@@ -23,6 +23,15 @@ function placePopup(anchor, size, bounds, gap = LAYER_GAP, prefer = "below") {
23
23
  function viewportBounds() {
24
24
  return { x: 0, y: 0, width: window.innerWidth, height: window.innerHeight };
25
25
  }
26
+ function anchorGone(anchor, host, inHost) {
27
+ const own = {
28
+ x: anchor.left - (inHost ? host.x : 0),
29
+ y: anchor.top - (inHost ? host.y : 0),
30
+ width: anchor.width,
31
+ height: anchor.height
32
+ };
33
+ return outsideBounds(own, { x: 0, y: 0, width: host.width, height: host.height });
34
+ }
26
35
  function outsideBounds(anchor, bounds) {
27
36
  return anchor.x + anchor.width < bounds.x || anchor.y + anchor.height < bounds.y || anchor.x > bounds.x + bounds.width || anchor.y > bounds.y + bounds.height;
28
37
  }
@@ -40,4 +49,4 @@ function useLayerContainer() {
40
49
  return typeof document === "undefined" ? null : document.body;
41
50
  }
42
51
 
43
- export { LAYER_GAP, LAYER_REPOSITION_EVENT, LayerHost, outsideBounds, placePopup, useLayerContainer, viewportBounds };
52
+ export { LAYER_GAP, LAYER_REPOSITION_EVENT, LayerHost, anchorGone, outsideBounds, placePopup, useLayerContainer, viewportBounds };
@@ -0,0 +1,55 @@
1
+ import { useRoving } from './chunk-RKKO7QHH.js';
2
+ import { cx } from './chunk-ODEQTPFM.js';
3
+ import './LayersList-NQZEIPZB.css';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var LAYERS_LIST_LABELS = {
7
+ openable: (label) => `${label}, press Enter or double-click to open`
8
+ };
9
+ function LayersList({
10
+ label,
11
+ items,
12
+ selected = null,
13
+ onSelect,
14
+ onOpen,
15
+ heading,
16
+ labels,
17
+ className
18
+ }) {
19
+ const text = { ...LAYERS_LIST_LABELS, ...labels };
20
+ const roving = useRoving(items.length, null, { followFocus: true });
21
+ const picked = items.findIndex((item) => item.id === selected);
22
+ const stop = roving.focused ?? Math.max(0, picked);
23
+ const onKeyDown = (event, id) => {
24
+ if (event.key === "Enter" && onOpen) {
25
+ event.preventDefault();
26
+ onOpen(id);
27
+ return;
28
+ }
29
+ roving.onKeyDown(event, true);
30
+ };
31
+ return /* @__PURE__ */ jsxs("nav", { className: cx("crewlet-layers-list", className), "aria-label": label, children: [
32
+ heading !== void 0 && heading !== null ? /* @__PURE__ */ jsx("div", { className: "crewlet-layers-list__heading", children: heading }) : null,
33
+ /* @__PURE__ */ jsx("ol", { className: "crewlet-layers-list__items", children: items.map((item, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ ref: (el) => {
38
+ roving.buttons.current[index] = el;
39
+ },
40
+ className: "crewlet-layers-list__item",
41
+ "aria-label": onOpen ? text.openable(item.label) : void 0,
42
+ "aria-current": item.id === selected ? "true" : void 0,
43
+ title: item.label,
44
+ tabIndex: index === stop ? 0 : -1,
45
+ onFocus: () => roving.onFocusAt(index),
46
+ onClick: () => onSelect?.(item.id),
47
+ onDoubleClick: onOpen ? () => onOpen(item.id) : void 0,
48
+ onKeyDown: (event) => onKeyDown(event, item.id),
49
+ children: item.label
50
+ }
51
+ ) }, item.id)) })
52
+ ] });
53
+ }
54
+
55
+ export { LAYERS_LIST_LABELS, LayersList };
@@ -1,4 +1,4 @@
1
- import { Avatar } from './chunk-5OM447RW.js';
1
+ import { Avatar } from './chunk-PZKHBB7D.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
3
  import './OrgLabel-R5KY7C3W.css';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -1,6 +1,6 @@
1
1
  import { Toolbar } from './chunk-PGRPNDWM.js';
2
- import { SegmentedControl } from './chunk-RCQXUT5K.js';
3
- import { tabId } from './chunk-HJEVSQN6.js';
2
+ import { SegmentedControl } from './chunk-CCAXYHQS.js';
3
+ import { tabId } from './chunk-VL6CUNSX.js';
4
4
  import { IconButton } from './chunk-4FQT6ZAY.js';
5
5
  import { cx } from './chunk-ODEQTPFM.js';
6
6
  import './MarkdownEditor-WOKV7CLK.css';