@owlmeans/web-panel 0.1.18-rc.9 → 0.1.18

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 (669) hide show
  1. package/README.md +510 -143
  2. package/THIRD-PARTY-NOTICES.txt +24 -0
  3. package/agent-meta/manifest.json +163 -4
  4. package/agent-meta/skills/web-panel/SKILL.md +136 -83
  5. package/agent-meta/skills/web-panel/parts/consent.md +114 -0
  6. package/agent-meta/skills/web-panel/parts/editor.md +47 -0
  7. package/agent-meta/skills/web-panel/parts/forms.md +85 -0
  8. package/agent-meta/skills/web-panel/parts/navigation.md +203 -0
  9. package/agent-meta/skills/web-panel/parts/picker.md +164 -0
  10. package/agent-meta/skills/web-panel/parts/reload.md +46 -0
  11. package/agent-meta/skills/web-panel/parts/sign-in.md +65 -0
  12. package/agent-meta/skills/web-panel/parts/theme.md +74 -0
  13. package/build/@/components/ui/alert-dialog.d.ts +15 -0
  14. package/build/@/components/ui/alert-dialog.d.ts.map +1 -0
  15. package/build/@/components/ui/alert-dialog.js +39 -0
  16. package/build/@/components/ui/alert-dialog.js.map +1 -0
  17. package/build/@/components/ui/alert.js +1 -1
  18. package/build/@/components/ui/alert.js.map +1 -1
  19. package/build/@/components/ui/button.js +1 -1
  20. package/build/@/components/ui/button.js.map +1 -1
  21. package/build/@/components/ui/card.js +1 -1
  22. package/build/@/components/ui/card.js.map +1 -1
  23. package/build/@/components/ui/input.js +1 -1
  24. package/build/@/components/ui/input.js.map +1 -1
  25. package/build/@/components/ui/label.js +1 -1
  26. package/build/@/components/ui/label.js.map +1 -1
  27. package/build/@/components/ui/navigation-menu.js +1 -1
  28. package/build/@/components/ui/navigation-menu.js.map +1 -1
  29. package/build/@/components/ui/popover.d.ts +8 -0
  30. package/build/@/components/ui/popover.d.ts.map +1 -0
  31. package/build/@/components/ui/popover.js +17 -0
  32. package/build/@/components/ui/popover.js.map +1 -0
  33. package/build/@/components/ui/progress.js +1 -1
  34. package/build/@/components/ui/progress.js.map +1 -1
  35. package/build/@/components/ui/separator.js +1 -1
  36. package/build/@/components/ui/separator.js.map +1 -1
  37. package/build/@/components/ui/sheet.d.ts +15 -0
  38. package/build/@/components/ui/sheet.d.ts.map +1 -0
  39. package/build/@/components/ui/sheet.js +40 -0
  40. package/build/@/components/ui/sheet.js.map +1 -0
  41. package/build/auth/context.d.ts.map +1 -1
  42. package/build/auth/context.js +0 -1
  43. package/build/auth/context.js.map +1 -1
  44. package/build/auth/entrypoints.d.ts +10 -0
  45. package/build/auth/entrypoints.d.ts.map +1 -0
  46. package/build/auth/entrypoints.js +4 -0
  47. package/build/auth/entrypoints.js.map +1 -0
  48. package/build/auth/exports.d.ts +4 -4
  49. package/build/auth/exports.d.ts.map +1 -1
  50. package/build/auth/exports.js +3 -3
  51. package/build/auth/exports.js.map +1 -1
  52. package/build/auth/modules.d.ts +1 -1
  53. package/build/auth/modules.d.ts.map +1 -1
  54. package/build/auth/plugins/basic-ed25519.js +4 -4
  55. package/build/auth/plugins/basic-ed25519.js.map +1 -1
  56. package/build/auth/plugins/re-captcha.js +3 -3
  57. package/build/auth/plugins/re-captcha.js.map +1 -1
  58. package/build/auth/plugins/tunnel-consumer.js +1 -1
  59. package/build/auth/plugins/tunnel-consumer.js.map +1 -1
  60. package/build/components/block.js +2 -2
  61. package/build/components/block.js.map +1 -1
  62. package/build/components/consts.local.d.ts +14 -0
  63. package/build/components/consts.local.d.ts.map +1 -0
  64. package/build/components/consts.local.js +26 -0
  65. package/build/components/consts.local.js.map +1 -0
  66. package/build/components/footer/component.d.ts +19 -1
  67. package/build/components/footer/component.d.ts.map +1 -1
  68. package/build/components/footer/component.js +38 -11
  69. package/build/components/footer/component.js.map +1 -1
  70. package/build/components/footer/credit.d.ts +27 -0
  71. package/build/components/footer/credit.d.ts.map +1 -0
  72. package/build/components/footer/credit.js +42 -0
  73. package/build/components/footer/credit.js.map +1 -0
  74. package/build/components/footer/index.d.ts +1 -0
  75. package/build/components/footer/index.d.ts.map +1 -1
  76. package/build/components/footer/index.js +1 -0
  77. package/build/components/footer/index.js.map +1 -1
  78. package/build/components/footer/types.d.ts +22 -1
  79. package/build/components/footer/types.d.ts.map +1 -1
  80. package/build/components/form/button/component.d.ts.map +1 -1
  81. package/build/components/form/button/component.js +5 -3
  82. package/build/components/form/button/component.js.map +1 -1
  83. package/build/components/form/component.js +2 -2
  84. package/build/components/form/component.js.map +1 -1
  85. package/build/components/form/text/component.js +2 -2
  86. package/build/components/form/text/component.js.map +1 -1
  87. package/build/components/helper.d.ts.map +1 -1
  88. package/build/components/helper.js +1 -12
  89. package/build/components/helper.js.map +1 -1
  90. package/build/components/index.d.ts +4 -0
  91. package/build/components/index.d.ts.map +1 -1
  92. package/build/components/index.js +4 -0
  93. package/build/components/index.js.map +1 -1
  94. package/build/components/link.js +3 -3
  95. package/build/components/link.js.map +1 -1
  96. package/build/components/login/append.d.ts +15 -0
  97. package/build/components/login/append.d.ts.map +1 -0
  98. package/build/components/login/append.js +26 -0
  99. package/build/components/login/append.js.map +1 -0
  100. package/build/components/login/consts.d.ts +3 -0
  101. package/build/components/login/consts.d.ts.map +1 -0
  102. package/build/components/login/consts.js +3 -0
  103. package/build/components/login/consts.js.map +1 -0
  104. package/build/components/login/consts.local.d.ts +4 -0
  105. package/build/components/login/consts.local.d.ts.map +1 -0
  106. package/build/components/login/consts.local.js +8 -0
  107. package/build/components/login/consts.local.js.map +1 -0
  108. package/build/components/login/credit.d.ts +12 -0
  109. package/build/components/login/credit.d.ts.map +1 -0
  110. package/build/components/login/credit.js +18 -0
  111. package/build/components/login/credit.js.map +1 -0
  112. package/build/components/login/i18n/be.json +10 -0
  113. package/build/components/login/i18n/de.json +10 -0
  114. package/build/components/login/i18n/en.json +10 -0
  115. package/build/components/login/i18n/es.json +10 -0
  116. package/build/components/login/i18n/fr.json +10 -0
  117. package/build/components/login/i18n/pl.json +10 -0
  118. package/build/components/login/i18n/ru.json +10 -0
  119. package/build/components/login/i18n/uk.json +10 -0
  120. package/build/components/login/i18n.d.ts +2 -0
  121. package/build/components/login/i18n.d.ts.map +1 -0
  122. package/build/components/login/i18n.js +28 -0
  123. package/build/components/login/i18n.js.map +1 -0
  124. package/build/components/login/icons.d.ts +14 -0
  125. package/build/components/login/icons.d.ts.map +1 -0
  126. package/build/components/login/icons.js +29 -0
  127. package/build/components/login/icons.js.map +1 -0
  128. package/build/components/login/index.d.ts +11 -0
  129. package/build/components/login/index.d.ts.map +1 -0
  130. package/build/components/login/index.js +10 -0
  131. package/build/components/login/index.js.map +1 -0
  132. package/build/components/login/notify.d.ts +18 -0
  133. package/build/components/login/notify.d.ts.map +1 -0
  134. package/build/components/login/notify.js +41 -0
  135. package/build/components/login/notify.js.map +1 -0
  136. package/build/components/login/provider.d.ts +20 -0
  137. package/build/components/login/provider.d.ts.map +1 -0
  138. package/build/components/login/provider.js +31 -0
  139. package/build/components/login/provider.js.map +1 -0
  140. package/build/components/login/screen.d.ts +24 -0
  141. package/build/components/login/screen.d.ts.map +1 -0
  142. package/build/components/login/screen.js +92 -0
  143. package/build/components/login/screen.js.map +1 -0
  144. package/build/components/login/terms.d.ts +19 -0
  145. package/build/components/login/terms.d.ts.map +1 -0
  146. package/build/components/login/terms.js +32 -0
  147. package/build/components/login/terms.js.map +1 -0
  148. package/build/components/login/types.d.ts +28 -0
  149. package/build/components/login/types.d.ts.map +1 -0
  150. package/build/components/login/types.js +2 -0
  151. package/build/components/login/types.js.map +1 -0
  152. package/build/components/nav/consts.local.d.ts +41 -0
  153. package/build/components/nav/consts.local.d.ts.map +1 -0
  154. package/build/components/nav/consts.local.js +60 -0
  155. package/build/components/nav/consts.local.js.map +1 -0
  156. package/build/components/nav/index.d.ts +1 -0
  157. package/build/components/nav/index.d.ts.map +1 -1
  158. package/build/components/nav/index.js +1 -0
  159. package/build/components/nav/index.js.map +1 -1
  160. package/build/components/nav/layout.d.ts +9 -2
  161. package/build/components/nav/layout.d.ts.map +1 -1
  162. package/build/components/nav/layout.js +48 -7
  163. package/build/components/nav/layout.js.map +1 -1
  164. package/build/components/nav/mobile.d.ts +21 -0
  165. package/build/components/nav/mobile.d.ts.map +1 -0
  166. package/build/components/nav/mobile.js +55 -0
  167. package/build/components/nav/mobile.js.map +1 -0
  168. package/build/components/nav/side.d.ts.map +1 -1
  169. package/build/components/nav/side.js +10 -10
  170. package/build/components/nav/side.js.map +1 -1
  171. package/build/components/nav/top.d.ts.map +1 -1
  172. package/build/components/nav/top.js +12 -8
  173. package/build/components/nav/top.js.map +1 -1
  174. package/build/components/nav/types.d.ts +64 -1
  175. package/build/components/nav/types.d.ts.map +1 -1
  176. package/build/components/nav/viewport.d.ts +3 -0
  177. package/build/components/nav/viewport.d.ts.map +1 -0
  178. package/build/components/nav/viewport.js +14 -0
  179. package/build/components/nav/viewport.js.map +1 -0
  180. package/build/components/panel-app/component.d.ts.map +1 -1
  181. package/build/components/panel-app/component.js +4 -3
  182. package/build/components/panel-app/component.js.map +1 -1
  183. package/build/components/picker/color-picker.d.ts +9 -0
  184. package/build/components/picker/color-picker.d.ts.map +1 -0
  185. package/build/components/picker/color-picker.js +9 -0
  186. package/build/components/picker/color-picker.js.map +1 -0
  187. package/build/components/picker/consts.local.d.ts +76 -0
  188. package/build/components/picker/consts.local.d.ts.map +1 -0
  189. package/build/components/picker/consts.local.js +214 -0
  190. package/build/components/picker/consts.local.js.map +1 -0
  191. package/build/components/picker/dot.d.ts +8 -0
  192. package/build/components/picker/dot.d.ts.map +1 -0
  193. package/build/components/picker/dot.js +10 -0
  194. package/build/components/picker/dot.js.map +1 -0
  195. package/build/components/picker/grid.d.ts +17 -0
  196. package/build/components/picker/grid.d.ts.map +1 -0
  197. package/build/components/picker/grid.js +73 -0
  198. package/build/components/picker/grid.js.map +1 -0
  199. package/build/components/picker/i18n/be.json +60 -0
  200. package/build/components/picker/i18n/de.json +60 -0
  201. package/build/components/picker/i18n/en.json +60 -0
  202. package/build/components/picker/i18n/es.json +60 -0
  203. package/build/components/picker/i18n/fr.json +60 -0
  204. package/build/components/picker/i18n/pl.json +60 -0
  205. package/build/components/picker/i18n/ru.json +60 -0
  206. package/build/components/picker/i18n/uk.json +60 -0
  207. package/build/components/picker/i18n.d.ts +2 -0
  208. package/build/components/picker/i18n.d.ts.map +1 -0
  209. package/build/components/picker/i18n.js +18 -0
  210. package/build/components/picker/i18n.js.map +1 -0
  211. package/build/components/picker/icon-color-picker.d.ts +14 -0
  212. package/build/components/picker/icon-color-picker.d.ts.map +1 -0
  213. package/build/components/picker/icon-color-picker.js +15 -0
  214. package/build/components/picker/icon-color-picker.js.map +1 -0
  215. package/build/components/picker/icon-picker.d.ts +8 -0
  216. package/build/components/picker/icon-picker.d.ts.map +1 -0
  217. package/build/components/picker/icon-picker.js +8 -0
  218. package/build/components/picker/icon-picker.js.map +1 -0
  219. package/build/components/picker/index.d.ts +11 -0
  220. package/build/components/picker/index.d.ts.map +1 -0
  221. package/build/components/picker/index.js +10 -0
  222. package/build/components/picker/index.js.map +1 -0
  223. package/build/components/picker/panel.d.ts +9 -0
  224. package/build/components/picker/panel.d.ts.map +1 -0
  225. package/build/components/picker/panel.js +23 -0
  226. package/build/components/picker/panel.js.map +1 -0
  227. package/build/components/picker/root.d.ts +13 -0
  228. package/build/components/picker/root.d.ts.map +1 -0
  229. package/build/components/picker/root.js +55 -0
  230. package/build/components/picker/root.js.map +1 -0
  231. package/build/components/picker/roving.d.ts +8 -0
  232. package/build/components/picker/roving.d.ts.map +1 -0
  233. package/build/components/picker/roving.js +62 -0
  234. package/build/components/picker/roving.js.map +1 -0
  235. package/build/components/picker/surface.d.ts +18 -0
  236. package/build/components/picker/surface.d.ts.map +1 -0
  237. package/build/components/picker/surface.js +36 -0
  238. package/build/components/picker/surface.js.map +1 -0
  239. package/build/components/picker/swatches/custom.d.ts +10 -0
  240. package/build/components/picker/swatches/custom.d.ts.map +1 -0
  241. package/build/components/picker/swatches/custom.js +65 -0
  242. package/build/components/picker/swatches/custom.js.map +1 -0
  243. package/build/components/picker/swatches.d.ts +16 -0
  244. package/build/components/picker/swatches.d.ts.map +1 -0
  245. package/build/components/picker/swatches.js +35 -0
  246. package/build/components/picker/swatches.js.map +1 -0
  247. package/build/components/picker/text.d.ts +5 -0
  248. package/build/components/picker/text.d.ts.map +1 -0
  249. package/build/components/picker/text.js +29 -0
  250. package/build/components/picker/text.js.map +1 -0
  251. package/build/components/picker/tile.d.ts +11 -0
  252. package/build/components/picker/tile.d.ts.map +1 -0
  253. package/build/components/picker/tile.js +19 -0
  254. package/build/components/picker/tile.js.map +1 -0
  255. package/build/components/picker/translate.d.ts +9 -0
  256. package/build/components/picker/translate.d.ts.map +1 -0
  257. package/build/components/picker/translate.js +13 -0
  258. package/build/components/picker/translate.js.map +1 -0
  259. package/build/components/picker/trigger.d.ts +12 -0
  260. package/build/components/picker/trigger.d.ts.map +1 -0
  261. package/build/components/picker/trigger.js +29 -0
  262. package/build/components/picker/trigger.js.map +1 -0
  263. package/build/components/picker/types.d.ts +114 -0
  264. package/build/components/picker/types.d.ts.map +1 -0
  265. package/build/components/picker/types.js +2 -0
  266. package/build/components/picker/types.js.map +1 -0
  267. package/build/components/picker/types.local.d.ts +143 -0
  268. package/build/components/picker/types.local.d.ts.map +1 -0
  269. package/build/components/picker/types.local.js +2 -0
  270. package/build/components/picker/types.local.js.map +1 -0
  271. package/build/components/scheme/consts.local.d.ts +8 -0
  272. package/build/components/scheme/consts.local.d.ts.map +1 -0
  273. package/build/components/scheme/consts.local.js +13 -0
  274. package/build/components/scheme/consts.local.js.map +1 -0
  275. package/build/components/scheme/hook.d.ts +16 -0
  276. package/build/components/scheme/hook.d.ts.map +1 -0
  277. package/build/components/scheme/hook.js +52 -0
  278. package/build/components/scheme/hook.js.map +1 -0
  279. package/build/components/scheme/index.d.ts +4 -0
  280. package/build/components/scheme/index.d.ts.map +1 -0
  281. package/build/components/scheme/index.js +3 -0
  282. package/build/components/scheme/index.js.map +1 -0
  283. package/build/components/scheme/toggle.d.ts +14 -0
  284. package/build/components/scheme/toggle.d.ts.map +1 -0
  285. package/build/components/scheme/toggle.js +24 -0
  286. package/build/components/scheme/toggle.js.map +1 -0
  287. package/build/components/scheme/types.d.ts +21 -0
  288. package/build/components/scheme/types.d.ts.map +1 -0
  289. package/build/components/scheme/types.js +2 -0
  290. package/build/components/scheme/types.js.map +1 -0
  291. package/build/components/socket/i18n/be.json +9 -0
  292. package/build/components/socket/i18n/de.json +9 -0
  293. package/build/components/socket/i18n/en.json +9 -0
  294. package/build/components/socket/i18n/es.json +9 -0
  295. package/build/components/socket/i18n/fr.json +9 -0
  296. package/build/components/socket/i18n/pl.json +9 -0
  297. package/build/components/socket/i18n/ru.json +9 -0
  298. package/build/components/socket/i18n/uk.json +9 -0
  299. package/build/components/socket/i18n.d.ts +2 -0
  300. package/build/components/socket/i18n.d.ts.map +1 -0
  301. package/build/components/socket/i18n.js +18 -0
  302. package/build/components/socket/i18n.js.map +1 -0
  303. package/build/components/socket/index.d.ts +3 -0
  304. package/build/components/socket/index.d.ts.map +1 -0
  305. package/build/components/socket/index.js +3 -0
  306. package/build/components/socket/index.js.map +1 -0
  307. package/build/components/socket/reload-dialog.d.ts +22 -0
  308. package/build/components/socket/reload-dialog.d.ts.map +1 -0
  309. package/build/components/socket/reload-dialog.js +34 -0
  310. package/build/components/socket/reload-dialog.js.map +1 -0
  311. package/build/components/status.js +1 -1
  312. package/build/components/status.js.map +1 -1
  313. package/build/components/text.d.ts.map +1 -1
  314. package/build/components/text.js +2 -13
  315. package/build/components/text.js.map +1 -1
  316. package/build/components/toaster.d.ts +16 -0
  317. package/build/components/toaster.d.ts.map +1 -0
  318. package/build/components/toaster.js +52 -0
  319. package/build/components/toaster.js.map +1 -0
  320. package/build/components/uploader/consts.local.d.ts +4 -0
  321. package/build/components/uploader/consts.local.d.ts.map +1 -0
  322. package/build/components/uploader/consts.local.js +6 -0
  323. package/build/components/uploader/consts.local.js.map +1 -0
  324. package/build/components/uploader/image.d.ts.map +1 -1
  325. package/build/components/uploader/image.js +2 -6
  326. package/build/components/uploader/image.js.map +1 -1
  327. package/build/consent/component.d.ts +27 -0
  328. package/build/consent/component.d.ts.map +1 -0
  329. package/build/consent/component.js +60 -0
  330. package/build/consent/component.js.map +1 -0
  331. package/build/consent/consts.d.ts +2 -0
  332. package/build/consent/consts.d.ts.map +1 -0
  333. package/build/consent/consts.js +2 -0
  334. package/build/consent/consts.js.map +1 -0
  335. package/build/consent/consts.local.d.ts +9 -0
  336. package/build/consent/consts.local.d.ts.map +1 -0
  337. package/build/consent/consts.local.js +9 -0
  338. package/build/consent/consts.local.js.map +1 -0
  339. package/build/consent/geo.d.ts +17 -0
  340. package/build/consent/geo.d.ts.map +1 -0
  341. package/build/consent/geo.js +19 -0
  342. package/build/consent/geo.js.map +1 -0
  343. package/build/consent/index.d.ts +11 -0
  344. package/build/consent/index.d.ts.map +1 -0
  345. package/build/consent/index.js +9 -0
  346. package/build/consent/index.js.map +1 -0
  347. package/build/consent/language.d.ts +12 -0
  348. package/build/consent/language.d.ts.map +1 -0
  349. package/build/consent/language.js +11 -0
  350. package/build/consent/language.js.map +1 -0
  351. package/build/consent/menu-widget.d.ts +13 -0
  352. package/build/consent/menu-widget.d.ts.map +1 -0
  353. package/build/consent/menu-widget.js +20 -0
  354. package/build/consent/menu-widget.js.map +1 -0
  355. package/build/consent/presence.d.ts +30 -0
  356. package/build/consent/presence.d.ts.map +1 -0
  357. package/build/consent/presence.js +40 -0
  358. package/build/consent/presence.js.map +1 -0
  359. package/build/consent/service.d.ts +18 -0
  360. package/build/consent/service.d.ts.map +1 -0
  361. package/build/consent/service.js +53 -0
  362. package/build/consent/service.js.map +1 -0
  363. package/build/consent/translate.d.ts +14 -0
  364. package/build/consent/translate.d.ts.map +1 -0
  365. package/build/consent/translate.js +28 -0
  366. package/build/consent/translate.js.map +1 -0
  367. package/build/consent/types.d.ts +39 -0
  368. package/build/consent/types.d.ts.map +1 -0
  369. package/build/consent/types.js +2 -0
  370. package/build/consent/types.js.map +1 -0
  371. package/build/consent/types.local.d.ts +6 -0
  372. package/build/consent/types.local.d.ts.map +1 -0
  373. package/build/consent/types.local.js +2 -0
  374. package/build/consent/types.local.js.map +1 -0
  375. package/build/context.d.ts.map +1 -1
  376. package/build/context.js +10 -0
  377. package/build/context.js.map +1 -1
  378. package/build/editor/component.d.ts +4 -0
  379. package/build/editor/component.d.ts.map +1 -0
  380. package/build/editor/component.js +103 -0
  381. package/build/editor/component.js.map +1 -0
  382. package/build/editor/consts.local.d.ts +6 -0
  383. package/build/editor/consts.local.d.ts.map +1 -0
  384. package/build/editor/consts.local.js +58 -0
  385. package/build/editor/consts.local.js.map +1 -0
  386. package/build/editor/index.d.ts +3 -0
  387. package/build/editor/index.d.ts.map +1 -0
  388. package/build/editor/index.js +2 -0
  389. package/build/editor/index.js.map +1 -0
  390. package/build/editor/types.d.ts +24 -0
  391. package/build/editor/types.d.ts.map +1 -0
  392. package/build/editor/types.js +2 -0
  393. package/build/editor/types.js.map +1 -0
  394. package/build/entrypoints.d.ts +8 -0
  395. package/build/entrypoints.d.ts.map +1 -0
  396. package/build/entrypoints.js +4 -0
  397. package/build/entrypoints.js.map +1 -0
  398. package/build/exports.d.ts +6 -5
  399. package/build/exports.d.ts.map +1 -1
  400. package/build/exports.js +5 -5
  401. package/build/exports.js.map +1 -1
  402. package/build/index.d.ts +1 -1
  403. package/build/index.d.ts.map +1 -1
  404. package/build/index.js +1 -1
  405. package/build/index.js.map +1 -1
  406. package/build/main.d.ts +1 -4
  407. package/build/main.d.ts.map +1 -1
  408. package/build/main.js.map +1 -1
  409. package/build/modules.d.ts +1 -1
  410. package/build/modules.d.ts.map +1 -1
  411. package/build/permission/i18n/be.json +13 -0
  412. package/build/permission/i18n/de.json +13 -0
  413. package/build/permission/i18n/en.json +13 -0
  414. package/build/permission/i18n/es.json +13 -0
  415. package/build/permission/i18n/fr.json +13 -0
  416. package/build/permission/i18n/pl.json +13 -0
  417. package/build/permission/i18n/ru.json +13 -0
  418. package/build/permission/i18n/uk.json +13 -0
  419. package/build/permission/i18n.d.ts +2 -0
  420. package/build/permission/i18n.d.ts.map +1 -0
  421. package/build/permission/i18n.js +13 -0
  422. package/build/permission/i18n.js.map +1 -0
  423. package/build/permission/index.d.ts +6 -0
  424. package/build/permission/index.d.ts.map +1 -0
  425. package/build/permission/index.js +27 -0
  426. package/build/permission/index.js.map +1 -0
  427. package/build/permission/toast.d.ts +5 -0
  428. package/build/permission/toast.d.ts.map +1 -0
  429. package/build/permission/toast.js +8 -0
  430. package/build/permission/toast.js.map +1 -0
  431. package/build/permission/types.d.ts +6 -0
  432. package/build/permission/types.d.ts.map +1 -0
  433. package/build/permission/types.js +2 -0
  434. package/build/permission/types.js.map +1 -0
  435. package/build/picker/icons/consts.d.ts +9 -0
  436. package/build/picker/icons/consts.d.ts.map +1 -0
  437. package/build/picker/icons/consts.js +264 -0
  438. package/build/picker/icons/consts.js.map +1 -0
  439. package/build/picker/icons/types.d.ts +18 -0
  440. package/build/picker/icons/types.d.ts.map +1 -0
  441. package/build/picker/icons/types.js +2 -0
  442. package/build/picker/icons/types.js.map +1 -0
  443. package/build/picker/icons.d.ts +4 -0
  444. package/build/picker/icons.d.ts.map +1 -0
  445. package/build/picker/icons.js +54 -0
  446. package/build/picker/icons.js.map +1 -0
  447. package/build/picker/index.d.ts +11 -0
  448. package/build/picker/index.d.ts.map +1 -0
  449. package/build/picker/index.js +10 -0
  450. package/build/picker/index.js.map +1 -0
  451. package/build/picker/utils/color/types.d.ts +35 -0
  452. package/build/picker/utils/color/types.d.ts.map +1 -0
  453. package/build/picker/utils/color/types.js +2 -0
  454. package/build/picker/utils/color/types.js.map +1 -0
  455. package/build/picker/utils/color.d.ts +4 -0
  456. package/build/picker/utils/color.d.ts.map +1 -0
  457. package/build/picker/utils/color.js +96 -0
  458. package/build/picker/utils/color.js.map +1 -0
  459. package/build/picker/vocabulary/consts.d.ts +26 -0
  460. package/build/picker/vocabulary/consts.d.ts.map +1 -0
  461. package/build/picker/vocabulary/consts.js +336 -0
  462. package/build/picker/vocabulary/consts.js.map +1 -0
  463. package/build/picker/vocabulary/types.d.ts +67 -0
  464. package/build/picker/vocabulary/types.d.ts.map +1 -0
  465. package/build/picker/vocabulary/types.js +2 -0
  466. package/build/picker/vocabulary/types.js.map +1 -0
  467. package/build/picker/vocabulary.d.ts +11 -0
  468. package/build/picker/vocabulary.d.ts.map +1 -0
  469. package/build/picker/vocabulary.js +83 -0
  470. package/build/picker/vocabulary.js.map +1 -0
  471. package/build/scheme/consts.d.ts +8 -0
  472. package/build/scheme/consts.d.ts.map +1 -0
  473. package/build/scheme/consts.js +8 -0
  474. package/build/scheme/consts.js.map +1 -0
  475. package/build/scheme/index.d.ts +4 -0
  476. package/build/scheme/index.d.ts.map +1 -0
  477. package/build/scheme/index.js +3 -0
  478. package/build/scheme/index.js.map +1 -0
  479. package/build/scheme/scheme.d.ts +16 -0
  480. package/build/scheme/scheme.d.ts.map +1 -0
  481. package/build/scheme/scheme.js +58 -0
  482. package/build/scheme/scheme.js.map +1 -0
  483. package/build/scheme/types.d.ts +30 -0
  484. package/build/scheme/types.d.ts.map +1 -0
  485. package/build/scheme/types.js +2 -0
  486. package/build/scheme/types.js.map +1 -0
  487. package/build/types.d.ts +18 -2
  488. package/build/types.d.ts.map +1 -1
  489. package/package.json +107 -52
  490. package/src/@/components/ui/alert-dialog.tsx +156 -0
  491. package/src/@/components/ui/alert.tsx +1 -1
  492. package/src/@/components/ui/button.tsx +1 -1
  493. package/src/@/components/ui/card.tsx +1 -1
  494. package/src/@/components/ui/input.tsx +1 -1
  495. package/src/@/components/ui/label.tsx +1 -1
  496. package/src/@/components/ui/navigation-menu.tsx +1 -1
  497. package/src/@/components/ui/popover.tsx +47 -0
  498. package/src/@/components/ui/progress.tsx +1 -1
  499. package/src/@/components/ui/separator.tsx +1 -1
  500. package/src/@/components/ui/sheet.tsx +142 -0
  501. package/src/auth/context.ts +0 -2
  502. package/src/auth/entrypoints.ts +5 -0
  503. package/src/auth/exports.ts +4 -4
  504. package/src/auth/plugins/basic-ed25519.tsx +4 -4
  505. package/src/auth/plugins/re-captcha.tsx +3 -3
  506. package/src/auth/plugins/tunnel-consumer.tsx +1 -1
  507. package/src/components/block.tsx +2 -2
  508. package/src/components/consts.local.ts +29 -0
  509. package/src/components/footer/component.tsx +58 -16
  510. package/src/components/footer/credit.tsx +61 -0
  511. package/src/components/footer/index.ts +1 -0
  512. package/src/components/footer/types.ts +22 -1
  513. package/src/components/form/button/component.tsx +7 -4
  514. package/src/components/form/component.tsx +2 -2
  515. package/src/components/form/text/component.tsx +2 -2
  516. package/src/components/helper.ts +1 -13
  517. package/src/components/index.ts +4 -0
  518. package/src/components/link.tsx +3 -3
  519. package/src/components/login/append.ts +34 -0
  520. package/src/components/login/consts.local.ts +10 -0
  521. package/src/components/login/consts.ts +2 -0
  522. package/src/components/login/credit.tsx +33 -0
  523. package/src/components/login/i18n/be.json +10 -0
  524. package/src/components/login/i18n/de.json +10 -0
  525. package/src/components/login/i18n/en.json +10 -0
  526. package/src/components/login/i18n/es.json +10 -0
  527. package/src/components/login/i18n/fr.json +10 -0
  528. package/src/components/login/i18n/pl.json +10 -0
  529. package/src/components/login/i18n/ru.json +10 -0
  530. package/src/components/login/i18n/uk.json +10 -0
  531. package/src/components/login/i18n.ts +29 -0
  532. package/src/components/login/icons.tsx +39 -0
  533. package/src/components/login/index.ts +11 -0
  534. package/src/components/login/notify.ts +48 -0
  535. package/src/components/login/provider.tsx +57 -0
  536. package/src/components/login/screen.tsx +178 -0
  537. package/src/components/login/terms.tsx +75 -0
  538. package/src/components/login/types.ts +30 -0
  539. package/src/components/nav/consts.local.ts +64 -0
  540. package/src/components/nav/index.ts +1 -0
  541. package/src/components/nav/layout.tsx +184 -26
  542. package/src/components/nav/mobile.tsx +165 -0
  543. package/src/components/nav/side.tsx +43 -27
  544. package/src/components/nav/top.tsx +44 -22
  545. package/src/components/nav/types.ts +65 -2
  546. package/src/components/nav/viewport.ts +16 -0
  547. package/src/components/panel-app/component.tsx +9 -1
  548. package/src/components/picker/color-picker.tsx +15 -0
  549. package/src/components/picker/consts.local.ts +267 -0
  550. package/src/components/picker/dot.tsx +21 -0
  551. package/src/components/picker/grid.tsx +138 -0
  552. package/src/components/picker/i18n/be.json +60 -0
  553. package/src/components/picker/i18n/de.json +60 -0
  554. package/src/components/picker/i18n/en.json +60 -0
  555. package/src/components/picker/i18n/es.json +60 -0
  556. package/src/components/picker/i18n/fr.json +60 -0
  557. package/src/components/picker/i18n/pl.json +60 -0
  558. package/src/components/picker/i18n/ru.json +60 -0
  559. package/src/components/picker/i18n/uk.json +60 -0
  560. package/src/components/picker/i18n.ts +19 -0
  561. package/src/components/picker/icon-color-picker.tsx +25 -0
  562. package/src/components/picker/icon-picker.tsx +13 -0
  563. package/src/components/picker/index.ts +11 -0
  564. package/src/components/picker/panel.tsx +61 -0
  565. package/src/components/picker/root.tsx +81 -0
  566. package/src/components/picker/roving.ts +70 -0
  567. package/src/components/picker/surface.tsx +62 -0
  568. package/src/components/picker/swatches/custom.tsx +110 -0
  569. package/src/components/picker/swatches.tsx +67 -0
  570. package/src/components/picker/text.ts +46 -0
  571. package/src/components/picker/tile.tsx +35 -0
  572. package/src/components/picker/translate.ts +15 -0
  573. package/src/components/picker/trigger.tsx +54 -0
  574. package/src/components/picker/types.local.ts +154 -0
  575. package/src/components/picker/types.ts +125 -0
  576. package/src/components/scheme/consts.local.ts +13 -0
  577. package/src/components/scheme/hook.ts +62 -0
  578. package/src/components/scheme/index.ts +4 -0
  579. package/src/components/scheme/toggle.tsx +32 -0
  580. package/src/components/scheme/types.ts +23 -0
  581. package/src/components/socket/i18n/be.json +9 -0
  582. package/src/components/socket/i18n/de.json +9 -0
  583. package/src/components/socket/i18n/en.json +9 -0
  584. package/src/components/socket/i18n/es.json +9 -0
  585. package/src/components/socket/i18n/fr.json +9 -0
  586. package/src/components/socket/i18n/pl.json +9 -0
  587. package/src/components/socket/i18n/ru.json +9 -0
  588. package/src/components/socket/i18n/uk.json +9 -0
  589. package/src/components/socket/i18n.ts +19 -0
  590. package/src/components/socket/index.ts +2 -0
  591. package/src/components/socket/reload-dialog.tsx +61 -0
  592. package/src/components/status.tsx +1 -1
  593. package/src/components/text.tsx +2 -14
  594. package/src/components/toaster.tsx +65 -0
  595. package/src/components/uploader/consts.local.ts +7 -0
  596. package/src/components/uploader/image.tsx +2 -6
  597. package/src/consent/component.tsx +84 -0
  598. package/src/consent/consts.local.ts +10 -0
  599. package/src/consent/consts.ts +1 -0
  600. package/src/consent/geo.ts +26 -0
  601. package/src/consent/index.ts +24 -0
  602. package/src/consent/language.ts +12 -0
  603. package/src/consent/menu-widget.tsx +22 -0
  604. package/src/consent/presence.ts +45 -0
  605. package/src/consent/service.ts +75 -0
  606. package/src/consent/translate.ts +31 -0
  607. package/src/consent/types.local.ts +6 -0
  608. package/src/consent/types.ts +43 -0
  609. package/src/context.ts +12 -0
  610. package/src/editor/component.tsx +172 -0
  611. package/src/editor/consts.local.ts +62 -0
  612. package/src/editor/index.ts +2 -0
  613. package/src/editor/types.ts +24 -0
  614. package/src/entrypoints.ts +5 -0
  615. package/src/exports.ts +6 -5
  616. package/src/index.ts +1 -1
  617. package/src/main.tsx +2 -6
  618. package/src/permission/i18n/be.json +13 -0
  619. package/src/permission/i18n/de.json +13 -0
  620. package/src/permission/i18n/en.json +13 -0
  621. package/src/permission/i18n/es.json +13 -0
  622. package/src/permission/i18n/fr.json +13 -0
  623. package/src/permission/i18n/pl.json +13 -0
  624. package/src/permission/i18n/ru.json +13 -0
  625. package/src/permission/i18n/uk.json +13 -0
  626. package/src/permission/i18n.ts +13 -0
  627. package/src/permission/index.ts +27 -0
  628. package/src/permission/toast.tsx +20 -0
  629. package/src/permission/types.ts +5 -0
  630. package/src/picker/icons/consts.ts +309 -0
  631. package/src/picker/icons/types.ts +18 -0
  632. package/src/picker/icons.ts +70 -0
  633. package/src/picker/index.ts +11 -0
  634. package/src/picker/utils/color/types.ts +37 -0
  635. package/src/picker/utils/color.ts +119 -0
  636. package/src/picker/vocabulary/consts.ts +347 -0
  637. package/src/picker/vocabulary/types.ts +72 -0
  638. package/src/picker/vocabulary.ts +111 -0
  639. package/src/scheme/consts.ts +8 -0
  640. package/src/scheme/index.ts +3 -0
  641. package/src/scheme/scheme.ts +66 -0
  642. package/src/scheme/types.ts +30 -0
  643. package/src/types.ts +19 -2
  644. package/tests/consent-language.spec.ts +31 -0
  645. package/tests/consent.spec.ts +112 -0
  646. package/tests/context.ts +4 -0
  647. package/tests/editor.spec.ts +58 -0
  648. package/tests/harness/editor.tsx +32 -0
  649. package/tests/harness/index.html +1 -0
  650. package/tests/harness/lazy-screen.tsx +9 -0
  651. package/tests/harness/mount.tsx +370 -29
  652. package/tests/harness/picker.tsx +110 -0
  653. package/tests/lazy.spec.ts +104 -0
  654. package/tests/login-provider.spec.ts +114 -0
  655. package/tests/login.spec.ts +447 -0
  656. package/tests/nav.spec.ts +449 -3
  657. package/tests/package-boundary.spec.ts +19 -0
  658. package/tests/picker-shots.spec.ts +174 -0
  659. package/tests/picker-vocabulary.spec.ts +217 -0
  660. package/tests/picker.spec.ts +333 -0
  661. package/tests/scheme.spec.ts +149 -0
  662. package/tests/smoke.spec.ts +2 -2
  663. package/tests/socket-dialog.spec.ts +154 -0
  664. package/tests/toaster.spec.ts +59 -0
  665. package/zz-tw.d.mts +2 -0
  666. package/zz-tw.d.mts.map +1 -0
  667. package/build/.gitkeep +0 -0
  668. package/src/auth/modules.ts +0 -5
  669. package/src/modules.ts +0 -5
