@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,47 @@
1
+ ---
2
+ name: editor
3
+ description: Controlled JSON editing and previews with the optional web-panel/editor entrypoint, CodeMirror 6, syntax diagnostics, formatting, copying and read-only state.
4
+ metadata:
5
+ purposes: form, view
6
+ mentions: JsonEditor, JsonEditorProps, JsonEditorLabels
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # JSON editor
11
+
12
+ Import `JsonEditor` and its `JsonEditorProps` / `JsonEditorLabels` from
13
+ `@owlmeans/web-panel/editor`. The root entrypoint does not import the editor, keeping CodeMirror
14
+ out of consumers that do not use it. JSON support, linting and highlighting are package dependencies.
15
+
16
+ ```tsx
17
+ <JsonEditor
18
+ key={record.id}
19
+ value={draft}
20
+ onChange={setDraft}
21
+ onValidityChange={setValid}
22
+ ariaLabel="Record JSON"
23
+ testId="record-json"
24
+ />
25
+ ```
26
+
27
+ - `value` is always raw text. Preserve incomplete drafts; parse at the host's save boundary.
28
+ `onValidityChange` reports syntax validity so a host can disable its save action.
29
+ - A change of document identity keys/remounts the component; an update within the same document
30
+ preserves undo history. External controlled values update the view without echoing `onChange`.
31
+ - `readOnly` disables editing and removes Format; Copy remains available. Use it for previews and
32
+ inspectors. Formatting pretty-prints valid JSON without changing its values.
33
+ - `id`, `testId` and `ariaLabel` address the editable content, including `aria-readonly`,
34
+ `aria-invalid` and its diagnostic description. The wrapper exposes `data-json-editor` and
35
+ `data-valid`. Pass `minHeight` / `maxHeight` in pixels when the host needs another viewport size.
36
+ - `labels` overrides format/copy/copied/copyFailed/readOnly/valid/invalid copy. Components do not
37
+ read an implicit i18n provider; defaults are English.
38
+ - Colours use host shadcn variables, falling back to Tailwind's `--color-*` variables. Brand-specific
39
+ primary/chart colours have standard-token fallbacks. The host still scans web-panel's `src`.
40
+
41
+ Acceptance: `@owlmeans/web-panel`'s `editor.spec.ts` (`bun test tests/editor.spec.ts` in the package); the real Chromium harness checks
42
+ highlighting, formatting, undo, incomplete drafts, validity, external values and read-only controls.
43
+
44
+ ## External docs
45
+
46
+ - https://github.com/codemirror/lang-json — `json()` language support and `jsonParseLinter()` diagnostics for CodeMirror 6.
47
+ - https://codemirror.net/docs/ref/ — editor state/view extensions, controlled transactions and read-only configuration.
@@ -0,0 +1,85 @@
1
+ ---
2
+ name: forms
3
+ description: The web form family (Form, TextInput, Button, SubmitButton, ButtonSelector) and the Toaster surface for sonner toasts.
4
+ metadata:
5
+ purposes: form, feedback
6
+ mentions: TextInput, SubmitButton, ButtonSelector, useFormRef, WebFormProps, Toaster, sonner, appendPermissionDeniedToast
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Forms and toasts
11
+
12
+ | Export | Description |
13
+ |--------|-------------|
14
+ | `Form` / `TextInput` / `Button` / `SubmitButton` / `ButtonSelector` | The web form family. `Form` builds its own `useForm` + `ajvResolver` and borrows only `FormContext` and `schemaToFormDefault` from `@owlmeans/client-panel`; `TextInput` drives `react-hook-form`'s `Controller` directly, and the buttons call `handleSubmit` directly — none of them wraps `ClientForm`, `InputCtrl` or `ActionCtrl` |
15
+
16
+ ## Forms — `Form`, `TextInput`, the buttons
17
+
18
+ `WebFormProps` is `@owlmeans/client-panel`'s `FormProps` plus `className` and `style`. `Form` holds
19
+ the whole model itself — `useForm` with `mode: 'all'`, `delayError: 300`, an `ajvResolver` over
20
+ `validation` with `coerceTypes` and the `ajv-formats` formats — and publishes it through
21
+ `FormProvider` plus `FormContext`, so every control below reads one form.
22
+
23
+ ```tsx
24
+ import { Form, TextInput, SubmitButton, Button } from '@owlmeans/web-panel'
25
+
26
+ <Form decorate validation={schema} onSubmit={async (data, update) => { await save(data); update(data) }}>
27
+ <TextInput name="email" label placeholder hint />
28
+ <TextInput name="password" type="password" label="Password" />
29
+ </Form>
30
+ ```
31
+
32
+ - **`decorate` switches the whole rendering.** With `decorate={true}` the fields go inside a shadcn
33
+ `Card`, the root error surfaces through `Status`, and a `SubmitButton` is rendered in the
34
+ `CardFooter` **whenever `onSubmit` is given** — the caller writes no action. Without it (the
35
+ default) `Form` is a bare flex column: no card, no root-error surface, no submit button, so the
36
+ caller renders its own action. `horizontal`/`vertical` scaling, `className` and `style` land on
37
+ the `Card` when decorated and on that column otherwise.
38
+ - **`formRef`** — a `useFormRef()` ref filled with `{ form, update, loader, error }`, which is how a
39
+ caller drives the form, flips the loader, or plants a field/root error from outside.
40
+ - **`TextInput` takes `label`, `placeholder` and `hint` as `string | boolean`.** `true` resolves
41
+ `<name>.label` / `<name>.placeholder` / `<name>.hint` from the form namespace; a string is used
42
+ verbatim; anything else renders nothing. It also takes `name`, `def`, `type` (any HTML input type,
43
+ default `text`) and `disableAutocomplete`. A field error replaces the hint line.
44
+ - **`Button`** takes a required `label`, `onClick`, `loader` (a `Toggleable` — open disables the
45
+ button and shows the spinner), `size` (`small`/`medium`/`large`), `fullWidth`, and `variant`,
46
+ which maps the MUI vocabulary onto shadcn (`contained` → `default`, `outlined` → `outline`,
47
+ `text` → `ghost`) and forwards a shadcn variant name unchanged.
48
+ - **`SubmitButton`** is that button bound to `handleSubmit`, taking `onSubmit` (or `onClick`) and a
49
+ `label` defaulting to `submit`. It resolves the label with the form `t` itself and passes it down
50
+ with `i18n.suppress` set, so the label is translated once.
51
+ - **`ButtonSelector`** renders one `Button` per entry of `options`, the one equal to `current`
52
+ `contained` and the rest `outlined`, calling `onSelect(option)`. `name` prefixes each option's
53
+ label key as `<name>.<option>`.
54
+
55
+ ## Toasts — `Toaster`
56
+
57
+ An action that succeeded or failed says so in a toast. The surface is `Toaster`; the messages are
58
+ `toast.success(...)` / `toast.error(...)` imported from **`sonner`** by whatever raised them.
59
+
60
+ ```tsx
61
+ import { NavLayout, Toaster } from '@owlmeans/web-panel'
62
+
63
+ export const MainLayout: FC<PropsWithChildren> = ({ children }) => <>
64
+ <NavLayout nav={navConfig} title="My App">{children}</NavLayout>
65
+ <Toaster />
66
+ </>
67
+ ```
68
+
69
+ - **Mount it exactly once, in the layout.** `toast()` writes to a module-global store, so two
70
+ mounted `Toaster`s render every message twice and none renders any of them — both failures are
71
+ silent, which is why `tests/toaster.spec.ts` asserts the count rather than the presence.
72
+ - **Colours come from the app's own tokens** — `--popover`, `--popover-foreground`, `--border` —
73
+ so a toast matches every other floating surface. A caller's `style` merges over them.
74
+ - **The theme follows the `.dark` class on the document element**, not a theme provider: the
75
+ package reads the class an app's `next-themes`, the owl theme provider, or a hand-written
76
+ toggle all set, and depends on none of them. Pass `theme` explicitly to override.
77
+ - Defaults are `richColors`, `closeButton`, `duration={5000}`, `position="top-right"`; every one
78
+ of them, and every other `ToasterProps` field, is overridable per app.
79
+ - `sonner` is a dependency of this package, so nothing is required of the consumer — but an app
80
+ raising its own toasts should declare `sonner` too, at a range that resolves to the same copy.
81
+
82
+ `appendPermissionDeniedToast(context)` plugs into the client entrypoint failure service and
83
+ shows a localized access-denied toast for errors carrying the server IAM marker. Mount `Toaster`
84
+ once as usual. The toast exposes the technical message and incident id in a separate details
85
+ section. The app supplies its locale through its i18n context.
@@ -0,0 +1,203 @@
1
+ ---
2
+ name: navigation
3
+ 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.
4
+ metadata:
5
+ purposes: navigation, layout, screen
6
+ mentions: NavLayout, TopNav, SideNav, MobileNav, Footer, ShellCredit, useShellCredit, PanelNavConfig, PanelNavLink, NavTranslate, defaultNavTranslate, mobileMenu, skipLinkLabel, headerClassName, containerClassName
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Navigation shell
11
+
12
+ ## Navigation — `NavLayout`
13
+
14
+ `NavLayout` is the application shell. A layout entrypoint binds a component that renders it and
15
+ nothing else; the matched screen arrives as `children`. Keep the navigation as data in its own
16
+ module (`src/nav.ts`) so screens, entrypoints and the shell all read the same aliases.
17
+
18
+ ```tsx
19
+ import { NavLayout, HOME } from '@owlmeans/web-panel'
20
+ import type { PanelNavConfig, PanelNavLink } from '@owlmeans/web-panel'
21
+
22
+ export const navConfig: PanelNavConfig = {
23
+ sections: [
24
+ { name: 'home', label: 'Home', items: [{ alias: HOME, label: 'Overview' }] },
25
+ {
26
+ name: 'demo', label: 'Demo', items: [
27
+ { alias: web.session, label: 'Session' },
28
+ { alias: web.about, label: 'About' },
29
+ ]
30
+ },
31
+ ],
32
+ }
33
+
34
+ export const footerLinks: PanelNavLink[] = [
35
+ { alias: HOME, label: 'My App' },
36
+ { href: 'https://owlmeans.com', label: 'OwlMeans', open: true },
37
+ ]
38
+
39
+ export const MainLayout: FC<PropsWithChildren> = ({ children }) =>
40
+ <NavLayout nav={navConfig} title="My App" footer={footerLinks}>{children}</NavLayout>
41
+ ```
42
+
43
+ **Navigation is two-layer.** The top menu lists **sections** — the first level; the side menu lists
44
+ the **active section's screens** — the second. A section holding a single screen renders **no side
45
+ menu at all**: the model owns that rule (`showSide`), so a section that later grows a second screen
46
+ gains its menu with no layout change. `NavLayout` mounts `SideNav` twice — `variant="side"` as the
47
+ `hidden md:block` column beside the content, `variant="bar"` as the `md:hidden` strip under the
48
+ header. Both render the same items; only one is visible at a time.
49
+
50
+ | Component | Props |
51
+ |---|---|
52
+ | `NavLayout` | `nav: PanelNavConfig`, `navTestId?: string`, `translate?`, `title?: ReactNode`, `home?: string` (brand target — defaults to the first section's first item), `actions?: ReactNode`, `mobileMenu?: boolean`, `skipLinkLabel?: string \| false`, `themeToggle?: boolean \| { labels? }`, `footer?: PanelNavLink[] \| ReactNode`, `headerClassName?`, `contentClassName?`, `containerClassName?`, `className?`, `style?` |
53
+ | `TopNav` | `config: PanelNavConfig`, `translate?`, `ariaLabel?`, `className?`, `style?` |
54
+ | `SideNav` | the same, plus `variant?: 'side' \| 'bar'` |
55
+ | `MobileNav` | the same as `TopNav`; `ariaLabel` names the landmark inside the sheet, `className`/`style` land on the trigger button |
56
+ | `Footer` | `links?: PanelNavLink[]`, `content?: ReactNode` (a full-width block — see below), `translate?`, `containerClassName?` (the shell's rhythm, so the footer row lines up with the header and content), `children?` (joins the centred link row), `themeToggle?: boolean \| { labels? }` (the switcher beside the credit), `className?`, `style?` |
57
+ | `ShellCredit` / `useShellCredit` | `className?`; the platform/owner credit line `Footer` always renders — see below |
58
+
59
+ **The narrow-viewport menu is opt-in: `mobileMenu`.** Off (the default) the shell is exactly the
60
+ two-layer layout above at every width. On, below `md` (768px) the section menu is hidden
61
+ (`hidden md:flex`) and `MobileNav` puts a menu button — accessible name "Menu", a 44px target, a
62
+ solid focus ring — at the end of the actions row, so `actions` ("Get started", sign-in) stay in
63
+ the header at every width. The button opens a shadcn `Sheet` from the right listing every section:
64
+ a multi-screen section as its name over links to its screens, a single-screen section as one link
65
+ carrying the section's own label, so no destination appears twice. Labels, keys and `translate`
66
+ are the menus' own (`nav.<section>`, `modules.<alias>`); the button's name, the sheet title and
67
+ its close button resolve `shell.menu` / `shell.close` — outside the `nav.` family, because an
68
+ app may have a section called `menu`. Rules the component owns:
69
+
70
+ - **The screen strip is not mounted when `mobileMenu` is on.** The sheet already lists the active
71
+ section's screens; a strip under the header would be a second menu for the same level. The side
72
+ column (`hidden md:block`) is untouched — wide viewports are the same shell either way.
73
+ - **An entry navigates AND closes from its own click handler.** It is an `<a href>` (focusable,
74
+ openable in a new tab) whose `onClick` calls `preventDefault()` for in-app navigation — which a
75
+ dialog never notices, so a sheet left to close itself stays open over the screen it just
76
+ navigated to.
77
+ - **The sheet states both halves of its surface** (`bg-background text-foreground`): it is
78
+ portalled to the document body and inherits nothing from the shell.
79
+ - Pinned by `nav.spec.ts` → "the narrow-viewport menu", at 375px and 1280px, with and without
80
+ the prop (`?mobileMenu=1` in the harness).
81
+
82
+ **The skip link comes first, and `main` is its target.** `NavLayout` renders
83
+ `<a href="#main" data-skip-link>` as the FIRST child of its root — before `<header>`, never inside
84
+ it, because `header > div` (first) is the shared-rhythm row the layout pins locate. It is `sr-only`
85
+ until focused, then a pill fixed in the top-left corner (`bg-foreground text-background`,
86
+ `rounded-full`, `z-50`, the 3px `--ring` focus ring); its padding is `focus:`-only, since a plain
87
+ `px-*` sorts after `sr-only` and leaves a padded box behind the clip. Activating it focuses
88
+ `<main id="main" tabIndex={-1}>` by hand (`preventDefault` + `focus()`), because a fragment
89
+ navigation changes the location and the router reads that as navigation. The label is
90
+ `skipLinkLabel`, defaulting to `translate('shell.skip', 'Skip to content')`. `skipLinkLabel={false}`
91
+ renders no link AND leaves `main` without the id: an application rendering its own skip link owns
92
+ its own `#main`, and no two elements may share it. A screen never renders a second `<main>`.
93
+ Pinned by `nav.spec.ts` → "the skip link" (Tab from the page start, Enter lands on `main#main`,
94
+ `?skip=off`).
95
+
96
+ **A node `footer` is a full-width block, never a replacement.** An array renders the centred link
97
+ row. A node — an application's own footer layout: a brand, a description, link columns — goes to
98
+ `Footer`'s `content` and renders as a `w-full self-stretch text-start` block (`data-footer-content`)
99
+ inside the footer's container, above the credit. The container keeps `items-center` for the link
100
+ row and the credit; only the block stretches. It used to land INSIDE the centred link row, where
101
+ it shrink-wrapped to its content in the middle of the page. `ShellCredit` stays the last thing the
102
+ footer renders in every case — the container's own last child, or, with `themeToggle`, first in the
103
+ bottom row `[data-footer-bottom]` with the switcher after it. Pinned by `nav.spec.ts` → "a node footer" (`?footer=node`).
104
+
105
+ **The style slots are REGIONS, and each region is its own SURFACE.** `className` is the root —
106
+ the full-height page *behind* the header, side menu and footer. `headerClassName` is the sticky
107
+ top bar. `contentClassName` is the content area. `containerClassName` is width and padding for
108
+ all three at once, never colour.
109
+
110
+ The header paints an opaque background of its own, because it is sticky and content scrolls
111
+ beneath it. That makes it a **different surface from the root**, so it states `text-foreground`
112
+ alongside its `bg-background` — not as decoration, and not redundantly. A root carrying a
113
+ contrasting pair (`className="bg-primary text-primary-foreground"`, an ordinary dark shell)
114
+ otherwise inherits its near-white foreground into a near-white bar, and every header child that
115
+ states no colour of its own — the brand, a ghost-variant action button — is painted in the
116
+ foreground of a surface it is not on. It type-checks, it builds, it renders, and the menu is
117
+ invisible. Pinned by `tests/nav.spec.ts` → "the header is its own surface", which measures
118
+ rendered lightness rather than class names; the harness root carries a dark shell permanently so
119
+ every navigation test runs against that case.
120
+
121
+ **The header is opaque even when `headerClassName` fails to be.** Behind the header's own visible
122
+ content sits a `[data-nav-backdrop]` layer that always paints `bg-background`, at negative
123
+ z-index inside the header's own `isolate` stacking context — so it never covers a caller's actual
124
+ header content, only whatever the header's own background would have been. It exists because
125
+ `headerClassName` is free text a design or restyle pass writes, and three shapes of it leave
126
+ tailwind-merge with no background utility at all on the header: a bare `bg-transparent`, an alpha
127
+ surface (`bg-<x>/50`), or Tailwind v3's dead syntax for referencing a CSS variable
128
+ (`bg-[--my-var]` — square brackets; v4's real shorthand is `bg-(--my-var)`, parentheses). Any of
129
+ those used to leave the sticky header fully see-through, with page content visibly scrolling
130
+ through the menu. A caller that genuinely wants a coloured bar still gets it: `headerClassName`'s
131
+ own background renders on top of the backdrop. Pinned by `nav.spec.ts` → "a broken headerClassName
132
+ still leaves the backdrop layer opaque".
133
+
134
+ **`Footer` always renders the platform/owner credit line, and there is no prop that hides it.**
135
+ Below the content block and the links (or on its own, when a layout passes no `footer` at all — `NavLayout` renders
136
+ `<Footer>` unconditionally now), `ShellCredit` shows "Powered by OwlMeans" and the owner's own
137
+ copyright notice, resolved from `security.auth.login.credit` via `resolveCredit`
138
+ (`@owlmeans/client-auth/login`) — the SAME resolver and the SAME config the sign-in screen's
139
+ `LoginCredit` reads, so an owner who pays to drop the platform credit (`poweredBy: false`) drops
140
+ it everywhere, not only on a screen a signed-in visitor may never see again. Order is the opposite
141
+ of the sign-in screen's: the owner's own notice leads, the platform credit follows — a footer is
142
+ read as "whose page is this, and who built it". The links row and the credit are both centred
143
+ (`justify-center`), not left-aligned. `useShellCredit()` is exported separately so a caller that
144
+ needs to know whether there is anything to show (without rendering it) can ask, exactly how
145
+ `Footer` itself decides whether to render `null`. Pinned by `nav.spec.ts` → "the shell footer
146
+ credit".
147
+
148
+ **Every style slot is MERGED over its default — none of them substitutes.** `className`,
149
+ `headerClassName`, `contentClassName` and `containerClassName` all go through `cn`, so a caller
150
+ names only the utility it wants to move and tailwind-merge drops just the one it conflicts with.
151
+ This matters most for `containerClassName`, whose default is a four-part rhythm
152
+ (`mx-auto w-full max-w-6xl px-4`): a design asking for a wider page writes `max-w-[1280px]` and
153
+ means *wider*, not *unpadded and uncentred*. Substituting there took `px-4` and `mx-auto` down
154
+ with the width and left the header, content and footer all flush to the window edge. Pinned by
155
+ `nav.spec.ts` → "a width-only rhythm override keeps the side padding"; the harness passes a
156
+ width-only override permanently.
157
+
158
+ **A dark top bar is asked for with `headerClassName`**, giving it both halves
159
+ (`bg-secondary text-secondary-foreground`) — never by colouring the root and expecting the bar
160
+ to follow.
161
+
162
+ **The shell reads exactly these colour variables**: `--background` (page and top bar),
163
+ `--foreground` (active section link), `--muted-foreground` (resting section links),
164
+ `--accent`/`--accent-foreground` (active side-menu item), `--border` (the header, side-menu and
165
+ footer rules) and `--primary` — the footer renders its entries through `Link`, which paints
166
+ `text-primary`; `mobileMenu` adds `--ring` (the menu button's and the sheet entries' focus rings)
167
+ and a `bg-black/50` overlay. It reads **no `--sidebar*` variable at all**. So `--muted-foreground` is not merely
168
+ the text colour of the `--muted` surface — it is secondary text sitting directly on `--background`,
169
+ and a theme that lightens it to suit a dark muted panel loses its top menu.
170
+
171
+ Rules that make the shell behave:
172
+
173
+ - **Labels never reach for i18n implicitly.** `translate` is a **prop** (`NavTranslate`), defaulting
174
+ to `defaultNavTranslate`, which returns the fallback. An app mounted with `renderApp` from
175
+ `@owlmeans/web-client` has no i18n provider, and the panel i18n hook dereferences `i18n.options`
176
+ on the empty object `react-i18next` returns without an instance — a throw inside render that
177
+ blanks the whole app. An app that does have i18n passes its own
178
+ `(key, defaultValue) => string` resolver. Order: literal `label` → `translate(key, humanized)` →
179
+ humanized alias. Default keys are
180
+ `nav.<section>` for sections and `modules.<alias>` for items and footer links — the same family
181
+ `Link` uses.
182
+ - **Menu entries are real links.** `TopNav` puts the resolved path on `href` and calls
183
+ `preventDefault()` in `onClick`, navigating in-app through `nav.press`. Never drop the `href`: an
184
+ `<a>` without one is not focusable, does not answer the keyboard, cannot be opened in a new tab,
185
+ and does not even carry the `link` role.
186
+ - **A parent route needs a `default: true` child.** A frontend entrypoint that has children but no
187
+ child declared `default: true` renders blank at its own path — give a grouping screen an index
188
+ child at `'/'`.
189
+ - **Vendor `navigation-menu` and `sheet`.** `SideNav` builds on the package-local `Button`; `TopNav`
190
+ uses the package-local shadcn `navigation-menu` primitive and `MobileNav` the package-local
191
+ `sheet` (over `@radix-ui/react-dialog`, a peer) — see *Consumer setup — package boundary and Tailwind* in [SKILL.md](../SKILL.md).
192
+
193
+ ## Stable selectors and detail screens
194
+
195
+ `PanelNavSection.testId` and `PanelNavItem.testId` optionally name their rendered destinations;
196
+ `NavLayout.navTestId` names the desktop navigation landmark. With `mobileMenu`, only the current
197
+ viewport's section menu is mounted, keeping the same destination selector unique when the sheet
198
+ opens. Side/bar item selectors are emitted only by the visible variant. Hosts keep their selectors
199
+ in navigation data rather than querying translated text or styling classes.
200
+
201
+ When an unlisted detail screen has no listed ancestor, the headless model selects the section of
202
+ the longest listed pathname prefix. This covers sibling route declarations such as `/items` and
203
+ `/items/:id` without changing their route hierarchy.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: picker
3
+ 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.
4
+ metadata:
5
+ purposes: picker, form
6
+ mentions: IconColorPicker, ColorPicker, IconPicker, ColorSwatches, IconGrid, IconTile, ColorDot, usePickerTranslate, pickerColorHelper, pickerIconHelper, PICKER_COLORS, PICKER_COLOR_KEYS, PICKER_ICON_NAMES, @owlmeans/web-panel/picker
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Icon and colour picker
11
+
12
+ ## Subpath: `./picker`
13
+
14
+ **Subpath exports**
15
+
16
+ - `./picker` — the standard icon + colour picker and its parts (`IconColorPicker`, `ColorPicker`,
17
+ `IconPicker`, `ColorSwatches`, `IconGrid`, `IconTile`, `ColorDot`, `usePickerTranslate`), the icon
18
+ components (`PICKER_ICONS`, `pickerIconHelper`) and everything of `./picker/vocabulary` — see
19
+ below. Not re-exported by the root, so only a bundle importing it carries
20
+ the icon catalogue
21
+ - `./picker/vocabulary` — the React-free half: the 24-colour palette (`PICKER_COLORS`,
22
+ `PICKER_COLOR_KEYS`), the icon catalogue's names, categories and search words
23
+ (`PICKER_ICON_ENTRIES`, `PICKER_ICON_NAMES`, `PICKER_ICON_CATEGORIES`), the fallbacks and
24
+ `pickerColorHelper` — safe on a server, in a seed or a Node build script
25
+
26
+ The standard editor and renderer of an icon and a colour **a person chooses** — a workcard type's
27
+ or a status flow's mark, a label, a category. One component family, so every application offers
28
+ the same 24 colours, the same curated icons and the same behaviour on a desktop and a phone.
29
+
30
+ ```ts
31
+ import {
32
+ IconColorPicker, ColorPicker, IconPicker, ColorSwatches, IconGrid, IconTile, ColorDot, usePickerTranslate,
33
+ pickerColorHelper, pickerIconHelper, PICKER_COLORS, PICKER_COLOR_KEYS,
34
+ } from '@owlmeans/web-panel/picker'
35
+ // Server, seed, build script — the data and the colour helper without React or icons:
36
+ // import { pickerColorHelper, PICKER_COLOR_KEYS } from '@owlmeans/web-panel/picker/vocabulary'
37
+ ```
38
+
39
+ ### Which part
40
+
41
+ | Part | When |
42
+ |---|---|
43
+ | `IconColorPicker` | Both halves of a mark. One trigger (the tile, "Rocket · Indigo", a chevron — or `trigger="tile"` for the tile alone) opens swatches above a searchable, categorized icon grid tinted in the chosen colour. Stays open for the other half; Esc, a click outside or (sheet) Done closes it |
44
+ | `ColorPicker` | A colour alone (`trigger="button"` or `"dot"`). Closes on a swatch. `colors` takes an application palette — e.g. status tones |
45
+ | `IconPicker` | An icon alone, tinted in `color`. Closes on a pick |
46
+ | `ColorSwatches`, `IconGrid` | Inline, for a dialog or sheet the application already owns — no trigger, no surface of their own |
47
+ | `IconTile` | A stored mark shown: the icon in the colour's ink on its ground (`variant="tile"`), or the ink alone (`"plain"`); `size` `xs`/`sm`/`md`/`lg`; `label` makes it an image, else decorative |
48
+ | `ColorDot` | A stored colour as a dot in its ink (`size` `xs`/`sm`/`md`) |
49
+ | `usePickerTranslate()` | The `translate` for an app rendered by `PanelApp` / `render()` — the packaged bundle in the current language |
50
+
51
+ ### Values
52
+
53
+ - **Colour**: a palette key — `red orange amber yellow lime green emerald teal cyan sky blue indigo
54
+ violet purple fuchsia pink rose maroon brown olive navy slate stone graphite` (`PICKER_COLOR_KEYS`,
55
+ hue order) — or, only with `customColors`, a lowercase `#rrggbb`. Never a label ("Indigo").
56
+ - **Icon**: a kebab-case lucide name from the catalogue (`PICKER_ICON_NAMES`, ~250 in ten categories,
57
+ a superset of the planning kits' icons). Never a component, never a label.
58
+ - `IconColorPicker` emits `onChange({ icon, color })` — both halves as they now stand; a half
59
+ never chosen stays `undefined`, never `null`. `value` tolerates `null`s and absent halves.
60
+ - An unknown stored value renders the fallback (`slate`, `circle`) and never throws, so a value
61
+ from an older palette or a typo never breaks a page.
62
+ - `customColors` (default `false`) adds a colour wheel (react-colorful) and a hex field: a full
63
+ `#rrggbb` commits while typing, `#rgb` / `abc` on Enter or blur, always normalized to lowercase six
64
+ digits; anything else marks the field `aria-invalid` and changes nothing. A custom colour's ink
65
+ and grounds are derived to keep 4.5:1 in both modes.
66
+
67
+ ### Surfaces
68
+
69
+ `surface="auto"` (default) opens a popover from 768px up and a bottom sheet below — decided when
70
+ it OPENS, kept until it closes. `surface="popover" | "sheet"` forces one. The popover is modal, so
71
+ inside an application's own Dialog or Sheet the wheel scrolls it and focus stays in it; it keeps
72
+ 12px off the edges and scrolls inside rather than growing past the viewport. The sheet has a grab
73
+ handle, a sticky header with the preview and a 44px Done button, `88dvh` at most and safe-area
74
+ padding. Below 768px and on coarse pointers every cell, chip, field and button is at least 44px;
75
+ the search field takes focus on open only for a fine pointer (no keyboard pops up on a phone).
76
+ Keyboard: arrows move in two dimensions through swatches and icons (one tab stop each), Home/End,
77
+ ArrowDown from the search into the grid and ArrowUp back, Enter/Space picks, Esc closes and focus
78
+ returns to the trigger. Every control is a `<button type="button">` with an `aria-label`, so a
79
+ pick never submits an enclosing form.
80
+
81
+ ### Strings
82
+
83
+ The parts never read i18n implicitly — rendered without an i18n instance they show English. Pass
84
+ `translate={usePickerTranslate()}` in an app rendered by `PanelApp` / `render()`: chrome, colour
85
+ names and category names come from the lib-tier `picker` bundle in eight languages (en, pl, ru, be,
86
+ uk, es, de, fr); icon names stay English. An app overrides a string at the App tier in the `lib`
87
+ namespace (`i18nHelper.addI18nApp('de', 'picker', { colors: { teal: 'Türkis' } }, { ns: LIB_NAMESPACE })`).
88
+ Keys: `label`, `icon`, `color`, `placeholder.{both,icon,color}`, `nothing`, `done`, `search`,
89
+ `searchPlaceholder`, `categoriesLabel`, `all`, `results` (`{count}`), `empty` (`{query}`), `clear`,
90
+ `custom`, `hex`, `invalidHex`, `colors.<key>`, `categories.<category>`. `label` and `placeholder`
91
+ props override per instance. Only the 24 palette names translate: an application palette passed as
92
+ `colors` shows its `label`s as given, so translate them before passing them in.
93
+
94
+ ### RIGHT and WRONG
95
+
96
+ ```tsx
97
+ import type { IconColorChange } from '@owlmeans/web-panel/picker'
98
+
99
+ // RIGHT — local state
100
+ const translate = usePickerTranslate()
101
+ const [mark, setMark] = useState<IconColorChange>({ icon: type.icon, color: type.tone })
102
+ <IconColorPicker label="Mark" value={mark} onChange={setMark} translate={translate} />
103
+
104
+ // RIGHT — react-hook-form: the field holds { icon, color }; the picker is the whole control
105
+ <Controller
106
+ name="mark" control={form.control}
107
+ render={({ field }) => <IconColorPicker
108
+ id="mark" label="Mark" value={field.value} onChange={field.onChange} disabled={field.disabled} translate={translate}
109
+ />}
110
+ />
111
+ // …and on save: { tone: values.mark.color, icon: values.mark.icon }
112
+
113
+ // WRONG — a Select of colour names, a hand-made swatch row, or a label stored instead of the key
114
+ <Select value={tone} onValueChange={setTone}>{PICKER_COLOR_KEYS.map(k => <SelectItem value={k}>{k}</SelectItem>)}</Select>
115
+ {['red', 'blue'].map(c => <button className={`bg-${c}-500`} onClick={() => setTone(c)} />)}
116
+ onChange={next => save({ tone: 'Indigo' })}
117
+ // WRONG — the picker hands over a value, not an event
118
+ <ColorPicker value={field.value} onChange={event => field.onChange(event.target.value)} />
119
+ ```
120
+
121
+ ### Rendering a stored mark
122
+
123
+ ```tsx
124
+ <IconTile icon={type.icon} color={type.tone} size="sm" /> // list row, chip, header
125
+ <IconTile icon={flow.icon} color={flow.tone} variant="plain" /> // the ink alone, inline with text
126
+ <ColorDot color={label.color} /> // a dot
127
+ <span style={pickerColorHelper.styleOf(card.color)} className="text-(--pick-ink)">…</span> // custom markup
128
+ ```
129
+
130
+ `pickerColorHelper.styleOf(value, colors?)` returns the custom properties `--pick-swatch`,
131
+ `--pick-ink`, `--pick-soft`, `--pick-ink-dark`, `--pick-soft-dark` (a plain string record — it goes
132
+ straight into `style`). The parts switch to the dark values themselves, through explicit
133
+ arbitrary variants on web-panel's scheme contract (`.dark` on `<html>`, or the system's dark
134
+ unless `.light`) — never through the app's `dark:` variant. A hand-written element using
135
+ `styleOf` reads `--pick-ink` / `--pick-ink-dark` itself. `pickerColorHelper.resolve(value)` gives
136
+ every field (and `custom: true` for a hex); `hashKey(seed)` gives a stable palette key for a record
137
+ that has none. Code-chosen tones (a status's meaning) stay the app's own classes; a colour a PERSON
138
+ chose always renders through these parts.
139
+
140
+ **DOM hooks** (stable, used by end-to-end suites): the trigger `data-picker-trigger`, the open
141
+ surface `data-picker-surface="popover|sheet"`, a swatch `data-picker-color="<key>"` (the custom
142
+ row `"custom"`, `data-selected` while a custom value is chosen), an icon cell
143
+ `data-picker-icon="<name>"`, a chip `data-picker-category`, the search field `data-picker-search`,
144
+ the hex field `data-picker-hex`, the sheet's Done `data-picker-done`; `IconTile` carries
145
+ `data-icon-tile`, `data-icon`, `data-color`, `ColorDot` `data-color-dot`. Picker parts never carry
146
+ `data-tone` or `data-slot="button"` — an application's own rules on those never reach them.
147
+
148
+ ### Consumer setup
149
+
150
+ - `@radix-ui/react-popover` is a peer, like the other Radix primitives: keep it on the SAME Radix
151
+ generation as `@radix-ui/react-dialog` (update them together). The two share the dismissable-layer
152
+ and focus-scope stacks; a popover from another generation inside a Dialog is treated as an outside
153
+ click and loses focus to the dialog. `react-colorful` is a dependency of this package.
154
+ - The `@source` line for this package's `src` (see *Consumer setup — package boundary and Tailwind* in [SKILL.md](../SKILL.md)) is what brings the
155
+ picker's classes — including its `[.dark_&]:` and `pointer-coarse:` variants — into the stylesheet.
156
+ - Tokens read: `--popover`, `--popover-foreground`, `--border`, `--input`, `--ring`, `--accent`,
157
+ `--accent-foreground`, `--primary`, `--primary-foreground`, `--muted-foreground`, `--foreground`,
158
+ `--destructive`.
159
+
160
+ Pinned by `tests/picker.spec.ts` (harness `/picker`: `?custom=1`, `?inSheet=1`, `?bare=1`,
161
+ `?surface=…`, `?compact=1`, `?empty=1`, `?inline=1`, `?dark=1`) and
162
+ `tests/picker-vocabulary.spec.ts` (palette contrast and OKLab distance, hex handling, catalogue ↔
163
+ components). `PICKER_SHOTS_DIR=<dir> bun test tests/picker-shots.spec.ts` writes every scenario's
164
+ screenshot at 1280 and 375, light and dark.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: reload
3
+ description: The global connection-lost prompt — SocketReloadDialog, the cfg.socket.reloadDialog opt-in, and its Try again and Reload page actions.
4
+ metadata:
5
+ purposes: feedback, config
6
+ mentions: SocketReloadDialog, reloadDialog, useSocketStatus, useSocketRetry, appendSocketStatus
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Reload prompt
11
+
12
+ | Export | Description |
13
+ |--------|-------------|
14
+ | `SocketReloadDialog` | The global "connection lost — try again / reload" prompt (opt in via `cfg.socket.reloadDialog`) `PanelApp` mounts automatically — see below. The hooks it reads, `useSocketStatus` and `useSocketRetry`, are imported from `@owlmeans/client-socket`, not from this package |
15
+
16
+ ## Reload prompt — `SocketReloadDialog`
17
+
18
+ `makeContext` calls `appendSocketStatus` from `@owlmeans/client-socket` unconditionally, and
19
+ `PanelApp` mounts `SocketReloadDialog` as a sibling of the Router — exactly where
20
+ `PanelCookieConsent` lives, and for the same reason: a dialog mounted inside a route is torn down
21
+ on every navigation. Neither does anything unless an app opts in:
22
+
23
+ ```typescript
24
+ cfg.socket = { reloadDialog: true }
25
+ ```
26
+
27
+ Once any `socketClientHelper.ws()`/`useWs()` connection in the app has exhausted its own retry budget
28
+ (`useSocketStatus() === 'lost'`), a global, blocking `AlertDialog` covers the screen — no Escape,
29
+ no outside click, two actions:
30
+
31
+ - **"Try again"** (`data-socket-retry-action`) — `useSocketRetry().retry()` revives every lost
32
+ connection (see the `client-socket` skill). The dialog stays up with the button disabled and
33
+ reading "Reconnecting…" while they retry, closes once the aggregate is `'online'`, and offers
34
+ both buttons again if it falls back to `'lost'`.
35
+ - **"Reload page"** (`data-socket-reload-action`) — `window.location.reload()`, the fallback that
36
+ always works.
37
+
38
+ The status service also retries by itself when the tab becomes visible, the window gains focus or
39
+ the browser comes back online, so a socket that died in a background tab is usually back before
40
+ anyone presses anything — an open dialog shows "Reconnecting…" through that too. Strings are
41
+ lib-tier (`useI18nLib('socket', 'reload')`: `title`, `description`, `action`, `retry`,
42
+ `retrying`), 8 languages, under `src/components/socket/i18n/`.
43
+
44
+ Leave `cfg.socket.reloadDialog` unset (or `false`) for an app that would rather show its own
45
+ inline "reconnecting…" state — `useSocketStatus()` from `@owlmeans/client-socket` serves that,
46
+ independent of the dialog.
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: sign-in
3
+ description: The sign-in screen's terms confirmation, privacy notice and provider disclosure — LoginTerms, LoginPrivacyNotice, LoginProviderNote and their DOM hooks.
4
+ metadata:
5
+ purposes: auth
6
+ mentions: LoginTerms, LoginPrivacyNotice, LoginProviderNote, LoginScreen, LocalizedLoginScreen, appendLoginScreen, data-login-terms, data-login-provider
7
+ ---
8
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
9
+
10
+ # @owlmeans/web-panel — Sign-in screen
11
+
12
+ | Export | Description |
13
+ |--------|-------------|
14
+ | `LoginScreen` / `LocalizedLoginScreen` / `appendLoginScreen` | The identity-provider choice screen — see `login-methods`. `LoginScreen` is pure w.r.t. `locale` too, exactly like `translate`: it is a prop, defaulting to nothing, never an implicit `useLanguage()` read, because a component that reaches for i18n context directly crashes an app mounted without one. `LocalizedLoginScreen` supplies `useLanguage()`'s value when the caller does not pass its own |
15
+
16
+ ## The terms confirmation — `LoginTerms`, `LoginPrivacyNotice`
17
+
18
+ `components/login/terms.tsx` renders `LoginTermsModel` (`@owlmeans/client-panel/auth`) via
19
+ `loginTermsHelper.termsSentence` + `.termsLabelResolver` (`@owlmeans/client-auth/login`) rather than re-deriving
20
+ link/label pairs itself. **`[data-login-terms]` marks exactly one checkbox — or NONE, once
21
+ `model.terms.deferred` is true** (`LoginScreen` renders `LoginTerms` when not deferred,
22
+ `LoginPrivacyNotice` when it is): an e2e suite elsewhere in the platform treats the checkbox as a
23
+ strict, at-most-one-match locator, so a change here must never add a second one, whatever
24
+ billing/product/custom documents a configuration adds. `[data-login-privacy]` is a SIBLING
25
+ paragraph of the checkbox's `<label>`, never nested inside it — a privacy disclosure is not
26
+ something the checkbox consents to — and it is exported ON ITS OWN as `LoginPrivacyNotice`: it
27
+ still renders while deferred, since the disclosure was never the checkbox's to remove. A linked
28
+ document/notice fragment carries `data-login-document="<key>"`. `[data-login-revised]` renders only
29
+ when NOT deferred and the resolved terms carry a `revisedAt` (i.e. the configuration set
30
+ `showRevision: true` and at least one document has its own revision date) — deferred, that date
31
+ belongs to the document the checkbox agreed to, and there is no checkbox on this screen to attach it
32
+ to. `LoginTerms`/`LoginPrivacyNotice` take `locale?: string` — from `LoginScreen`'s own `locale`
33
+ prop, never read from context directly — for `Intl.ListFormat` and a custom document's locale-keyed
34
+ `labelMap`. Method buttons carry `aria-disabled={model.blocked || undefined}`, never a literal
35
+ `"false"` — a deferred screen (which never sets `blocked`) then renders identically to an unblocked
36
+ ordinary one, with no special case. Pinned by `tests/login.spec.ts` → the "with billing, product and
37
+ custom documents configured" and "the Terms confirmation deferred to a step" blocks.
38
+
39
+ ## The provider disclosure — `LoginProviderNote`
40
+
41
+ `LoginScreen` renders `useLoginMethods().provider` (`@owlmeans/client-panel/auth`, resolution rules
42
+ there) through `components/login/provider.tsx`:
43
+ `<div role="note" data-login-provider data-placement="top|inline">` — a `ShieldCheck` icon, the
44
+ sentence, and, when `info` resolved, `<a data-login-provider-info target="_blank"
45
+ rel="noopener noreferrer">More information</a>`. Never a `header`/`nav`: it is a disclosure, not a
46
+ landmark.
47
+
48
+ - **No provider → the DOM is exactly the pre-provider screen** (no note, no stage, title
49
+ `login.title`).
50
+ - **`top`** (the platform's own hosts) — the strip is the FIRST child of `[data-login-screen]`,
51
+ full width, at the screen's top edge; the card sits in `<div data-login-stage>`, which takes the
52
+ remaining height and centres it. The screen's column layout, its zero padding, the stage's flex
53
+ centring/padding and the strip's width are INLINE styles (same reason as the screen height —
54
+ `login-methods` → Layout); classes there are cosmetic only.
55
+ - **`inline`** (an owner's own domain) — the note is one line inside `CardContent`, directly under
56
+ the methods and above the terms; the screen keeps its ordinary shape.
57
+ - The card title becomes `login.provider.title` ("Sign in to {{product}}") whenever a provider
58
+ resolves; `props.title` still wins.
59
+ - Copy: `login.provider.{title,top,inline,more}` in all eight languages
60
+ (`components/login/i18n/*.json`), registered by `components/login/i18n.ts` into the SAME `auth`
61
+ library resource as `client-auth`'s login copy (deep-merged; this package owns only the
62
+ `login.provider` subtree). Names are filled after translation by `loginProviderHelper.fill`.
63
+ - Still exactly one `[data-login-terms]` in either placement. Pinned by `tests/login.spec.ts` →
64
+ "the provider disclosure" (`?provider=top|inline` in the harness) and
65
+ `tests/login-provider.spec.ts` (resolver, `fill`, eight-language key/placeholder parity).