@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,70 @@
1
+ import { useCallback, useRef, useState } from 'react'
2
+ import type { KeyboardEvent } from 'react'
3
+ import type { RovingGrid, RovingGridOptions } from './types.local.js'
4
+
5
+ /** What marks a roving item inside the container. */
6
+ const ITEM = '[data-roving-item]'
7
+
8
+ /**
9
+ * Arrow-key focus across the buttons of a grid (or one row): a single tab stop, the arrows move
10
+ * within it — Left/Right along, Up/Down a whole row (counted from the layout, so it follows
11
+ * whatever the CSS grid wrapped to), Home/End to the ends. Enter and Space are the buttons' own.
12
+ */
13
+ export const useRovingGrid = ({ count, selected, onExitUp, grid = true }: RovingGridOptions): RovingGrid => {
14
+ const ref = useRef<HTMLDivElement | null>(null)
15
+ const [current, setCurrent] = useState<number | null>(null)
16
+ const active = Math.min(Math.max(current ?? selected, 0), Math.max(count - 1, 0))
17
+
18
+ const items = (): HTMLElement[] => Array.from(ref.current?.querySelectorAll<HTMLElement>(ITEM) ?? [])
19
+
20
+ const columnsOf = (list: HTMLElement[]): number => {
21
+ const top = list[0]?.offsetTop
22
+ const first = list.findIndex(item => item.offsetTop !== top)
23
+
24
+ return first < 0 ? list.length : Math.max(first, 1)
25
+ }
26
+
27
+ const onKeyDown = (event: KeyboardEvent<HTMLElement>): void => {
28
+ if (event.altKey || event.ctrlKey || event.metaKey) {
29
+ return
30
+ }
31
+ const list = items()
32
+ const from = list.indexOf(event.target as HTMLElement)
33
+ if (from < 0) {
34
+ return
35
+ }
36
+ const columns = grid ? columnsOf(list) : list.length
37
+ const step: Record<string, number> = {
38
+ ArrowRight: 1, ArrowLeft: -1, ...(grid ? { ArrowDown: columns, ArrowUp: -columns } : {}),
39
+ }
40
+ let to: number
41
+ if (event.key === 'Home') {
42
+ to = 0
43
+ } else if (event.key === 'End') {
44
+ to = list.length - 1
45
+ } else if (event.key in step) {
46
+ to = from + step[event.key]
47
+ if (event.key === 'ArrowUp' && to < 0 && onExitUp != null) {
48
+ event.preventDefault()
49
+ onExitUp()
50
+
51
+ return
52
+ }
53
+ to = Math.min(Math.max(to, 0), list.length - 1)
54
+ } else {
55
+ return
56
+ }
57
+ event.preventDefault()
58
+ setCurrent(to)
59
+ list[to]?.focus()
60
+ }
61
+
62
+ const tabIndexOf = (index: number): number => index === active ? 0 : -1
63
+
64
+ const focusCurrent = useCallback(() => {
65
+ const list = items()
66
+ ;(list.find(item => item.tabIndex === 0) ?? list[0])?.focus()
67
+ }, [])
68
+
69
+ return { ref, onKeyDown, tabIndexOf, setCurrent, focusCurrent }
70
+ }
@@ -0,0 +1,62 @@
1
+ import { useRef } from 'react'
2
+ import type { FC } from 'react'
3
+ import { cn } from '../../@/lib/utils.js'
4
+ import { Popover, PopoverAnchor, PopoverContent } from '../../@/components/ui/popover.js'
5
+ import { Sheet, SheetContent, SheetTitle } from '../../@/components/ui/sheet.js'
6
+ import type { PickerSurfaceProps } from './types.local.js'
7
+ import { GRAB, POPOVER, SHEET, TALL } from './consts.local.js'
8
+
9
+ /**
10
+ * Where a picker's panel opens: a popover beside the trigger, or a sheet from the bottom edge.
11
+ *
12
+ * The popover is MODAL. That is what makes it work inside an application's own Dialog or Sheet:
13
+ * the topmost scroll lock and focus scope are its own, so the mouse wheel scrolls it and focus stays
14
+ * in it, where a non-modal one portalled outside the dialog is locked out of both. It keeps 12px off
15
+ * the viewport's edges and never grows past the space it has (`--radix-popover-content-available-height`),
16
+ * scrolling inside instead.
17
+ *
18
+ * The sheet has no close cross: a grab handle, the panel's own Done button, Esc, or a tap outside
19
+ * close it. Both surfaces state their own colours (`bg-popover text-popover-foreground`) — they are
20
+ * portalled to the document body and inherit nothing. Focus goes in on open and back to the trigger
21
+ * on close, by hand, because the trigger is an anchor rather than a Radix trigger.
22
+ */
23
+ export const PickerSurface: FC<PickerSurfaceProps> = (
24
+ { open, onOpenChange, kind, tall, anchor, title, onOpenFocus, onCloseFocus, children }
25
+ ) => {
26
+ const popover = useRef<HTMLDivElement | null>(null)
27
+ const sheet = useRef<HTMLDivElement | null>(null)
28
+
29
+ const focusIn = (content: HTMLDivElement | null) => (event: Event): void => {
30
+ event.preventDefault()
31
+ if (content != null) {
32
+ onOpenFocus(content)
33
+ }
34
+ }
35
+ const focusBack = (event: Event): void => {
36
+ event.preventDefault()
37
+ onCloseFocus()
38
+ }
39
+
40
+ return <>
41
+ <Popover open={open && kind === 'popover'} onOpenChange={onOpenChange} modal>
42
+ <PopoverAnchor asChild>{anchor}</PopoverAnchor>
43
+ <PopoverContent
44
+ ref={popover} data-picker-surface="popover" aria-label={title}
45
+ align="start" sideOffset={6} collisionPadding={12}
46
+ onOpenAutoFocus={event => focusIn(popover.current)(event)} onCloseAutoFocus={focusBack}
47
+ className={cn(POPOVER, tall && TALL.popover)}
48
+ >{kind === 'popover' && children}</PopoverContent>
49
+ </Popover>
50
+ <Sheet open={open && kind === 'sheet'} onOpenChange={onOpenChange}>
51
+ <SheetContent
52
+ ref={sheet} side="bottom" showCloseButton={false} aria-describedby={undefined} data-picker-surface="sheet"
53
+ onOpenAutoFocus={event => focusIn(sheet.current)(event)} onCloseAutoFocus={focusBack}
54
+ className={cn(SHEET, tall && TALL.sheet)}
55
+ >
56
+ <SheetTitle className="sr-only">{title}</SheetTitle>
57
+ <div aria-hidden="true" className={GRAB} />
58
+ {kind === 'sheet' && children}
59
+ </SheetContent>
60
+ </Sheet>
61
+ </>
62
+ }
@@ -0,0 +1,110 @@
1
+ import { useEffect, useId, useRef, useState } from 'react'
2
+ import type { ChangeEvent, FC, KeyboardEvent } from 'react'
3
+ import { ChevronDownIcon } from 'lucide-react'
4
+ import { HexColorPicker } from 'react-colorful'
5
+ import { cn } from '../../../@/lib/utils.js'
6
+ import { pickerColorHelper } from '../../../picker/vocabulary.js'
7
+ import type { CustomColorProps } from '../types.local.js'
8
+ import {
9
+ CUSTOM_DISC, CUSTOM_PANEL, CUSTOM_ROW, CUSTOM_START, FIELD, FIELD_ERROR, FULL_HEX, HAIRLINE, HEX_FIELD, RAINBOW,
10
+ SWATCH_SELECTED, WHEEL_STYLE,
11
+ } from '../consts.local.js'
12
+
13
+ /**
14
+ * The opt-in custom colour: a row that opens a colour wheel (react-colorful — accessible sliders,
15
+ * touch) and a hex field. The wheel commits as it moves, like a native colour input; the field
16
+ * commits a full `#rrggbb` while typing and a short `#rgb` on Enter or blur, always normalized to
17
+ * lowercase six digits. Anything else marks the field invalid and changes nothing.
18
+ */
19
+ export const CustomColor: FC<CustomColorProps> = ({ value, onChange, text }) => {
20
+ const [open, setOpen] = useState(value != null)
21
+ const [draft, setDraft] = useState(value?.key ?? '')
22
+ const [checked, setChecked] = useState(false)
23
+ const typing = useRef(false)
24
+ const panelId = useId()
25
+ const errorId = useId()
26
+
27
+ // Follow the committed value, but never under the person's fingers.
28
+ useEffect(() => {
29
+ if (!typing.current) {
30
+ setDraft(value?.key ?? '')
31
+ }
32
+ }, [value?.key])
33
+
34
+ const normalized = pickerColorHelper.normalizeHex(draft)
35
+ const invalid = checked && draft.trim() !== '' && normalized == null
36
+ const label = text.text('custom', 'Custom colour')
37
+
38
+ const commit = (hex: string): void => {
39
+ if (hex !== value?.key) {
40
+ onChange(hex)
41
+ }
42
+ }
43
+
44
+ const onText = (event: ChangeEvent<HTMLInputElement>): void => {
45
+ const next = event.target.value
46
+ setDraft(next)
47
+ setChecked(false)
48
+ const full = FULL_HEX.test(next.trim()) ? pickerColorHelper.normalizeHex(next) : null
49
+ if (full != null) {
50
+ commit(full)
51
+ }
52
+ }
53
+
54
+ const settle = (): void => {
55
+ setChecked(true)
56
+ if (normalized != null) {
57
+ setDraft(normalized)
58
+ commit(normalized)
59
+ }
60
+ }
61
+
62
+ const onKey = (event: KeyboardEvent<HTMLInputElement>): void => {
63
+ if (event.key === 'Enter') {
64
+ // Never the enclosing form's submit.
65
+ event.preventDefault()
66
+ settle()
67
+ }
68
+ }
69
+
70
+ const onWheel = (hex: string): void => {
71
+ setDraft(hex)
72
+ setChecked(false)
73
+ commit(hex)
74
+ }
75
+
76
+ return <>
77
+ <button
78
+ type="button" data-picker-color="custom" data-selected={value != null || undefined}
79
+ aria-label={value != null ? `${label}: ${value.label}` : label}
80
+ aria-expanded={open} aria-controls={open ? panelId : undefined}
81
+ onClick={() => setOpen(!open)} className={CUSTOM_ROW}
82
+ >
83
+ <span
84
+ aria-hidden="true"
85
+ style={value != null ? pickerColorHelper.styleOf(value.key) : undefined}
86
+ className={cn(CUSTOM_DISC, HAIRLINE, value != null ? 'bg-(--pick-swatch)' : RAINBOW, value != null && SWATCH_SELECTED)}
87
+ />
88
+ <span className="min-w-0 flex-1 truncate">{label}</span>
89
+ {value != null && <span className="font-mono text-xs text-muted-foreground">{value.label}</span>}
90
+ <ChevronDownIcon
91
+ aria-hidden="true"
92
+ className={cn('size-4 shrink-0 text-muted-foreground transition-transform motion-reduce:transition-none', open && 'rotate-180')}
93
+ />
94
+ </button>
95
+ {open && <div id={panelId} className={CUSTOM_PANEL}>
96
+ <HexColorPicker color={normalized ?? value?.key ?? CUSTOM_START} onChange={onWheel} style={WHEEL_STYLE} />
97
+ <input
98
+ data-picker-hex type="text" inputMode="text" autoComplete="off" autoCapitalize="off" spellCheck={false}
99
+ enterKeyHint="done" maxLength={7} placeholder={CUSTOM_START}
100
+ aria-label={text.text('hex', 'Hex colour')} aria-invalid={invalid || undefined}
101
+ aria-describedby={invalid ? errorId : undefined}
102
+ value={draft} onChange={onText} onKeyDown={onKey}
103
+ onFocus={() => { typing.current = true }}
104
+ onBlur={() => { typing.current = false; settle() }}
105
+ className={cn(FIELD, HEX_FIELD)}
106
+ />
107
+ {invalid && <p id={errorId} className={FIELD_ERROR}>{text.text('invalidHex', 'Enter a colour like #3b82f6')}</p>}
108
+ </div>}
109
+ </>
110
+ }
@@ -0,0 +1,67 @@
1
+ import { useMemo } from 'react'
2
+ import type { FC } from 'react'
3
+ import { cn } from '../../@/lib/utils.js'
4
+ import { pickerColorHelper } from '../../picker/vocabulary.js'
5
+ import { PICKER_COLORS } from '../../picker/vocabulary/consts.js'
6
+ import type { ColorSwatchesProps } from './types.js'
7
+ import type { SwatchGridProps } from './types.local.js'
8
+ import { CustomColor } from './swatches/custom.js'
9
+ import { useRovingGrid } from './roving.js'
10
+ import { makePickerText } from './text.js'
11
+ import { PICK_SCOPE, SWATCH, SWATCH_DISC, SWATCH_SELECTED, SWATCHES } from './consts.local.js'
12
+
13
+ /**
14
+ * The swatch grid every picker shares, laid out for its surface: twelve to a row in a popover,
15
+ * as many 44px cells as fit in a sheet or below 768px. One tab stop; the arrows move in two
16
+ * dimensions. A swatch is a `<button type="button">` named by its colour and pressed while chosen.
17
+ */
18
+ export const SwatchGrid: FC<SwatchGridProps> = (
19
+ { value, onChange, onCustomChange, colors, customColors, text, layout, label, className }
20
+ ) => {
21
+ const resolved = pickerColorHelper.resolve(value, colors)
22
+ const selected = resolved == null || resolved.custom ? -1 : colors.findIndex(color => color.key === resolved.key)
23
+ const roving = useRovingGrid({ count: colors.length, selected })
24
+
25
+ return <div className={className}>
26
+ <div
27
+ ref={roving.ref} role="group" aria-label={label} onKeyDown={roving.onKeyDown}
28
+ data-picker-swatches className={SWATCHES[layout]}
29
+ >
30
+ {colors.map((color, index) => {
31
+ const named = pickerColorHelper.resolve(color.key, colors)
32
+ const name = named != null ? text.color(named) : color.key
33
+ const chosen = index === selected
34
+
35
+ return <button
36
+ key={color.key} type="button" data-roving-item data-picker-color={color.key}
37
+ aria-label={name} aria-pressed={chosen} title={name}
38
+ tabIndex={roving.tabIndexOf(index)} onFocus={() => roving.setCurrent(index)}
39
+ onClick={() => onChange(color.key)}
40
+ style={pickerColorHelper.styleOf(color.key, colors)}
41
+ className={cn(PICK_SCOPE, SWATCH)}
42
+ >
43
+ <span aria-hidden="true" className={cn(SWATCH_DISC, chosen && SWATCH_SELECTED)} />
44
+ </button>
45
+ })}
46
+ </div>
47
+ {customColors && <CustomColor
48
+ value={resolved?.custom === true ? resolved : null} onChange={onCustomChange ?? onChange} text={text}
49
+ />}
50
+ </div>
51
+ }
52
+
53
+ /**
54
+ * The colour swatches inline — for a dialog or sheet the application already owns. Commits on
55
+ * click; `customColors` adds the colour wheel and hex field. Strings through `translate` (English
56
+ * without it — never an implicit i18n read).
57
+ */
58
+ export const ColorSwatches: FC<ColorSwatchesProps> = (
59
+ { value, onChange, colors = PICKER_COLORS, customColors = false, translate, label, className }
60
+ ) => {
61
+ const text = useMemo(() => makePickerText(translate), [translate])
62
+
63
+ return <SwatchGrid
64
+ value={value} onChange={onChange} colors={colors} customColors={customColors} text={text} layout="inline"
65
+ label={label ?? text.text('color', 'Colour')} className={className}
66
+ />
67
+ }
@@ -0,0 +1,46 @@
1
+ import { PICKER_COLORS } from '../../picker/vocabulary/consts.js'
2
+ import type { PickerIconCategory, ResolvedPickerColor } from '../../picker/vocabulary/types.js'
3
+ import type { PickerTranslate } from './types.js'
4
+ import type { PickerMode, PickerText } from './types.local.js'
5
+
6
+ const english: PickerTranslate = (_key, fallback) => fallback
7
+
8
+ const humanize = (name: string): string => {
9
+ const words = name.replace(/-/g, ' ')
10
+
11
+ return words === '' ? name : words[0].toUpperCase() + words.slice(1)
12
+ }
13
+
14
+ /** Every string a picker shows, through one `translate` (English without one). Built once per render. */
15
+ export const makePickerText = (translate: PickerTranslate = english): PickerText => {
16
+ const text = (key: string, fallback: string): string => translate(key, fallback)
17
+
18
+ // Only the palette's own names translate; an application palette's labels are shown as given
19
+ // (a status palette may well have a key called `red` labelled "Blocked").
20
+ const color = (resolved: ResolvedPickerColor): string =>
21
+ !resolved.custom && PICKER_COLORS.some(entry => entry.key === resolved.key && entry.label === resolved.label)
22
+ ? translate(`colors.${resolved.key}`, resolved.label)
23
+ : resolved.label
24
+
25
+ const icon = (name: string): string => humanize(name)
26
+
27
+ const category = (value: PickerIconCategory): string => translate(`categories.${value}`, humanize(value))
28
+
29
+ // Filled after translation: a `{count}` placeholder is never one i18next interpolates or strips.
30
+ const count = (value: number): string => translate('results', 'Icons found: {count}').replace('{count}', String(value))
31
+
32
+ const empty = (query: string): string => translate('empty', 'No icons match “{query}”').replace('{query}', query)
33
+
34
+ const summary = (
35
+ iconName: string | null | undefined, resolved: ResolvedPickerColor | null, mode: PickerMode
36
+ ): string | null => {
37
+ const parts = [
38
+ mode !== 'color' && iconName != null && iconName !== '' ? icon(iconName) : null,
39
+ mode !== 'icon' && resolved != null ? color(resolved) : null,
40
+ ].filter((part): part is string => part != null)
41
+
42
+ return parts.length > 0 ? parts.join(' · ') : null
43
+ }
44
+
45
+ return { text, color, icon, category, count, empty, summary }
46
+ }
@@ -0,0 +1,35 @@
1
+ import type { FC } from 'react'
2
+ import { cn } from '../../@/lib/utils.js'
3
+ import { pickerIconHelper } from '../../picker/icons.js'
4
+ import { pickerColorHelper } from '../../picker/vocabulary.js'
5
+ import { PICKER_FALLBACK_ICON } from '../../picker/vocabulary/consts.js'
6
+ import type { IconTileProps } from './types.js'
7
+ import { PICK_SCOPE, PLAIN, PLAIN_SIZE, TILE, TILE_SIZE } from './consts.local.js'
8
+
9
+ /**
10
+ * A stored mark rendered — the way a list, a chip or a header shows what a person chose.
11
+ *
12
+ * `tile` puts the icon in the colour's ink on the colour's ground; `plain` is the ink alone. Both
13
+ * follow the page's scheme on their own (`.dark`, or the system's dark unless `.light`). An unknown
14
+ * icon renders the fallback circle and an unknown colour slate — a stored value never breaks a page.
15
+ */
16
+ export const IconTile: FC<IconTileProps> = (
17
+ { icon, color, colors, size = 'md', variant = 'tile', label, className, style }
18
+ ) => {
19
+ const Icon = pickerIconHelper.iconOf(icon)
20
+ const resolved = pickerColorHelper.resolve(color, colors)
21
+
22
+ return <span
23
+ data-icon-tile={variant}
24
+ data-icon={pickerIconHelper.has(icon) ? icon : PICKER_FALLBACK_ICON}
25
+ data-color={resolved?.key}
26
+ role={label != null ? 'img' : undefined}
27
+ aria-label={label}
28
+ aria-hidden={label != null ? undefined : true}
29
+ title={label}
30
+ style={{ ...pickerColorHelper.styleOf(color, colors), ...style }}
31
+ className={cn(PICK_SCOPE, variant === 'tile' ? TILE : PLAIN, variant === 'tile' ? TILE_SIZE[size] : PLAIN_SIZE[size], className)}
32
+ >
33
+ <Icon aria-hidden="true" />
34
+ </span>
35
+ }
@@ -0,0 +1,15 @@
1
+ import { useCallback } from 'react'
2
+ import { useI18nLib } from '@owlmeans/client-i18n'
3
+ import type { PickerTranslate } from './types.js'
4
+
5
+ /**
6
+ * A `translate` reading the picker's own library bundle (`lib:picker`, eight languages) in the
7
+ * current language — what an application rendered by `PanelApp` / `render()` passes to every picker
8
+ * part. It needs that i18n instance: called anywhere without one it throws inside render, which is
9
+ * exactly why no picker part calls it by itself. Missing keys fall back to the English text.
10
+ */
11
+ export const usePickerTranslate = (): PickerTranslate => {
12
+ const t = useI18nLib('picker')
13
+
14
+ return useCallback<PickerTranslate>((key, fallback) => t(key, { defaultValue: fallback }), [t])
15
+ }
@@ -0,0 +1,54 @@
1
+ import type { FC } from 'react'
2
+ import { ChevronDownIcon, PlusIcon } from 'lucide-react'
3
+ import { cn } from '../../@/lib/utils.js'
4
+ import { pickerColorHelper } from '../../picker/vocabulary.js'
5
+ import type { PickerTriggerProps } from './types.local.js'
6
+ import { IconTile } from './tile.js'
7
+ import {
8
+ CHEVRON, HAIRLINE, TRIGGER_BUTTON, TRIGGER_COMPACT, TRIGGER_DISC, TRIGGER_DOT, TRIGGER_EMPTY,
9
+ } from './consts.local.js'
10
+
11
+ /**
12
+ * What opens a picker: a field-like button (the mark, its names, a chevron) or the mark alone.
13
+ *
14
+ * It is the popover's anchor and stays mounted in one place whichever surface opens, so focus has
15
+ * one element to return to. Its accessible name is the label and the current choice ("Mark:
16
+ * Rocket · Indigo"); it carries `data-picker-trigger`, never `data-slot="button"` or `data-tone`.
17
+ * Extra props — the popover anchor's — land on the button.
18
+ */
19
+ export const PickerTrigger: FC<PickerTriggerProps> = ({
20
+ ref, mode, variant, icon, color, colors, text, label, placeholder, open, disabled, id, className, onOpen, ...anchor
21
+ }) => {
22
+ const resolved = pickerColorHelper.resolve(color, colors)
23
+ const summary = text.summary(icon, resolved, mode)
24
+ const name = label != null && label !== '' ? `${label}: ${summary ?? placeholder}` : summary ?? placeholder
25
+ const empty = summary == null
26
+
27
+ const mark = mode === 'color'
28
+ ? empty
29
+ ? <span aria-hidden="true" className={cn(TRIGGER_EMPTY, 'rounded-full', variant === 'dot' && 'size-5')} />
30
+ : <span
31
+ aria-hidden="true" style={pickerColorHelper.styleOf(color, colors)}
32
+ className={cn(TRIGGER_DISC, HAIRLINE, variant === 'dot' && 'size-5')}
33
+ />
34
+ : empty
35
+ ? <span aria-hidden="true" className={cn(TRIGGER_EMPTY, variant === 'tile' && 'size-full rounded-lg')}><PlusIcon /></span>
36
+ : <IconTile icon={icon} color={color} colors={colors} size={variant === 'tile' ? 'md' : 'sm'} className={variant === 'tile' ? 'size-full' : undefined} />
37
+
38
+ return <button
39
+ {...anchor}
40
+ ref={ref} type="button" id={id} disabled={disabled}
41
+ data-picker-trigger={variant} aria-haspopup="dialog" aria-expanded={open} aria-label={name}
42
+ title={variant === 'button' ? undefined : name}
43
+ onClick={onOpen}
44
+ className={cn(
45
+ variant === 'button' ? TRIGGER_BUTTON : TRIGGER_COMPACT, variant === 'dot' && TRIGGER_DOT, className
46
+ )}
47
+ >
48
+ {variant === 'button' && mode === 'color' ? <span className="inline-flex size-7 shrink-0 items-center justify-center">{mark}</span> : mark}
49
+ {variant === 'button' && <>
50
+ <span className={cn('min-w-0 flex-1 truncate', empty && 'text-muted-foreground')}>{summary ?? placeholder}</span>
51
+ <ChevronDownIcon aria-hidden="true" className={CHEVRON} />
52
+ </>}
53
+ </button>
54
+ }
@@ -0,0 +1,154 @@
1
+ import type { ComponentProps, KeyboardEvent, ReactElement, ReactNode, Ref, RefObject } from 'react'
2
+ import type { PickerColor, PickerIconCategory, ResolvedPickerColor } from '../../picker/vocabulary/types.js'
3
+ import type { PickerTranslate } from './types.js'
4
+
5
+ /** Where a panel is laid out — it decides cell sizes and paddings. */
6
+ export type PickerLayout = 'popover' | 'sheet' | 'inline'
7
+
8
+ /** Which halves a picker edits. */
9
+ export type PickerMode = 'both' | 'icon' | 'color'
10
+
11
+ /** Every string a picker shows, resolved through one `translate`. */
12
+ export interface PickerText {
13
+ /** A chrome string by key, English fallback. */
14
+ text: (key: string, fallback: string) => string
15
+ /** A colour's name: a palette name through `colors.<key>`, a custom colour's hex as is. */
16
+ color: (color: ResolvedPickerColor) => string
17
+ /** An icon's name — the kebab name humanized; icon names are never translated. */
18
+ icon: (name: string) => string
19
+ category: (category: PickerIconCategory) => string
20
+ /** "Icons found: 12" for the live region. */
21
+ count: (count: number) => string
22
+ /** "No icons match …". */
23
+ empty: (query: string) => string
24
+ /** "Rocket · Indigo", or `null` while nothing is chosen. */
25
+ summary: (icon: string | null | undefined, color: ResolvedPickerColor | null, mode: PickerMode) => string | null
26
+ }
27
+
28
+ /** Arrow-key focus across a grid of buttons; only one of them is in the tab order. */
29
+ export interface RovingGrid {
30
+ ref: RefObject<HTMLDivElement | null>
31
+ onKeyDown: (event: KeyboardEvent<HTMLElement>) => void
32
+ /** `0` for the one item in the tab order, `-1` for the rest. */
33
+ tabIndexOf: (index: number) => number
34
+ /** Remember an item as the current one (it took focus). */
35
+ setCurrent: (index: number) => void
36
+ /** Focus the current item. */
37
+ focusCurrent: () => void
38
+ }
39
+
40
+ export interface RovingGridOptions {
41
+ count: number
42
+ /** The item that starts in the tab order — the selected one. */
43
+ selected: number
44
+ /** ArrowUp from the first row: hand focus back (the search field above a grid). */
45
+ onExitUp?: () => void
46
+ /** `false` — one row, Left/Right only. */
47
+ grid?: boolean
48
+ }
49
+
50
+ export interface SwatchGridProps {
51
+ value?: string | null
52
+ /** A swatch was pressed. */
53
+ onChange: (color: string) => void
54
+ /** The custom wheel or hex field changed; default `onChange`. A picker that closes on a pick keeps this open. */
55
+ onCustomChange?: (color: string) => void
56
+ colors: readonly PickerColor[]
57
+ customColors: boolean
58
+ text: PickerText
59
+ layout: PickerLayout
60
+ label: string
61
+ className?: string
62
+ }
63
+
64
+ export interface CustomColorProps {
65
+ /** The current value when it is a custom colour, else `null`. */
66
+ value: ResolvedPickerColor | null
67
+ onChange: (color: string) => void
68
+ text: PickerText
69
+ }
70
+
71
+ export interface IconBrowserProps {
72
+ value?: string | null
73
+ onChange: (icon: string) => void
74
+ color?: string | null
75
+ colors: readonly PickerColor[]
76
+ icons?: readonly string[]
77
+ text: PickerText
78
+ layout: PickerLayout
79
+ label: string
80
+ /** The search field — the surface focuses it on open for a fine pointer. */
81
+ searchRef?: Ref<HTMLInputElement>
82
+ className?: string
83
+ }
84
+
85
+ export interface PickerPanelProps {
86
+ mode: PickerMode
87
+ icon?: string | null
88
+ color?: string | null
89
+ onIcon: (icon: string) => void
90
+ /** A swatch was pressed. */
91
+ onColor: (color: string) => void
92
+ /** The custom wheel or hex field changed. */
93
+ onCustomColor: (color: string) => void
94
+ colors: readonly PickerColor[]
95
+ icons?: readonly string[]
96
+ customColors: boolean
97
+ text: PickerText
98
+ layout: 'popover' | 'sheet'
99
+ title: string
100
+ /** The sheet's Done button; the popover has none. */
101
+ onDone?: () => void
102
+ searchRef: Ref<HTMLInputElement>
103
+ }
104
+
105
+ export interface PickerSurfaceProps {
106
+ open: boolean
107
+ onOpenChange: (open: boolean) => void
108
+ kind: 'popover' | 'sheet'
109
+ /** Holds an icon grid — keep one height so filtering never makes the surface jump. */
110
+ tall: boolean
111
+ /** The trigger — the popover's anchor, kept in the same place in the tree for both surfaces. */
112
+ anchor: ReactElement
113
+ title: string
114
+ /** Focus on open (the search field for a fine pointer, the selected cell otherwise). */
115
+ onOpenFocus: (content: HTMLElement) => void
116
+ /** Focus back on the trigger once closed. */
117
+ onCloseFocus: () => void
118
+ children: ReactNode
119
+ }
120
+
121
+ /** The trigger's own props; anything else (the popover anchor's) lands on the button. */
122
+ export interface PickerTriggerProps extends Omit<ComponentProps<'button'>, 'color' | 'onClick' | 'type' | 'children'> {
123
+ mode: PickerMode
124
+ variant: 'button' | 'tile' | 'dot'
125
+ icon?: string | null
126
+ color?: string | null
127
+ colors: readonly PickerColor[]
128
+ text: PickerText
129
+ label?: string
130
+ placeholder: string
131
+ open: boolean
132
+ onOpen: () => void
133
+ }
134
+
135
+ export interface PickerRootProps {
136
+ mode: PickerMode
137
+ icon?: string | null
138
+ color?: string | null
139
+ onIcon: (icon: string) => void
140
+ onColor: (color: string) => void
141
+ colors?: readonly PickerColor[]
142
+ icons?: readonly string[]
143
+ customColors?: boolean
144
+ trigger: 'button' | 'tile' | 'dot'
145
+ /** A single-purpose picker closes once something is picked; the composite stays for the other half. */
146
+ closeOnPick: boolean
147
+ label?: string
148
+ placeholder?: string
149
+ disabled?: boolean
150
+ surface?: 'auto' | 'popover' | 'sheet'
151
+ translate?: PickerTranslate
152
+ className?: string
153
+ id?: string
154
+ }