@@ -0,0 +1,24 @@
1
+ shadcn/ui — copied UI components
2
+ Source: https://github.com/shadcn-ui/ui
3
+
4
+ MIT License
5
+
6
+ Copyright (c) 2023 shadcn
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/web-panel",
4
- "version": "0.1.18-rc.9",
5
- "generatedAt": "2026-08-24T21:14:00.140Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.768Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -10,7 +10,166 @@
10
10
  "name": "web-panel",
11
11
  "category": "package-specific",
12
12
  "file": "skills/web-panel/SKILL.md",
13
- "canonicalPath": ".agents/skills/web-panel/SKILL.md"
13
+ "canonicalPath": ".agents/skills/web-panel/SKILL.md",
14
+ "parts": [
15
+ {
16
+ "name": "consent",
17
+ "file": "skills/web-panel/parts/consent.md",
18
+ "description": "The ./consent subpath — PanelCookieConsent and PanelCookiePolicy bound to the app's i18n, cfg.cookieConsent, a geo plugin, and the host-menu presence service.",
19
+ "purposes": [
20
+ "consent"
21
+ ],
22
+ "mentions": [
23
+ "PanelCookieConsent",
24
+ "PanelCookiePolicy",
25
+ "PanelConsentMenuWidget",
26
+ "useConsentMenuPresence",
27
+ "appendConsentWidgetService",
28
+ "appendConsentGeoPlugin",
29
+ "cookieConsent",
30
+ "@owlmeans/web-panel/consent"
31
+ ]
32
+ },
33
+ {
34
+ "name": "editor",
35
+ "file": "skills/web-panel/parts/editor.md",
36
+ "description": "Controlled JSON editing and previews with the optional web-panel/editor entrypoint, CodeMirror 6, syntax diagnostics, formatting, copying and read-only state.",
37
+ "purposes": [
38
+ "form",
39
+ "view"
40
+ ],
41
+ "mentions": [
42
+ "JsonEditor",
43
+ "JsonEditorProps",
44
+ "JsonEditorLabels"
45
+ ]
46
+ },
47
+ {
48
+ "name": "forms",
49
+ "file": "skills/web-panel/parts/forms.md",
50
+ "description": "The web form family (Form, TextInput, Button, SubmitButton, ButtonSelector) and the Toaster surface for sonner toasts.",
51
+ "purposes": [
52
+ "form",
53
+ "feedback"
54
+ ],
55
+ "mentions": [
56
+ "TextInput",
57
+ "SubmitButton",
58
+ "ButtonSelector",
59
+ "useFormRef",
60
+ "WebFormProps",
61
+ "Toaster",
62
+ "sonner",
63
+ "appendPermissionDeniedToast"
64
+ ]
65
+ },
66
+ {
67
+ "name": "navigation",
68
+ "file": "skills/web-panel/parts/navigation.md",
69
+ "description": "The application shell — NavLayout, TopNav/SideNav/MobileNav/Footer, the two-layer nav config, the narrow-viewport menu, the skip link, the footer credit and the header's surface rules.",
70
+ "purposes": [
71
+ "navigation",
72
+ "layout",
73
+ "screen"
74
+ ],
75
+ "mentions": [
76
+ "NavLayout",
77
+ "TopNav",
78
+ "SideNav",
79
+ "MobileNav",
80
+ "Footer",
81
+ "ShellCredit",
82
+ "useShellCredit",
83
+ "PanelNavConfig",
84
+ "PanelNavLink",
85
+ "NavTranslate",
86
+ "defaultNavTranslate",
87
+ "mobileMenu",
88
+ "skipLinkLabel",
89
+ "headerClassName",
90
+ "containerClassName"
91
+ ]
92
+ },
93
+ {
94
+ "name": "picker",
95
+ "file": "skills/web-panel/parts/picker.md",
96
+ "description": "The ./picker subpath — the standard icon and colour picker parts, their values, surfaces and strings, rendering a stored mark, DOM hooks and consumer setup.",
97
+ "purposes": [
98
+ "picker",
99
+ "form"
100
+ ],
101
+ "mentions": [
102
+ "IconColorPicker",
103
+ "ColorPicker",
104
+ "IconPicker",
105
+ "ColorSwatches",
106
+ "IconGrid",
107
+ "IconTile",
108
+ "ColorDot",
109
+ "usePickerTranslate",
110
+ "pickerColorHelper",
111
+ "pickerIconHelper",
112
+ "PICKER_COLORS",
113
+ "PICKER_COLOR_KEYS",
114
+ "PICKER_ICON_NAMES",
115
+ "@owlmeans/web-panel/picker"
116
+ ]
117
+ },
118
+ {
119
+ "name": "reload",
120
+ "file": "skills/web-panel/parts/reload.md",
121
+ "description": "The global connection-lost prompt — SocketReloadDialog, the cfg.socket.reloadDialog opt-in, and its Try again and Reload page actions.",
122
+ "purposes": [
123
+ "feedback",
124
+ "config"
125
+ ],
126
+ "mentions": [
127
+ "SocketReloadDialog",
128
+ "reloadDialog",
129
+ "useSocketStatus",
130
+ "useSocketRetry",
131
+ "appendSocketStatus"
132
+ ]
133
+ },
134
+ {
135
+ "name": "sign-in",
136
+ "file": "skills/web-panel/parts/sign-in.md",
137
+ "description": "The sign-in screen's terms confirmation, privacy notice and provider disclosure — LoginTerms, LoginPrivacyNotice, LoginProviderNote and their DOM hooks.",
138
+ "purposes": [
139
+ "auth"
140
+ ],
141
+ "mentions": [
142
+ "LoginTerms",
143
+ "LoginPrivacyNotice",
144
+ "LoginProviderNote",
145
+ "LoginScreen",
146
+ "LocalizedLoginScreen",
147
+ "appendLoginScreen",
148
+ "data-login-terms",
149
+ "data-login-provider"
150
+ ]
151
+ },
152
+ {
153
+ "name": "theme",
154
+ "file": "skills/web-panel/parts/theme.md",
155
+ "description": "The light/dark switch — ThemeToggle, useColorScheme, the two-class html contract and the CSS a theme must read, and the head bootstrap script from ./scheme.",
156
+ "purposes": [
157
+ "theme"
158
+ ],
159
+ "mentions": [
160
+ "ThemeToggle",
161
+ "useColorScheme",
162
+ "colorSchemeHelper",
163
+ "colorSchemeBootstrapScript",
164
+ "applyColorScheme",
165
+ "COLOR_SCHEME_KEY",
166
+ "COLOR_SCHEME_EVENT",
167
+ "ColorSchemeChoice",
168
+ "themeToggle",
169
+ "@owlmeans/web-panel/scheme"
170
+ ]
171
+ }
172
+ ]
14
173
  }
15
174
  ]
16
175
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: web-panel
3
- description: How to use @owlmeans/web-panel — base browser context factory (makeContext) with shadcn/Radix + Tailwind and the default OwlMeans router wired in, plus the two-layer navigation shell (NavLayout/TopNav/SideNav/Footer) and form/panel components. Auto-invoked when building a web app's makeContext, wiring its navigation or layout, or importing web panel components.
3
+ description: How to use @owlmeans/web-panel — base browser context factory (makeContext) with shadcn/Radix + Tailwind and the default OwlMeans router wired in, the two-layer navigation shell (NavLayout/TopNav/SideNav/Footer), form/panel components, and the controlled JSON editor (`./editor`: JsonEditor), the standard icon + colour picker (`./picker`: IconColorPicker, ColorPicker, IconPicker, IconTile, ColorDot). Auto-invoked when building a web app's makeContext, wiring its navigation or layout, importing web panel components, or letting a person choose (or showing) an icon or a colour.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,23 +8,90 @@ user-invocable: false
8
8
  # @owlmeans/web-panel
9
9
 
10
10
  **Layer:** Web (React)
11
- **Install:** `"@owlmeans/web-panel": "^0.1.18-rc.9"` in `dependencies`
11
+ **Install:** `"@owlmeans/web-panel": "^0.1.18"` in `dependencies`
12
+
13
+ ## Choosing a component
14
+
15
+ Pick the row for the job; the one-liner is the correct shape. Everything comes from the package
16
+ root unless the import column names a subpath.
17
+
18
+ | Job | Use | Import | Correct one-liner |
19
+ |---|---|---|---|
20
+ | The app's context — the base web context factory (shadcn/Radix + default OwlMeans router) | `makeContext` | root | `const context = makeContext<C, T>(cfg)` in `context.ts`, then `append*(context)` mixins |
21
+ | Mount the app | `render` (or `PanelApp` for a host that mounts itself) | root | `render(context)` |
22
+ | The application shell — header, section menu, screen menu, content, footer | `NavLayout` | root | `<NavLayout nav={navConfig} title="App" mobileMenu themeToggle>{children}</NavLayout>` |
23
+ | One piece of the shell | `TopNav` / `SideNav` / `MobileNav` / `Footer` / `ShellCredit` | root | `<Footer links={footerLinks} />` |
24
+ | Toasts | `Toaster` + `toast` from `sonner` | root | `<Toaster />` once, in the layout; `toast.success('Saved')` where the action ends |
25
+ | Light / dark switch | `ThemeToggle` / `useColorScheme`; head script from `./scheme` | root, `./scheme` | `<NavLayout themeToggle … />` |
26
+ | A link to a screen | `Link` | root | `<Link module={web.about} />` |
27
+ | A form | `Form`, `TextInput`, `SubmitButton`, `Button`, `ButtonSelector` | root | `<Form decorate validation={schema} onSubmit={save}><TextInput name="email" label /></Form>` |
28
+ | A panel, a heading, an error | `Block`, `Text`, `Status` | root | `<Status error={error} />` |
29
+ | An image upload | `ImageUploader` (react-dropzone options) | root | `<ImageUploader accept={{ 'image/*': [] }} onDrop={files => upload(files[0])} previewUrl={url} />` |
30
+ | "Connection lost" prompt | `SocketReloadDialog` (mounted by `PanelApp`) | root | `cfg.socket = { reloadDialog: true }` |
31
+ | The sign-in screen | `LoginScreen` / `LocalizedLoginScreen` / `appendLoginScreen` | root | `appendLoginScreen(context, { Logo })` |
32
+ | Cookie consent | `PanelCookieConsent`, `PanelConsentMenuWidget` | `./consent` | `<PanelCookieConsent />` as a `PanelApp` child |
33
+ | A person picks an icon AND a colour (a type's, a flow's, a label's mark) | `IconColorPicker` | `./picker` | `<IconColorPicker label="Mark" value={{ icon, color }} onChange={next => …} translate={usePickerTranslate()} />` |
34
+ | A person picks a colour only | `ColorPicker` | `./picker` | `<ColorPicker label="Colour" value={color} onChange={setColor} />` |
35
+ | A person picks an icon only | `IconPicker` | `./picker` | `<IconPicker label="Icon" value={icon} onChange={setIcon} color={color} />` |
36
+ | The same, inline in a dialog the app already owns | `ColorSwatches`, `IconGrid` | `./picker` | `<IconGrid value={icon} onChange={setIcon} color={color} />` |
37
+ | Show a chosen mark or colour (list, chip, header) | `IconTile`, `ColorDot` | `./picker` | `<IconTile icon={type.icon} color={type.tone} size="sm" />` |
38
+ | Palette, icon names, colour maths — no React | `PICKER_*`, `pickerColorHelper`, `pickerIconHelper` | `./picker/vocabulary` (`pickerIconHelper`, `PICKER_ICONS`: `./picker`) | `pickerColorHelper.styleOf(color)` |
39
+ | Editable or read-only JSON | `JsonEditor` | `./editor` | `<JsonEditor key={record.id} value={draft} onChange={setDraft} onValidityChange={setValid} ariaLabel="Record JSON" />` |
40
+ | The current breakpoint | `useBreakPoint` / `useMapBreakpoint` | root | `useMapBreakpoint({ xs: 1, md: 2 }, 3)` |
41
+
42
+ **Common mistakes:**
43
+
44
+ - **Importing the package's private primitives.** `src/@/components/ui/*` (button, sheet, popover …)
45
+ and its `cn` are not exports; an app keeps its own shadcn components and never imports
46
+ `@owlmeans/web-panel/build/@/…` or expects `@/components/ui` to resolve to this package's copy.
47
+ - **A missing `@source`.** The app's Tailwind entry must scan this package's `src`
48
+ (`@source "../../../node_modules/@owlmeans/web-panel/src";`) or every class used only here — the
49
+ shell, the footer, the picker — silently never reaches the stylesheet.
50
+ - **Two `Toaster`s.** Mount it once, in the layout: two render every toast twice.
51
+ - **`Form decorate` plus an own submit button.** `decorate` already renders the `Card`, the root
52
+ error and a `SubmitButton` whenever `onSubmit` is given; without `decorate` there is no submit
53
+ button at all and the caller renders one.
54
+ - **A `Select`, radio group or hand-made swatch row for a colour or an icon a person chooses, or
55
+ `` `text-${color}-600` `` / `` `text-tone-${…}` `` built from a stored value.** A person-chosen colour
56
+ or icon is always edited with the `./picker` parts and rendered with `IconTile` / `ColorDot` (or
57
+ `pickerColorHelper.styleOf`); code-chosen tones (a status's meaning) stay the app's own classes.
58
+ - **`usePickerTranslate()` outside `PanelApp` / `render()`.** It needs the i18n instance and throws
59
+ without one; the picker parts themselves never read i18n (pass `translate`, or get English).
12
60
 
13
61
  ## Key Exports
14
62
 
63
+ Rows the chooser above already covers (`makeContext`, the shell pieces, `Toaster`, `Link`) are not
64
+ repeated here, and the rows of `ThemeToggle`, `SocketReloadDialog`, `LoginScreen` and the
65
+ `Form` family live in their parts.
66
+
15
67
  | Export | Description |
16
68
  |--------|-------------|
17
- | `makeContext<C, T>(cfg)` | Base web context factory (shadcn/Radix + default OwlMeans router) |
18
- | `NavLayout` | The application shell — header, section menu, screen menu, content, footer |
19
- | `TopNav` / `SideNav` / `Footer` | The shell's pieces, mountable on their own |
20
- | `components` submodule | shadcn/Radix panel/form components |
69
+ | `LoginProviderNote` | The provider disclosure (`LoginProviderNoteProps`) — see [parts/sign-in.md](parts/sign-in.md) |
70
+ | `render(context, opts?)` | Mounts the tree inside `PanelApp`, with the browser language detector installed on the i18n instance. `opts` is `RenderOptions` plus `rootClassName` |
71
+ | `PanelApp` | That wrapper on its own — the themed root `div` plus the i18n provider — for a host that mounts the tree itself |
72
+ | `useContext<C, T>()` | The current context, from React. `AppContext` adds `context.flow()` over `@owlmeans/web-client`'s |
73
+ | `entrypoints` | The base declaration list — `@owlmeans/web-client`'s plus `@owlmeans/api-config-client`'s. Compose the app's own over it |
74
+ | `Block` / `Text` / `Status` | The shadcn `Card` panel with an optional `Actions` footer, a heading/paragraph whose copy comes from the panel namespace, and the shadcn `Alert` resolving a `ResilientError` to a translated message |
75
+ | `ImageUploader` / `Layout` | The uploader in a drop target with a preview, and a plain content wrapper (the shell is `NavLayout`) |
76
+ | `scalingToStyles(h, v)` | `BlockScaling` → the width/height utility classes the panels share |
77
+ | `useBreakPoint()` | The current Tailwind breakpoint name, tracked on `resize` (`lg` when there is no `window`) |
78
+ | `useMapBreakpoint(map, def?, breakpoint?)` | The `map` entry for the current breakpoint (or for the `breakpoint` passed), falling back to `def`. It **throws a `SyntaxError`** when neither yields a value, so give it a `def` or cover every breakpoint |
21
79
  | Re-exports from `@owlmeans/client-panel` | Cross-platform panel primitives, incl. `usePanelNav` and the `PanelNav*` types |
22
- | `main`, `exports`, `context`, `modules`, `types` | Wiring helpers |
80
+ | Re-exports from `@owlmeans/client` / `@owlmeans/client-entrypoint` / `@owlmeans/route` | `bind`, `bindAll`, `bindScreen`, `handler`, `lazyHandler` / `lazyComponent` (+ `LazyHandler` / `LazyComponent` / `LazyComponentOptions` types — see the `client` skill), `clientRequestHelper` (`provideRequest`), `stab`, `route`, `croute`, `frontend`, `useNavigate`, `useEntrypoint`, `useValue` |
81
+ | Re-exports from the surrounding layers | `config`, `service`, `addWebService`, `AppType` / `HOME` / `ROOT` / `BASE` / `GUEST`, `DISPATCHER`, `CAUTHEN_FLOW_ENTER`, `DAUTH_GUARD`, `bindExternalAuthentication`, `Dispatcher`, `appendWebAuthService`, `flow` / `configureFlows` / `useFlow` / `FLOW_PARAM` / `SERVICE_PARAM`, `useI18n*` / `useLanguage` / `composePrefix`, `i18nHelper` (`addI18nApp` / `addI18nLib`) / `SUPPORTED_LNGS` |
23
82
 
24
83
  ## Subpath Exports
25
84
 
26
85
  - `./auth` — auth panel components for web
27
- - `./auth/modules` — auth panel module declarations
86
+ - `./auth/entrypoints` — auth panel entrypoint declarations
87
+ - `./consent` — the cookie consent dialog and policy, bound to this app's i18n, plus a menu-row
88
+ widget and a presence service so a host's own collapsed menu can take over the floating button's
89
+ job — see [parts/consent.md](parts/consent.md)
90
+ - `./scheme` — the React-free colour-scheme half, safe to import from a Node build script — see
91
+ [parts/theme.md](parts/theme.md)
92
+ - `./picker` — the standard icon + colour picker and its parts, not re-exported by the root; and
93
+ `./picker/vocabulary`, its React-free half (palette, icon names, `pickerColorHelper`), safe on a
94
+ server, in a seed or a Node build script — see [parts/picker.md](parts/picker.md)
28
95
 
29
96
  ## Usage
30
97
 
@@ -38,100 +105,86 @@ export const makeContext = <C extends Config, T extends Context<C>>(cfg: C): T =
38
105
  const context = makeBasicContext<C, T>(cfg)
39
106
  appendOidcGuard<C, T>(context)
40
107
  appendStateResource<C, T>(context, VIB_PROJECT_STATE)
41
- context.makeContext = makeContext as typeof context.makeContext
42
108
  return context
43
109
  }
44
110
  ```
45
111
 
46
- ### Navigation — `NavLayout`
112
+ **A context is created once per process, by one factory.** An app factory calls the factory of the
113
+ layer below it, applies idempotent `append*(context)` mixins, and returns that same context — the
114
+ whole shape of the file above. Nothing is stored for re-creation, and every service, resource and
115
+ entrypoint binds to exactly the one context it was appended to.
47
116
 
48
- `NavLayout` is the application shell. A layout entrypoint elevates a component that renders it and
49
- nothing else; the matched screen arrives as `children`. Keep the navigation as data in its own
50
- module (`src/nav.ts`) so screens, modules and the shell all read the same aliases.
117
+ ### Links — `Link`
51
118
 
52
- ```tsx
53
- import { NavLayout, HOME } from '@owlmeans/web-panel'
54
- import type { PanelNavConfig, PanelNavLink } from '@owlmeans/web-panel'
55
-
56
- export const navConfig: PanelNavConfig = {
57
- sections: [
58
- { name: 'home', label: 'Home', items: [{ alias: HOME, label: 'Overview' }] },
59
- {
60
- name: 'demo', label: 'Demo', items: [
61
- { alias: web.session, label: 'Session' },
62
- { alias: web.about, label: 'About' },
63
- ]
64
- },
65
- ],
66
- }
119
+ `Link` renders an `<a>` whose `href` is the entrypoint's own answer: it asks
120
+ `entrypoint.url()` and puts the result on the anchor, so a link into another service comes out
121
+ absolute and a link inside this one comes out as a path. Address a screen by **alias** (or hand it
122
+ the entrypoint you already hold); `src` is the escape hatch for a literal URL.
67
123
 
68
- export const footerLinks: PanelNavLink[] = [
69
- { alias: HOME, label: 'My App' },
70
- { href: 'https://owlmeans.com', label: 'OwlMeans', open: true },
71
- ]
124
+ ```tsx
125
+ import { Link } from '@owlmeans/web-panel'
72
126
 
73
- export const MainLayout: FC<PropsWithChildren> = ({ children }) =>
74
- <NavLayout nav={navConfig} title="My App" footer={footerLinks}>{children}</NavLayout>
127
+ <Link module={web.about} /> // label from `modules.<alias>`
128
+ <Link module={web.session} name="nav.session">Session</Link> // explicit i18n key
129
+ <Link src="https://owlmeans.com" open>OwlMeans</Link> // literal target, new tab
75
130
  ```
76
131
 
77
- **Navigation is two-layer.** The top menu lists **sections** — the first level; the side menu lists
78
- the **active section's screens** — the second. A section holding a single screen renders **no side
79
- menu at all**: the model owns that rule (`showSide`), so a section that later grows a second screen
80
- gains its menu with no layout change. `NavLayout` mounts `SideNav` twice — `variant="side"` as the
81
- `hidden md:block` column beside the content, `variant="bar"` as the `md:hidden` strip under the
82
- header. Both render the same items; only one is visible at a time.
132
+ Resolution is asynchronous — `href` is absent for the first paint and settles once the URL is
133
+ known — so never key a test or a layout on the anchor having an `href` synchronously. The label
134
+ falls back to `modules.<alias>` when neither `name` nor `children` is given, `open` adds
135
+ `target="_blank"` with `rel="noopener noreferrer"`, and `center` centres the text.
83
136
 
84
- | Component | Props |
85
- |---|---|
86
- | `NavLayout` | `nav: PanelNavConfig`, `translate?`, `title?: ReactNode`, `home?: string` (brand target — defaults to the first section's first item), `actions?: ReactNode`, `footer?: PanelNavLink[] \| ReactNode`, `contentClassName?`, `className?`, `style?` |
87
- | `TopNav` | `config: PanelNavConfig`, `translate?`, `ariaLabel?`, `className?`, `style?` |
88
- | `SideNav` | the same, plus `variant?: 'side' \| 'bar'` |
89
- | `Footer` | `links?: PanelNavLink[]`, `translate?`, `children?`, `className?`, `style?` |
90
-
91
- Rules that make the shell behave:
92
-
93
- - **Labels never reach for i18n implicitly.** `translate` is a **prop** (`NavTranslate`), defaulting
94
- to `defaultNavTranslate`, which returns the fallback. An app mounted with `renderApp` from
95
- `@owlmeans/web-client` has no i18n provider, and the panel i18n hook dereferences `i18n.options`
96
- on the empty object `react-i18next` returns without an instance — a throw inside render that
97
- blanks the whole app. An app that does have i18n passes its own
98
- `(key, defaultValue) => string` resolver. Order: literal `label` → `translate(key, humanized)` →
99
- humanized alias. Default keys are
100
- `nav.<section>` for sections and `modules.<alias>` for items and footer links — the same family
101
- `Link` uses.
102
- - **Menu entries are real links.** `TopNav` puts the resolved path on `href` and calls
103
- `preventDefault()` in `onClick`, navigating in-app through `nav.press`. Never drop the `href`: an
104
- `<a>` without one is not focusable, does not answer the keyboard, cannot be opened in a new tab,
105
- and does not even carry the `link` role.
106
- - **A parent route needs a `default: true` child.** A frontend entrypoint that has children but no
107
- child declared `default: true` renders blank at its own path — give a grouping screen an index
108
- child at `'/'`.
109
- - **Vendor `navigation-menu`.** `SideNav` builds on the existing `Button`; `TopNav` uses the shadcn
110
- `navigation-menu` primitive — see the `@` contract below.
111
-
112
- ## Consumer setup — the `@` contract and Tailwind
113
-
114
- `web-panel` emits `@/components/ui/*` and `@/lib/utils` verbatim; the app's bundler resolves `@` to
115
- its own shadcn copy. Vendor every primitive the package imports: `alert`, `button`, `card`, `input`,
116
- `label`, `navigation-menu`, `progress` (plus `separator` if you use it), and add
117
- `@radix-ui/react-navigation-menu` alongside the other Radix peers.
118
-
119
- Then point Tailwind at the built package. Its oxide scanner reads the CSS root plus `@source`
120
- directives only, and excludes `node_modules` — so classes that exist **only** inside `web-panel`
121
- components (the whole navigation shell and footer) never reach the stylesheet, and the app renders
122
- an unstyled menu. In the app's Tailwind entry:
137
+ ## Consumer setup — package boundary and Tailwind
138
+
139
+ `web-panel` ships its shadcn primitives and `cn` helper as private implementation files under its
140
+ own `build/@/` tree. Package source imports them only through relative specifiers; it must never
141
+ emit an absolute `@/…` import, because that alias belongs to the consuming application and makes a
142
+ fresh installation depend on unrelated files. `cn` is not exported: a consumer keeps its own
143
+ class-name helper and never vendors or imports this package's UI primitives.
144
+
145
+ Consumers still supply the package's peer dependencies: the Radix primitives (`alert-dialog`,
146
+ `dialog`, `label`, `navigation-menu`, `popover`, `progress`, `separator`, `slot` — `dialog` and
147
+ `popover` on the same Radix generation) plus React, Tailwind and the usual utility libraries. A
148
+ consumer may have its own shadcn `@` alias, but it is unrelated to this package.
149
+
150
+ Then point Tailwind at the installed package's **`src`** directory. Its oxide scanner reads the CSS root
151
+ plus `@source` directives only, and excludes `node_modules` — so classes that exist **only** inside
152
+ `web-panel` components (the whole navigation shell and footer) never reach the stylesheet, and the
153
+ app renders an unstyled menu. In the app's Tailwind entry:
123
154
 
124
155
  ```css
125
156
  @import "tailwindcss";
126
157
 
127
- @source "../../../node_modules/@owlmeans/web-panel/build";
158
+ @source "../../../node_modules/@owlmeans/web-panel/src";
128
159
  ```
129
160
 
130
- Adjust the relative depth to your own layout; the target is the installed package's `build`.
161
+ Adjust the relative depth to your own layout. Source ships in the published tarball and is tracked
162
+ in a linked workspace, so it is the reliable scan target in both modes.
131
163
 
132
164
  ## Depends On
133
165
 
134
166
  - `@owlmeans/web-client`, `@owlmeans/client-panel`, `@owlmeans/client-i18n`, `@owlmeans/web-router`
167
+ - `@owlmeans/client-socket` — `appendSocketStatus`, `useSocketStatus`, `useSocketRetry`, behind `SocketReloadDialog`
168
+ - `react-colorful` — the custom-colour wheel of `./picker` (`customColors`); `sonner` — toasts
135
169
  - Peers (app-provided): `react`, `react-dom`, `react-hook-form`, `tailwindcss`, `tailwind-merge`,
136
- `clsx`, `class-variance-authority`, `lucide-react`, `ajv`, and the `@radix-ui/react-*` primitives
137
- (`label`, `navigation-menu`, `progress`, `separator`, `slot`). No MUI, no react-router.
170
+ `clsx`, `class-variance-authority`, `lucide-react` (`./picker` imports its ~250 catalogue icons
171
+ statically), `ajv`, and the `@radix-ui/react-*` primitives (`alert-dialog`, `dialog`, `label`,
172
+ `navigation-menu`, `popover`, `progress`, `separator`, `slot`). No MUI, no react-router.
173
+ - `ajv-formats` is imported at module scope by the form model but is declared in no dependency
174
+ section of the manifest, which lists `ajv` alone. An install that does not otherwise pull it in
175
+ fails at import time, so declare `ajv-formats` next to `ajv` in the consuming application.
176
+
177
+ ## Parts
178
+
179
+ Load a part on top of this core when its job is in play.
180
+
181
+ | Part | Load it when |
182
+ |---|---|
183
+ | [editor](parts/editor.md) | Editing or displaying JSON, syntax diagnostics, controlled text, read-only previews and document identity |
184
+ | [navigation](parts/navigation.md) | Building or restyling the application shell — `NavLayout`, `TopNav`/`SideNav`/`MobileNav`/`Footer`, the nav config, `mobileMenu`, the skip link, the footer credit, the header surface |
185
+ | [forms](parts/forms.md) | Writing a form (`Form`, `TextInput`, the buttons) or raising a toast (`Toaster`, `sonner`, the permission-denied toast) |
186
+ | [theme](parts/theme.md) | Adding the light/dark switch (`ThemeToggle`, `useColorScheme`), the head bootstrap from `./scheme`, or CSS that follows the scheme |
187
+ | [reload](parts/reload.md) | Opting into the "connection lost" prompt (`cfg.socket.reloadDialog`, `SocketReloadDialog`) |
188
+ | [sign-in](parts/sign-in.md) | Changing the sign-in screen's terms confirmation, privacy notice or provider disclosure |
189
+ | [consent](parts/consent.md) | Mounting cookie consent through `./consent`, its geo gate, or a host menu's cookie-settings row |
190
+ | [picker](parts/picker.md) | Letting a person choose an icon or a colour, or rendering a stored mark (`./picker`) |
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: consent
3
+ description: The ./consent subpath — PanelCookieConsent and PanelCookiePolicy bound to the app's i18n, cfg.cookieConsent, a geo plugin, and the host-menu presence service.
4
+ metadata:
5
+ purposes: consent
6
+ mentions: PanelCookieConsent, PanelCookiePolicy, PanelConsentMenuWidget, useConsentMenuPresence, appendConsentWidgetService, appendConsentGeoPlugin, cookieConsent, @owlmeans/web-panel/consent
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Cookie consent
11
+
12
+ ## Subpath: `./consent`
13
+
14
+ `PanelCookieConsent` and `PanelCookiePolicy` — `@owlmeans/web-consent`'s components bound to this
15
+ app's language and translations, falling through to the package's own eight-language bundle for
16
+ every key the app has not overridden — and to the app's cookie-consent configuration. See the
17
+ `consent` and `web-consent` skills.
18
+
19
+ **The configuration lives in `cfg.cookieConsent`** (`PanelCookieConsentConfig`, on `AppConfig`),
20
+ set where the rest of the app's configuration is, before anything renders:
21
+
22
+ ```typescript
23
+ cfg.cookieConsent = { geo: { cloudflare: true } } // ask only in consent countries; mode: 'bar' default
24
+ ```
25
+
26
+ - `mode` (`'bar'` | `'window'`) and `geo` (`ConsentGeoOptions`) feed both components; a prop of the
27
+ same name always wins. Not `cfg.consent` — "consent" also names the marketing-consent and sign-in
28
+ terms options.
29
+ - A file restored into apps of every age (a generated target's `config.ts`) writes it as
30
+ `Object.assign(cfg, { cookieConsent: … })`, so a tree whose framework predates the key still
31
+ type-checks; an older package ignores it.
32
+ - **A locator of the app's own** is code, not configuration: `appendConsentGeoPlugin(context,
33
+ plugin)` in `context.ts` registers a `ConsentGeoPlugin` (`{ alias, locate }` — resolve the country
34
+ or throw) ahead of Cloudflare's and installs `context.consentGeo()`. Appending one IS asking for
35
+ the gate: `PanelCookieConsent` turns it on (`geo: {}`) even where `cfg.cookieConsent.geo` says
36
+ nothing. `PanelCookiePolicy` reads the same, so the policy states the regional rule exactly when
37
+ the dialog applies it.
38
+
39
+ A re-export does not move Tailwind class strings, so a consumer adds a second `@source` for
40
+ `@owlmeans/web-consent` alongside this package's — pointing at **`src`**, for the reason spelled out
41
+ under *Consumer setup — package boundary and Tailwind* in [SKILL.md](../SKILL.md). Without it the dialog renders half-styled.
42
+
43
+ **A service wrapping a state resource is what lets a host's own menu take over the floating
44
+ button's job.** `appendConsentWidgetService(context, alias?)` registers a ref-counted presence
45
+ service (`@owlmeans/state`'s `appendStateResource` behind `@owlmeans/context`'s `createService`) —
46
+ call it once, from the app's own `context.ts`, the same as any other `append*` mixin:
47
+
48
+ ```ts
49
+ import { appendConsentWidgetService } from '@owlmeans/web-panel/consent'
50
+
51
+ appendConsentWidgetService<C, T>(context)
52
+ ```
53
+
54
+ Then call `useConsentMenuPresence()` from the host menu's own **always-mounted** shell component,
55
+ never from inside the row. A dropdown's content (Radix `DropdownMenuContent` and most headless
56
+ menu content primitives) mounts its children only while the menu is OPEN, so presence announced
57
+ from inside the row hid the floating button only while the dropdown happened to be open, and
58
+ showed it again the instant it closed. The row is also not a `DropdownMenuItem`: an item takes the
59
+ inner button's focus and closes the menu on the click before the button's own handler runs.
60
+
61
+ ```tsx
62
+ import { PanelConsentMenuWidget, useConsentMenuPresence } from '@owlmeans/web-panel/consent'
63
+
64
+ const MyMenu: FC = () => {
65
+ useConsentMenuPresence() // declares the row reachable for as long as THIS component is mounted
66
+ return <DropdownMenu>
67
+ <DropdownMenuTrigger>…</DropdownMenuTrigger>
68
+ <DropdownMenuContent>
69
+ <div className="px-2 py-1.5"><PanelConsentMenuWidget /></div> {/* a plain row, not an item */}
70
+ </DropdownMenuContent>
71
+ </DropdownMenu>
72
+ }
73
+ ```
74
+
75
+ `PanelCookieConsent` reads the same service (`useConsentWidgetPresent()`, internally) and computes
76
+ `noReopenButton` from it whenever the caller has not passed one explicitly — an app that both
77
+ mounts `PanelCookieConsent` at its root and calls `useConsentMenuPresence()` from its collapsed
78
+ menu gets the floating button exactly while the menu is not, with no further wiring. Ref-counted
79
+ rather than a boolean latch, because more than one menu shell can be mounted for one commit during
80
+ a layout transition (a stale header still showing its own collapsed menu while a new screen's own
81
+ menu has already mounted) and because React 18 StrictMode double-invokes mount/cleanup in dev.
82
+
83
+ **The pair a consumer imports** — the dialog and the control that takes over its floating button:
84
+
85
+ | Job | Import from `@owlmeans/web-panel/consent` | Where it goes |
86
+ |---|---|---|
87
+ | The consent UI — bar, window, spinner (and its floating re-open button) | `PanelCookieConsent` | Beside the router — a `PanelApp` child — once |
88
+ | Asking only in consent countries | `cfg.cookieConsent.geo`, or `appendConsentGeoPlugin(context, plugin)` | The app's `config.ts` / `context.ts` |
89
+ | The "Cookie settings" control in a footer or menu | `PanelConsentMenuWidget` (`label`, `className`, `onSelect?` — defaults to `consentStore.open('reopen')`) | Inside the host's own footer/menu |
90
+ | Hiding the floating button while that control is reachable | `useConsentMenuPresence()` | Called by the always-mounted component that renders the control — mounted ONLY while the control can actually be reached: a component that is merely hidden by CSS (`xl:hidden`) is still mounted and still claims presence, so the floating button vanishes with nothing else to open the dialog; render it conditionally instead (viable's header mounts its hamburger menu only below the full-row breakpoint) |
91
+ | Registering the presence service | `appendConsentWidgetService(context)` | The app's `context.ts` |
92
+
93
+ A footer is the simplest host, because it is always mounted — the control and the presence call
94
+ live in one component:
95
+
96
+ ```tsx
97
+ const CookieSettings: FC = () => {
98
+ useConsentMenuPresence()
99
+ return <PanelConsentMenuWidget label={t('footer.cookies')} className="w-auto text-muted-foreground" />
100
+ }
101
+ ```
102
+
103
+ The widget renders a `<button data-consent-menu-widget>` styled as a menu row (`w-full`,
104
+ `text-popover-foreground`, `hover:bg-accent`); a footer passes `className` to restyle it (merged
105
+ through `cn`) and its own `label` — the packaged default reads "Cookie preferences".
106
+
107
+ **The presence service is optional, and nothing throws without it.** `PanelCookieConsent` checks
108
+ the context for `consentWidget` and, when `appendConsentWidgetService` never ran, renders the plain
109
+ bound dialog with its floating button; `useConsentMenuPresence()` then has nothing to claim and
110
+ does nothing. The presence read itself (`useConsentWidgetPresent`) still needs the service — its
111
+ state resource is registered by it — so any other caller checks first. A dialog that read an
112
+ unregistered state resource threw inside render ("Resource consent-widget-presence not found") and
113
+ blanked the whole application. Pinned by `tests/consent.spec.ts` (`?consent=bare` / `?consent=menu`;
114
+ the configuration by `?consentCfg=window|bar`, `?modeProp=` and `?consentGeo=<CC>|fail`).