@coffer-org/web-ui 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/README.md +87 -0
  2. package/dist/Markdown.d.ts +4 -0
  3. package/dist/Markdown.js +13 -0
  4. package/dist/MarkdownEditor.d.ts +6 -0
  5. package/dist/MarkdownEditor.js +83 -0
  6. package/dist/actions/ActionButton.d.ts +7 -0
  7. package/dist/actions/ActionButton.js +54 -0
  8. package/dist/actions/PopupBody.d.ts +4 -0
  9. package/dist/actions/PopupBody.js +8 -0
  10. package/dist/actions/TemplateHost.d.ts +4 -0
  11. package/dist/actions/TemplateHost.js +36 -0
  12. package/dist/actions/registry.d.ts +20 -0
  13. package/dist/actions/registry.js +9 -0
  14. package/dist/components/ExtendReasonInfo.d.ts +6 -0
  15. package/dist/components/ExtendReasonInfo.js +12 -0
  16. package/dist/components/FavoriteButton.d.ts +8 -0
  17. package/dist/components/FavoriteButton.js +7 -0
  18. package/dist/components/Icon.d.ts +6 -0
  19. package/dist/components/Icon.js +12 -0
  20. package/dist/components/PageBody.d.ts +4 -0
  21. package/dist/components/PageBody.js +4 -0
  22. package/dist/components/RecordInline.d.ts +8 -0
  23. package/dist/components/RecordInline.js +29 -0
  24. package/dist/components/SaveStatus.d.ts +1 -0
  25. package/dist/components/SaveStatus.js +11 -0
  26. package/dist/components/Toolbar.d.ts +5 -0
  27. package/dist/components/Toolbar.js +4 -0
  28. package/dist/components/icons/color.d.ts +2 -0
  29. package/dist/components/icons/color.js +10 -0
  30. package/dist/components/icons/flag.d.ts +2 -0
  31. package/dist/components/icons/flag.js +6 -0
  32. package/dist/components/icons/lucide.d.ts +2 -0
  33. package/dist/components/icons/lucide.js +111 -0
  34. package/dist/components/icons/registry.d.ts +4 -0
  35. package/dist/components/icons/registry.js +22 -0
  36. package/dist/components/icons/simple.d.ts +2 -0
  37. package/dist/components/icons/simple.js +15 -0
  38. package/dist/components/icons/tabler.d.ts +2 -0
  39. package/dist/components/icons/tabler.js +11 -0
  40. package/dist/components/ui/FieldLabel.d.ts +9 -0
  41. package/dist/components/ui/FieldLabel.js +4 -0
  42. package/dist/components/ui/badge.d.ts +9 -0
  43. package/dist/components/ui/badge.js +19 -0
  44. package/dist/components/ui/button.d.ts +11 -0
  45. package/dist/components/ui/button.js +33 -0
  46. package/dist/components/ui/calendar.d.ts +8 -0
  47. package/dist/components/ui/calendar.js +72 -0
  48. package/dist/components/ui/card.d.ts +8 -0
  49. package/dist/components/ui/card.js +16 -0
  50. package/dist/components/ui/checkbox.d.ts +4 -0
  51. package/dist/components/ui/checkbox.js +8 -0
  52. package/dist/components/ui/chip-cls.d.ts +1 -0
  53. package/dist/components/ui/chip-cls.js +1 -0
  54. package/dist/components/ui/combobox.d.ts +24 -0
  55. package/dist/components/ui/combobox.js +58 -0
  56. package/dist/components/ui/confirm.d.ts +10 -0
  57. package/dist/components/ui/confirm.js +37 -0
  58. package/dist/components/ui/date-picker.d.ts +5 -0
  59. package/dist/components/ui/date-picker.js +16 -0
  60. package/dist/components/ui/dialog.d.ts +16 -0
  61. package/dist/components/ui/dialog.js +27 -0
  62. package/dist/components/ui/dropdown-menu.d.ts +15 -0
  63. package/dist/components/ui/dropdown-menu.js +18 -0
  64. package/dist/components/ui/input-group.d.ts +16 -0
  65. package/dist/components/ui/input-group.js +56 -0
  66. package/dist/components/ui/input.d.ts +3 -0
  67. package/dist/components/ui/input.js +6 -0
  68. package/dist/components/ui/label.d.ts +4 -0
  69. package/dist/components/ui/label.js +7 -0
  70. package/dist/components/ui/mask-input.d.ts +61 -0
  71. package/dist/components/ui/mask-input.js +1052 -0
  72. package/dist/components/ui/month-year-picker.d.ts +10 -0
  73. package/dist/components/ui/month-year-picker.js +46 -0
  74. package/dist/components/ui/option-icon.d.ts +15 -0
  75. package/dist/components/ui/option-icon.js +19 -0
  76. package/dist/components/ui/phone-input.d.ts +13 -0
  77. package/dist/components/ui/phone-input.js +53 -0
  78. package/dist/components/ui/popover.d.ts +11 -0
  79. package/dist/components/ui/popover.js +28 -0
  80. package/dist/components/ui/rating.d.ts +44 -0
  81. package/dist/components/ui/rating.js +501 -0
  82. package/dist/components/ui/scroll-area.d.ts +5 -0
  83. package/dist/components/ui/scroll-area.js +11 -0
  84. package/dist/components/ui/select-combobox.d.ts +25 -0
  85. package/dist/components/ui/select-combobox.js +36 -0
  86. package/dist/components/ui/select.d.ts +13 -0
  87. package/dist/components/ui/select.js +24 -0
  88. package/dist/components/ui/separator.d.ts +4 -0
  89. package/dist/components/ui/separator.js +7 -0
  90. package/dist/components/ui/switch.d.ts +4 -0
  91. package/dist/components/ui/switch.js +7 -0
  92. package/dist/components/ui/textarea.d.ts +3 -0
  93. package/dist/components/ui/textarea.js +6 -0
  94. package/dist/components/ui/time-picker.d.ts +84 -0
  95. package/dist/components/ui/time-picker.js +1258 -0
  96. package/dist/components/visually-hidden-input.d.ts +10 -0
  97. package/dist/components/visually-hidden-input.js +96 -0
  98. package/dist/hooks/use-as-ref.d.ts +3 -0
  99. package/dist/hooks/use-as-ref.js +10 -0
  100. package/dist/hooks/use-isomorphic-layout-effect.d.ts +3 -0
  101. package/dist/hooks/use-isomorphic-layout-effect.js +3 -0
  102. package/dist/hooks/use-lazy-ref.d.ts +3 -0
  103. package/dist/hooks/use-lazy-ref.js +9 -0
  104. package/dist/hooks/use-media-query.d.ts +3 -0
  105. package/dist/hooks/use-media-query.js +26 -0
  106. package/dist/host-services.d.ts +47 -0
  107. package/dist/host-services.js +35 -0
  108. package/dist/index.d.ts +70 -0
  109. package/dist/index.js +69 -0
  110. package/dist/layout.d.ts +29 -0
  111. package/dist/layout.js +323 -0
  112. package/dist/lib/cat-color.d.ts +1 -0
  113. package/dist/lib/cat-color.js +7 -0
  114. package/dist/lib/compose-refs.d.ts +5 -0
  115. package/dist/lib/compose-refs.js +38 -0
  116. package/dist/lib/date-format.d.ts +9 -0
  117. package/dist/lib/date-format.js +31 -0
  118. package/dist/lib/format.d.ts +14 -0
  119. package/dist/lib/format.js +34 -0
  120. package/dist/lib/json.d.ts +1 -0
  121. package/dist/lib/json.js +12 -0
  122. package/dist/lib/multi-value.d.ts +3 -0
  123. package/dist/lib/multi-value.js +22 -0
  124. package/dist/lib/record-option.d.ts +7 -0
  125. package/dist/lib/record-option.js +52 -0
  126. package/dist/lib/use-record-labels.d.ts +14 -0
  127. package/dist/lib/use-record-labels.js +130 -0
  128. package/dist/lib/utils.d.ts +2 -0
  129. package/dist/lib/utils.js +5 -0
  130. package/dist/list-view.d.ts +26 -0
  131. package/dist/list-view.js +11 -0
  132. package/dist/markdown/blocks.d.ts +10 -0
  133. package/dist/markdown/blocks.js +57 -0
  134. package/dist/markdown/extensions.d.ts +6 -0
  135. package/dist/markdown/extensions.js +25 -0
  136. package/dist/markdown/slash.d.ts +23 -0
  137. package/dist/markdown/slash.js +27 -0
  138. package/dist/markdown/toolbar.d.ts +13 -0
  139. package/dist/markdown/toolbar.js +119 -0
  140. package/dist/plugin-ui.d.ts +43 -0
  141. package/dist/plugin-ui.js +37 -0
  142. package/dist/registry.d.ts +26 -0
  143. package/dist/registry.js +169 -0
  144. package/dist/render/blocks/accordion.d.ts +1 -0
  145. package/dist/render/blocks/accordion.js +15 -0
  146. package/dist/render/blocks/aside.d.ts +1 -0
  147. package/dist/render/blocks/aside.js +14 -0
  148. package/dist/render/blocks/balance.d.ts +1 -0
  149. package/dist/render/blocks/balance.js +14 -0
  150. package/dist/render/blocks/bento.d.ts +1 -0
  151. package/dist/render/blocks/bento.js +24 -0
  152. package/dist/render/blocks/block-shell.d.ts +15 -0
  153. package/dist/render/blocks/block-shell.js +20 -0
  154. package/dist/render/blocks/calendar.d.ts +1 -0
  155. package/dist/render/blocks/calendar.js +142 -0
  156. package/dist/render/blocks/callout.d.ts +1 -0
  157. package/dist/render/blocks/callout.js +21 -0
  158. package/dist/render/blocks/chart.d.ts +1 -0
  159. package/dist/render/blocks/chart.js +46 -0
  160. package/dist/render/blocks/compare.d.ts +1 -0
  161. package/dist/render/blocks/compare.js +16 -0
  162. package/dist/render/blocks/countdown.d.ts +1 -0
  163. package/dist/render/blocks/countdown.js +36 -0
  164. package/dist/render/blocks/deck.d.ts +1 -0
  165. package/dist/render/blocks/deck.js +29 -0
  166. package/dist/render/blocks/epigraph.d.ts +1 -0
  167. package/dist/render/blocks/epigraph.js +13 -0
  168. package/dist/render/blocks/facets.d.ts +1 -0
  169. package/dist/render/blocks/facets.js +23 -0
  170. package/dist/render/blocks/figure.d.ts +1 -0
  171. package/dist/render/blocks/figure.js +13 -0
  172. package/dist/render/blocks/grid.d.ts +1 -0
  173. package/dist/render/blocks/grid.js +21 -0
  174. package/dist/render/blocks/heatmap.d.ts +1 -0
  175. package/dist/render/blocks/heatmap.js +135 -0
  176. package/dist/render/blocks/idcard.d.ts +1 -0
  177. package/dist/render/blocks/idcard.js +30 -0
  178. package/dist/render/blocks/identity.d.ts +1 -0
  179. package/dist/render/blocks/identity.js +46 -0
  180. package/dist/render/blocks/index.d.ts +40 -0
  181. package/dist/render/blocks/index.js +40 -0
  182. package/dist/render/blocks/journal.d.ts +1 -0
  183. package/dist/render/blocks/journal.js +50 -0
  184. package/dist/render/blocks/ledger.d.ts +1 -0
  185. package/dist/render/blocks/ledger.js +23 -0
  186. package/dist/render/blocks/manifest.d.ts +1 -0
  187. package/dist/render/blocks/manifest.js +50 -0
  188. package/dist/render/blocks/masthead.d.ts +1 -0
  189. package/dist/render/blocks/masthead.js +15 -0
  190. package/dist/render/blocks/meter.d.ts +1 -0
  191. package/dist/render/blocks/meter.js +32 -0
  192. package/dist/render/blocks/nutrition.d.ts +1 -0
  193. package/dist/render/blocks/nutrition.js +27 -0
  194. package/dist/render/blocks/people.d.ts +1 -0
  195. package/dist/render/blocks/people.js +35 -0
  196. package/dist/render/blocks/plaque.d.ts +1 -0
  197. package/dist/render/blocks/plaque.js +15 -0
  198. package/dist/render/blocks/properties.d.ts +1 -0
  199. package/dist/render/blocks/properties.js +22 -0
  200. package/dist/render/blocks/prose.d.ts +1 -0
  201. package/dist/render/blocks/prose.js +17 -0
  202. package/dist/render/blocks/receipt.d.ts +1 -0
  203. package/dist/render/blocks/receipt.js +23 -0
  204. package/dist/render/blocks/registry.d.ts +16 -0
  205. package/dist/render/blocks/registry.js +7 -0
  206. package/dist/render/blocks/relation-source.d.ts +2 -0
  207. package/dist/render/blocks/relation-source.js +6 -0
  208. package/dist/render/blocks/route.d.ts +1 -0
  209. package/dist/render/blocks/route.js +23 -0
  210. package/dist/render/blocks/score.d.ts +1 -0
  211. package/dist/render/blocks/score.js +15 -0
  212. package/dist/render/blocks/series.d.ts +23 -0
  213. package/dist/render/blocks/series.js +57 -0
  214. package/dist/render/blocks/specimen.d.ts +1 -0
  215. package/dist/render/blocks/specimen.js +19 -0
  216. package/dist/render/blocks/split.d.ts +1 -0
  217. package/dist/render/blocks/split.js +15 -0
  218. package/dist/render/blocks/spread.d.ts +1 -0
  219. package/dist/render/blocks/spread.js +15 -0
  220. package/dist/render/blocks/stack.d.ts +1 -0
  221. package/dist/render/blocks/stack.js +15 -0
  222. package/dist/render/blocks/stats.d.ts +1 -0
  223. package/dist/render/blocks/stats.js +23 -0
  224. package/dist/render/blocks/status.d.ts +1 -0
  225. package/dist/render/blocks/status.js +18 -0
  226. package/dist/render/blocks/table.d.ts +11 -0
  227. package/dist/render/blocks/table.js +136 -0
  228. package/dist/render/blocks/tabs.d.ts +1 -0
  229. package/dist/render/blocks/tabs.js +17 -0
  230. package/dist/render/blocks/terminal.d.ts +1 -0
  231. package/dist/render/blocks/terminal.js +18 -0
  232. package/dist/render/blocks/timeline.d.ts +1 -0
  233. package/dist/render/blocks/timeline.js +31 -0
  234. package/dist/render/box.d.ts +5 -0
  235. package/dist/render/box.js +23 -0
  236. package/dist/render/chrome.d.ts +64 -0
  237. package/dist/render/chrome.js +92 -0
  238. package/dist/render/core/amount.d.ts +1 -0
  239. package/dist/render/core/amount.js +19 -0
  240. package/dist/render/core/attachment.d.ts +29 -0
  241. package/dist/render/core/attachment.js +102 -0
  242. package/dist/render/core/choice.d.ts +1 -0
  243. package/dist/render/core/choice.js +40 -0
  244. package/dist/render/core/composite.d.ts +1 -0
  245. package/dist/render/core/composite.js +132 -0
  246. package/dist/render/core/datetime.d.ts +2 -0
  247. package/dist/render/core/datetime.js +215 -0
  248. package/dist/render/core/dimensions.d.ts +1 -0
  249. package/dist/render/core/dimensions.js +44 -0
  250. package/dist/render/core/embed.d.ts +11 -0
  251. package/dist/render/core/embed.js +99 -0
  252. package/dist/render/core/file.d.ts +12 -0
  253. package/dist/render/core/file.js +238 -0
  254. package/dist/render/core/illustrated.d.ts +39 -0
  255. package/dist/render/core/illustrated.js +113 -0
  256. package/dist/render/core/index.d.ts +23 -0
  257. package/dist/render/core/index.js +23 -0
  258. package/dist/render/core/layout-elements.d.ts +1 -0
  259. package/dist/render/core/layout-elements.js +78 -0
  260. package/dist/render/core/localpath.d.ts +6 -0
  261. package/dist/render/core/localpath.js +73 -0
  262. package/dist/render/core/money.d.ts +1 -0
  263. package/dist/render/core/money.js +39 -0
  264. package/dist/render/core/number.d.ts +17 -0
  265. package/dist/render/core/number.js +104 -0
  266. package/dist/render/core/period.d.ts +1 -0
  267. package/dist/render/core/period.js +60 -0
  268. package/dist/render/core/range.d.ts +1 -0
  269. package/dist/render/core/range.js +55 -0
  270. package/dist/render/core/reminder.d.ts +2 -0
  271. package/dist/render/core/reminder.js +56 -0
  272. package/dist/render/core/source.d.ts +3 -0
  273. package/dist/render/core/source.js +65 -0
  274. package/dist/render/core/stepper.d.ts +1 -0
  275. package/dist/render/core/stepper.js +81 -0
  276. package/dist/render/core/storage-group.d.ts +1 -0
  277. package/dist/render/core/storage-group.js +30 -0
  278. package/dist/render/core/text.d.ts +15 -0
  279. package/dist/render/core/text.js +370 -0
  280. package/dist/render/core/tristate.d.ts +1 -0
  281. package/dist/render/core/tristate.js +42 -0
  282. package/dist/render/core/weight.d.ts +4 -0
  283. package/dist/render/core/weight.js +38 -0
  284. package/dist/render/dispatch.d.ts +12 -0
  285. package/dist/render/dispatch.js +53 -0
  286. package/dist/render/display-override.d.ts +25 -0
  287. package/dist/render/display-override.js +23 -0
  288. package/dist/render/editor-mode.d.ts +4 -0
  289. package/dist/render/editor-mode.js +11 -0
  290. package/dist/render/field-address.d.ts +14 -0
  291. package/dist/render/field-address.js +10 -0
  292. package/dist/render/field-errors.d.ts +8 -0
  293. package/dist/render/field-errors.js +25 -0
  294. package/dist/render/field-frame.d.ts +20 -0
  295. package/dist/render/field-frame.js +78 -0
  296. package/dist/render/field-scope.d.ts +8 -0
  297. package/dist/render/field-scope.js +25 -0
  298. package/dist/render/field-width.d.ts +7 -0
  299. package/dist/render/field-width.js +12 -0
  300. package/dist/render/form-types.d.ts +12 -0
  301. package/dist/render/form-types.js +1 -0
  302. package/dist/render/hybrid-scope.d.ts +5 -0
  303. package/dist/render/hybrid-scope.js +9 -0
  304. package/dist/render/image.d.ts +64 -0
  305. package/dist/render/image.js +322 -0
  306. package/dist/render/live-kind.d.ts +7 -0
  307. package/dist/render/live-kind.js +104 -0
  308. package/dist/render/markdown-view.d.ts +5 -0
  309. package/dist/render/markdown-view.js +17 -0
  310. package/dist/render/multi.d.ts +10 -0
  311. package/dist/render/multi.js +26 -0
  312. package/dist/render/multiple-chips.d.ts +24 -0
  313. package/dist/render/multiple-chips.js +18 -0
  314. package/dist/render/option-list.d.ts +15 -0
  315. package/dist/render/option-list.js +47 -0
  316. package/dist/render/option-value.d.ts +20 -0
  317. package/dist/render/option-value.js +41 -0
  318. package/dist/render/picker-scrim.d.ts +7 -0
  319. package/dist/render/picker-scrim.js +32 -0
  320. package/dist/render/picker-surface.d.ts +5 -0
  321. package/dist/render/picker-surface.js +9 -0
  322. package/dist/render/popover-field.d.ts +16 -0
  323. package/dist/render/popover-field.js +153 -0
  324. package/dist/render/record-save-ctx.d.ts +11 -0
  325. package/dist/render/record-save-ctx.js +41 -0
  326. package/dist/render/shared.d.ts +92 -0
  327. package/dist/render/shared.js +182 -0
  328. package/dist/render/slot.d.ts +45 -0
  329. package/dist/render/slot.js +194 -0
  330. package/dist/render/sort-rows.d.ts +3 -0
  331. package/dist/render/sort-rows.js +38 -0
  332. package/dist/render/use-collection-rows.d.ts +10 -0
  333. package/dist/render/use-collection-rows.js +11 -0
  334. package/dist/render/use-field-edit.d.ts +28 -0
  335. package/dist/render/use-field-edit.js +50 -0
  336. package/dist/render/use-file-upload.d.ts +10 -0
  337. package/dist/render/use-file-upload.js +35 -0
  338. package/dist/render/use-form-bridge.d.ts +21 -0
  339. package/dist/render/use-form-bridge.js +53 -0
  340. package/dist/render/use-hybrid.d.ts +2 -0
  341. package/dist/render/use-hybrid.js +5 -0
  342. package/dist/render/widgets/attachment-group.d.ts +1 -0
  343. package/dist/render/widgets/attachment-group.js +35 -0
  344. package/dist/render/widgets/checklist-content.d.ts +15 -0
  345. package/dist/render/widgets/checklist-content.js +12 -0
  346. package/dist/render/widgets/checklist-group.d.ts +11 -0
  347. package/dist/render/widgets/checklist-group.js +47 -0
  348. package/dist/render/widgets/checklist-row.d.ts +14 -0
  349. package/dist/render/widgets/checklist-row.js +14 -0
  350. package/dist/render/widgets/display.d.ts +33 -0
  351. package/dist/render/widgets/display.js +97 -0
  352. package/dist/render/widgets/edit.d.ts +63 -0
  353. package/dist/render/widgets/edit.js +283 -0
  354. package/dist/render/widgets/fixed-collection.d.ts +11 -0
  355. package/dist/render/widgets/fixed-collection.js +34 -0
  356. package/dist/render/widgets/flow-row.d.ts +14 -0
  357. package/dist/render/widgets/flow-row.js +27 -0
  358. package/dist/render/widgets/group-edit.d.ts +9 -0
  359. package/dist/render/widgets/group-edit.js +23 -0
  360. package/dist/render/widgets/group-field.d.ts +9 -0
  361. package/dist/render/widgets/group-field.js +42 -0
  362. package/dist/render/widgets/group-widgets.d.ts +2 -0
  363. package/dist/render/widgets/group-widgets.js +41 -0
  364. package/dist/render/widgets/group.d.ts +26 -0
  365. package/dist/render/widgets/group.js +139 -0
  366. package/dist/render/widgets/illustrated-group.d.ts +1 -0
  367. package/dist/render/widgets/illustrated-group.js +41 -0
  368. package/dist/render/widgets/table-group.d.ts +11 -0
  369. package/dist/render/widgets/table-group.js +58 -0
  370. package/dist/render/widgets/two-cell-group.d.ts +21 -0
  371. package/dist/render/widgets/two-cell-group.js +42 -0
  372. package/dist/render/widgets/url-widget.d.ts +7 -0
  373. package/dist/render/widgets/url-widget.js +15 -0
  374. package/dist/render/widgets/weekday-grid.d.ts +13 -0
  375. package/dist/render/widgets/weekday-grid.js +47 -0
  376. package/dist/render/write.d.ts +5 -0
  377. package/dist/render/write.js +14 -0
  378. package/dist/schema-registry.d.ts +6 -0
  379. package/dist/schema-registry.js +25 -0
  380. package/dist/site-links.d.ts +13 -0
  381. package/dist/site-links.js +18 -0
  382. package/dist/strip-markdown.d.ts +1 -0
  383. package/dist/strip-markdown.js +11 -0
  384. package/dist/theme.css +189 -0
  385. package/dist/types.d.ts +84 -0
  386. package/dist/types.js +1 -0
  387. package/package.json +85 -0
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # @coffer-org/web-ui
2
+
3
+ The UI contract for Coffer plugin **web bundles**. A plugin's `dist/web.js` is
4
+ loaded at runtime by the host's federation loader; this package defines what that
5
+ bundle declares (`PluginUIBundle`) and the field-renderer registry it plugs into.
6
+
7
+ ## What a web bundle exports
8
+
9
+ `web.js` **default-exports** a single `PluginUIBundle` — one bundle, not an array:
10
+
11
+ ```ts
12
+ export default PluginUIBundle;
13
+ ```
14
+
15
+ Build one with `definePluginUI(bundle)`:
16
+
17
+ ```tsx
18
+ import { definePluginUI } from '@coffer-org/web-ui';
19
+
20
+ export default definePluginUI({
21
+ // shelf?: { library, shelf, RecordView? } — only needed for a custom
22
+ // RecordView (replaces the generic RecordContent) tied to one shelf
23
+ // renderers?: FieldRenderer[] — own field-type renderers (each carries kinds[])
24
+ // listViews?: ListViewDef[] — own list-view kinds
25
+ // templates?: Record<string, TemplateImporter<any>> — action-result templates
26
+ // translations?: Partial<Record<'uk' | 'ru' | 'en', Record<string, unknown>>>
27
+ // slots?/routes?/nav?: contributions to the app shell (overlay, SPA routes, sidebar nav)
28
+ translations: { en: { 'myplugin.hello': 'Hello from myplugin' } },
29
+ });
30
+ ```
31
+
32
+ `definePluginUI` is the identity function — it exists so every plugin's `ui.tsx`
33
+ has one recognizable call, not three. There is no per-plugin choice to make: a
34
+ `ui.tsx` that only needs a `RecordView`, one that only needs `renderers`, and one
35
+ that only needs `slots` all call the same factory with the same type.
36
+
37
+ The host's federation loader applies the bundle once: `applyWebBundle`
38
+ (`packages/web/federation.ts`) forwards `slots`/`routes`/`nav` to `applyAppUI`
39
+ (this package) and itself registers `shelf.RecordView` for `shelf.library/shelf`,
40
+ calls `registerRenderer`/`registerListView` for `renderers`/`listViews`, and merges
41
+ `translations` into the global i18next instance.
42
+
43
+ ## Vendor singleton model (importmap)
44
+
45
+ Plugin web bundles must **not** ship their own copy of React, i18next, or
46
+ `@coffer-org/web-ui` — they share the host's. The host publishes one vendor bundle
47
+ under `/vendor/*` and wires an [import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap)
48
+ so every bare specifier resolves to that single instance:
49
+
50
+ ```html
51
+ <script type="importmap">
52
+ {
53
+ "imports": {
54
+ "react": "/vendor/react.js",
55
+ "react-dom": "/vendor/react-dom.js",
56
+ "i18next": "/vendor/i18next.js",
57
+ "@coffer-org/web-ui": "/vendor/web-ui.js"
58
+ }
59
+ }
60
+ </script>
61
+ ```
62
+
63
+ This keeps a single React (so hooks/context work across bundles) and a single
64
+ i18next (so `addResourceBundle` merges into the one live instance). In dev, Vite
65
+ resolves these specifiers via its own aliases, so the import map is a prod-only
66
+ concern.
67
+
68
+ ## Supported vendor majors
69
+
70
+ | Vendor | Range |
71
+ | --------------------- | ---------------------------- |
72
+ | `react` / `react-dom` | **19** (`>=19`) |
73
+ | `i18next` | **26** (23+ host-compatible) |
74
+
75
+ A scaffolded plugin declares these as **peer** dependencies (see
76
+ `create-coffer-plugin`'s `package.json` template), so it builds against the
77
+ host's instance instead of bundling its own.
78
+
79
+ ## Mismatched vendor versions warn, don't block
80
+
81
+ The import map always resolves a plugin's `react` / `react-dom` / `i18next` /
82
+ `@coffer-org/web-ui` imports to the host's single instance — there is no runtime
83
+ version gate that refuses to load a bundle. A vendor-major mismatch surfaces as a
84
+ **peer-dependency warning at install/build time**, not a hard runtime failure: a
85
+ plugin built against an older major still loads against the host's instance and
86
+ runs as far as the shared API allows. Keep peers in range to avoid surprises; a
87
+ mismatch is a warning, not a block.
@@ -0,0 +1,4 @@
1
+ export declare function renderMarkdown(src: string): string;
2
+ export default function Markdown({ value }: {
3
+ value: string;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { micromark } from 'micromark';
3
+ import { gfm, gfmHtml } from 'micromark-extension-gfm';
4
+ export function renderMarkdown(src) {
5
+ return micromark(src, {
6
+ allowDangerousHtml: true,
7
+ extensions: [gfm()],
8
+ htmlExtensions: [gfmHtml()],
9
+ });
10
+ }
11
+ export default function Markdown({ value }) {
12
+ return _jsx("div", { className: "md-static", dangerouslySetInnerHTML: { __html: renderMarkdown(value) } });
13
+ }
@@ -0,0 +1,6 @@
1
+ export default function MarkdownEditor({ value, onChange, placeholder, readonly, }: {
2
+ value: string;
3
+ onChange?: (v: string) => void;
4
+ placeholder?: string;
5
+ readonly?: boolean;
6
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { EditorContent, useEditor } from '@tiptap/react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { markdownExtensions } from "./markdown/extensions.js";
6
+ import { BLOCKS } from "./markdown/blocks.js";
7
+ import { Toolbar } from "./markdown/toolbar.js";
8
+ const markdownOf = (editor) => editor && !editor.isDestroyed ? editor.storage.markdown : undefined;
9
+ export default function MarkdownEditor({ value, onChange, placeholder, readonly, }) {
10
+ const { t } = useTranslation();
11
+ const [slash, setSlash] = useState(null);
12
+ const slashRef = useRef(null);
13
+ slashRef.current = slash;
14
+ const label = (key) => t(`form.md.${key}`);
15
+ const labelRef = useRef(label);
16
+ labelRef.current = label;
17
+ const handlers = useMemo(() => ({
18
+ filter: (query) => {
19
+ const q = query.trim().toLowerCase();
20
+ const items = BLOCKS.map((block) => ({
21
+ key: block.key,
22
+ run: ({ editor: e, range }) => block.run(e, range),
23
+ }));
24
+ if (!q)
25
+ return items;
26
+ return items.filter((item) => item.key.toLowerCase().includes(q) || labelRef.current(item.key).toLowerCase().includes(q));
27
+ },
28
+ open: ({ rect, items, pick }) => setSlash((prev) => ({ rect, items, pick, index: prev && prev.index < items.length ? prev.index : 0 })),
29
+ close: () => setSlash(null),
30
+ keyDown: (event) => {
31
+ const current = slashRef.current;
32
+ if (!current)
33
+ return false;
34
+ const last = current.items.length - 1;
35
+ if (event.key === 'ArrowDown') {
36
+ setSlash({ ...current, index: current.index >= last ? 0 : current.index + 1 });
37
+ return true;
38
+ }
39
+ if (event.key === 'ArrowUp') {
40
+ setSlash({ ...current, index: current.index <= 0 ? last : current.index - 1 });
41
+ return true;
42
+ }
43
+ if (event.key === 'Enter') {
44
+ const item = current.items[current.index];
45
+ if (!item)
46
+ return false;
47
+ current.pick(item);
48
+ return true;
49
+ }
50
+ if (event.key === 'Escape') {
51
+ setSlash(null);
52
+ return true;
53
+ }
54
+ return false;
55
+ },
56
+ }), []);
57
+ const editor = useEditor({
58
+ editable: !readonly,
59
+ extensions: markdownExtensions({ placeholder: readonly ? undefined : placeholder, slash: handlers }),
60
+ content: value,
61
+ autofocus: false,
62
+ onUpdate: ({ editor: e }) => {
63
+ const markdown = markdownOf(e);
64
+ if (markdown)
65
+ onChange?.(markdown.getMarkdown());
66
+ },
67
+ editorProps: { attributes: { class: 'md-static outline-none' } },
68
+ });
69
+ useEffect(() => {
70
+ const markdown = markdownOf(editor);
71
+ if (!editor || !markdown)
72
+ return;
73
+ if (value === markdown.getMarkdown())
74
+ return;
75
+ editor.commands.setContent(value, { emitUpdate: false });
76
+ }, [editor, value]);
77
+ if (!editor || editor.isDestroyed)
78
+ return null;
79
+ return (_jsxs("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col gap-1.5 md:gap-2", children: [!readonly && _jsx(Toolbar, { editor: editor }), _jsx(EditorContent, { editor: editor, className: "min-h-48 w-full min-w-0 max-w-full flex-1 overflow-y-auto rounded-lg border border-border bg-bg px-2 py-1.5 transition-colors focus-within:border-accent md:min-h-64 md:rounded-xl md:px-4 md:py-3" }), slash && slash.items.length > 0 && (_jsx("div", { role: "listbox", className: "fixed z-50 max-h-64 w-56 overflow-y-auto rounded-lg border border-border bg-surface p-1 shadow-lg", style: { top: (slash.rect?.bottom ?? 0) + 4, left: slash.rect?.left ?? 0 }, children: slash.items.map((item, i) => {
80
+ const Icon = BLOCKS.find((b) => b.key === item.key)?.icon;
81
+ return (_jsxs("button", { type: "button", role: "option", "aria-selected": i === slash.index, onMouseEnter: () => setSlash({ ...slash, index: i }), onClick: () => slash.pick(item), className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm ${i === slash.index ? 'bg-elevated text-text' : 'text-muted'}`, children: [Icon && _jsx(Icon, { size: 15, className: "shrink-0" }), label(item.key)] }, item.key));
82
+ }) }))] }));
83
+ }
@@ -0,0 +1,7 @@
1
+ import type { ButtonEl } from '@coffer-org/sdk/fields';
2
+ import { type ActionContext } from './registry.ts';
3
+ export declare function ActionButton({ el, ctx, disabled }: {
4
+ el: ButtonEl;
5
+ ctx: ActionContext;
6
+ disabled?: boolean;
7
+ }): import("react").JSX.Element;
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { toast } from 'sonner';
5
+ import { Button } from "../components/ui/button.js";
6
+ import { Icon } from "../components/Icon.js";
7
+ import { Dialog, DialogContent, DialogHeader } from "../components/ui/dialog.js";
8
+ import { resolveAction } from "./registry.js";
9
+ import { TemplateHost } from "./TemplateHost.js";
10
+ import { PopupBody } from "./PopupBody.js";
11
+ export function ActionButton({ el, ctx, disabled }) {
12
+ const { t } = useTranslation();
13
+ const [loading, setLoading] = useState(false);
14
+ const [popup, setPopup] = useState(null);
15
+ const show = (ui) => {
16
+ if (ui.kind === 'popup') {
17
+ setPopup(ui);
18
+ return;
19
+ }
20
+ const body = ui.component ? (_jsx(TemplateHost, { name: ui.component.name, data: ui.component.data })) : (t(ui.message ?? '', ui.params));
21
+ if (ui.variant === 'success')
22
+ toast.success(body);
23
+ else if (ui.variant === 'error')
24
+ toast.error(body);
25
+ else
26
+ toast(body);
27
+ };
28
+ const run = async () => {
29
+ const handler = resolveAction(el.value);
30
+ if (!handler) {
31
+ toast.error(t('actions.actionNotFound'));
32
+ return;
33
+ }
34
+ setLoading(true);
35
+ try {
36
+ const res = await handler(ctx);
37
+ if (res)
38
+ show(res);
39
+ else
40
+ toast.success(t('actions.actionSuccess'));
41
+ }
42
+ catch (e) {
43
+ const ui = e.ui;
44
+ if (ui)
45
+ show(ui);
46
+ else
47
+ toast.error(e instanceof Error ? e.message : t('actions.actionError'));
48
+ }
49
+ finally {
50
+ setLoading(false);
51
+ }
52
+ };
53
+ return (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: el.variant ?? 'outline', onClick: run, disabled: disabled || loading, children: [loading ? (_jsx("span", { className: "animate-spin inline-block w-4 h-4 border-2 border-current/30 border-t-current rounded-full" })) : (el.icon && _jsx(Icon, { name: el.icon, size: 16 })), t(el.label)] }), _jsx(Dialog, { open: !!popup, onOpenChange: (o) => !o && setPopup(null), children: _jsx(DialogContent, { children: _jsx(DialogHeader, { children: popup && _jsx(PopupBody, { ui: popup }) }) }) })] }));
54
+ }
@@ -0,0 +1,4 @@
1
+ import type { ActionUI } from './registry.ts';
2
+ export declare function PopupBody({ ui }: {
3
+ ui: ActionUI;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from 'react-i18next';
3
+ import { DialogTitle, DialogDescription } from "../components/ui/dialog.js";
4
+ import { TemplateHost } from "./TemplateHost.js";
5
+ export function PopupBody({ ui }) {
6
+ const { t } = useTranslation();
7
+ return (_jsxs(_Fragment, { children: [_jsx(DialogTitle, { children: ui.title ? t(ui.title, ui.params) : t('actions.notice') }), ui.component ? (_jsx(TemplateHost, { name: ui.component.name, data: ui.component.data })) : (_jsx(DialogDescription, { children: t(ui.message ?? '', ui.params) }))] }));
8
+ }
@@ -0,0 +1,4 @@
1
+ export declare function TemplateHost({ name, data }: {
2
+ name: string;
3
+ data?: unknown;
4
+ }): import("react").JSX.Element;
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Component, lazy, Suspense } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { resolveTemplate } from "../registry.js";
5
+ const cache = new Map();
6
+ function lazyFor(name) {
7
+ const importer = resolveTemplate(name);
8
+ if (!importer)
9
+ return null;
10
+ let c = cache.get(name);
11
+ if (!c) {
12
+ c = lazy(importer);
13
+ cache.set(name, c);
14
+ }
15
+ return c;
16
+ }
17
+ class Boundary extends Component {
18
+ state = { failed: false };
19
+ static getDerivedStateFromError() {
20
+ return { failed: true };
21
+ }
22
+ render() {
23
+ return this.state.failed ? this.props.fallback : this.props.children;
24
+ }
25
+ }
26
+ const Spinner = () => (_jsx("span", { className: "animate-spin inline-block w-4 h-4 border-2 border-current/30 border-t-current rounded-full" }));
27
+ export function TemplateHost({ name, data }) {
28
+ const { t } = useTranslation();
29
+ const fallback = _jsx(_Fragment, { children: t('actions.notice') });
30
+ const Cmp = lazyFor(name);
31
+ if (!Cmp) {
32
+ console.warn(`[template] unknown '${name}'`);
33
+ return fallback;
34
+ }
35
+ return (_jsx(Boundary, { fallback: fallback, children: _jsx(Suspense, { fallback: _jsx(Spinner, {}), children: _jsx(Cmp, { data: data, t: t }) }) }));
36
+ }
@@ -0,0 +1,20 @@
1
+ export interface ActionContext {
2
+ library: string;
3
+ shelf: string;
4
+ recordId: string;
5
+ }
6
+ export interface ActionUI {
7
+ kind: 'toast' | 'popup';
8
+ variant?: 'success' | 'error' | 'info';
9
+ title?: string;
10
+ message?: string;
11
+ params?: Record<string, string | number>;
12
+ component?: {
13
+ name: string;
14
+ data?: unknown;
15
+ };
16
+ }
17
+ export type ActionResult = void | ActionUI;
18
+ export type ActionHandler = (ctx: ActionContext) => Promise<ActionResult>;
19
+ export declare function registerAction(key: string, handler: ActionHandler): void;
20
+ export declare function resolveAction(key: string): ActionHandler | undefined;
@@ -0,0 +1,9 @@
1
+ const registry = new Map();
2
+ export function registerAction(key, handler) {
3
+ if (registry.has(key))
4
+ throw new Error(`[actions] '${key}' already registered`);
5
+ registry.set(key, handler);
6
+ }
7
+ export function resolveAction(key) {
8
+ return registry.get(key);
9
+ }
@@ -0,0 +1,6 @@
1
+ import type { ExtendDef } from '@coffer-org/sdk/extend';
2
+ export declare function ExtendReasonInfo({ ext, fieldLabel, valueLabel, }: {
3
+ ext: ExtendDef;
4
+ fieldLabel: (key: string) => string;
5
+ valueLabel?: (key: string, value: string | number | boolean) => string;
6
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from 'react-i18next';
3
+ import { describeCondition } from '@coffer-org/sdk/condition';
4
+ import { Icon } from "./Icon.js";
5
+ import { Popover, PopoverTrigger, PopoverContent } from "./ui/popover.js";
6
+ export function ExtendReasonInfo({ ext, fieldLabel, valueLabel, }) {
7
+ const { t } = useTranslation();
8
+ const clauses = describeCondition(ext.showWhen, fieldLabel, valueLabel);
9
+ if (clauses.length === 0)
10
+ return null;
11
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { type: "button", "aria-label": t('extend.shownWhen'), className: "inline-flex items-center text-muted hover:text-text", children: _jsx(Icon, { name: "lucide:info", size: 14 }) }), _jsxs(PopoverContent, { align: "start", className: "w-auto max-w-xs text-sm", children: [_jsx("p", { className: "text-muted mb-1", children: t('extend.shownWhen') }), _jsx("p", { children: clauses.join('; ') })] })] }));
12
+ }
@@ -0,0 +1,8 @@
1
+ export declare function FavoriteButton({ favorite, busy, onClick, labelAdd, labelRemove, variant, }: {
2
+ favorite: boolean;
3
+ busy?: boolean;
4
+ onClick: () => void;
5
+ labelAdd: string;
6
+ labelRemove: string;
7
+ variant?: 'ghost' | 'outline';
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Star } from 'lucide-react';
3
+ import { Button } from './ui/button';
4
+ export function FavoriteButton({ favorite, busy = false, onClick, labelAdd, labelRemove, variant = 'ghost', }) {
5
+ const label = favorite ? labelRemove : labelAdd;
6
+ return (_jsx(Button, { variant: variant, size: "icon", type: "button", disabled: busy, "aria-label": label, "aria-pressed": favorite, title: label, onClick: onClick, className: favorite ? 'text-accent hover:text-accent' : 'text-muted hover:text-text', children: _jsx(Star, { "data-icon": "inline-start", size: 16, fill: favorite ? 'currentColor' : 'none' }) }));
7
+ }
@@ -0,0 +1,6 @@
1
+ export declare function Icon({ name, size, className, strokeWidth, }: {
2
+ name?: string;
3
+ size?: number;
4
+ className?: string;
5
+ strokeWidth?: number;
6
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { HelpCircle } from 'lucide-react';
3
+ import { resolveIcon } from "./icons/registry.js";
4
+ export function Icon({ name, size = 16, className, strokeWidth, }) {
5
+ if (!name)
6
+ return null;
7
+ const node = resolveIcon(name, size, className, strokeWidth);
8
+ if (node !== undefined)
9
+ return _jsx(_Fragment, { children: node });
10
+ console.warn(`[Icon] unknown icon: ${name}`);
11
+ return _jsx(HelpCircle, { size: size, className: className, strokeWidth: strokeWidth });
12
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare function PageBody({ children }: {
3
+ children: React.ReactNode;
4
+ }): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function PageBody({ children }) {
3
+ return (_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsx("div", { className: "mx-auto max-w-7xl px-5 py-8 md:px-8", children: children }) }));
4
+ }
@@ -0,0 +1,8 @@
1
+ import type { ShelfDef } from '@coffer-org/sdk/shelf';
2
+ export declare function RecordInline({ shelf, row, size, height, className, }: {
3
+ shelf: ShelfDef;
4
+ row: Record<string, unknown>;
5
+ size?: 'sm' | 'md';
6
+ height?: number;
7
+ className?: string;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { inlineText, inlineImageKey } from '@coffer-org/sdk/shelf';
3
+ import { mediaUrl } from "../host-services.js";
4
+ import { OptionIconView } from "./ui/option-icon.js";
5
+ function firstImageName(value) {
6
+ if (typeof value !== 'string' || !value)
7
+ return undefined;
8
+ try {
9
+ const p = JSON.parse(value);
10
+ const first = Array.isArray(p) ? p[0] : p;
11
+ if (first && typeof first === 'object' && typeof first.name === 'string')
12
+ return first.name;
13
+ if (typeof first === 'string')
14
+ return first;
15
+ return undefined;
16
+ }
17
+ catch {
18
+ return value;
19
+ }
20
+ }
21
+ export function RecordInline({ shelf, row, size = 'md', height, className, }) {
22
+ const text = inlineText(shelf, row);
23
+ const imgKey = inlineImageKey(shelf);
24
+ const imgName = imgKey ? firstImageName(row[imgKey]) : undefined;
25
+ const icon = imgName
26
+ ? { kind: 'image', value: mediaUrl(imgName) }
27
+ : { kind: 'icon', value: shelf.icon ?? 'lucide:square' };
28
+ return (_jsxs("span", { className: `inline-flex min-w-0 items-center gap-2 ${className ?? ''}`, style: height ? { height, minHeight: height } : undefined, children: [imgKey && _jsx(OptionIconView, { icon: icon, size: size === 'sm' ? 'md' : 'lg', framed: true }), _jsx("span", { className: "truncate", children: text })] }));
29
+ }
@@ -0,0 +1 @@
1
+ export declare function SaveStatus(): import("react").JSX.Element | null;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Loader2 } from 'lucide-react';
4
+ import { useRecordSave } from "../render/record-save-ctx.js";
5
+ export function SaveStatus() {
6
+ const { t } = useTranslation();
7
+ const { saving } = useRecordSave();
8
+ if (!saving)
9
+ return null;
10
+ return (_jsxs("span", { className: "flex items-center gap-1.5 px-2 text-xs text-muted", "aria-live": "polite", children: [_jsx(Loader2, { size: 14, className: "animate-spin" }), _jsx("span", { className: "hidden sm:inline", children: t('save.saving') })] }));
11
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export declare function Toolbar({ children, actions }: {
3
+ children: React.ReactNode;
4
+ actions?: React.ReactNode;
5
+ }): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function Toolbar({ children, actions }) {
3
+ return (_jsxs("div", { "data-toolbar": true, className: "eink-solid sticky top-0 z-20 flex h-[52px] items-center justify-between gap-3 bg-bg/85 px-4 backdrop-blur md:px-6 border-b border-border2 shrink-0", children: [_jsx("div", { className: "flex items-center gap-2.5 min-w-0", children: children }), actions && (_jsx("div", { "data-toolbar-actions": true, className: "flex items-center gap-2 shrink-0", children: actions }))] }));
4
+ }
@@ -0,0 +1,2 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function colorIcon(name: string, size: number, className?: string): ReactNode;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { BASIC_COLORS } from '@coffer-org/sdk/color-names';
3
+ const BY_NAME = new Map(BASIC_COLORS.map((c) => [c.name, c.hex]));
4
+ const HEX_RE = /^#[0-9a-fA-F]{6}$/;
5
+ export function colorIcon(name, size, className) {
6
+ const hex = HEX_RE.test(name) ? name : BY_NAME.get(name);
7
+ if (!hex)
8
+ return null;
9
+ return (_jsx("span", { className: `shrink-0 inline-block rounded-full border border-border/60 ${className ?? ''}`, style: { width: size, height: size, backgroundColor: hex } }));
10
+ }
@@ -0,0 +1,2 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function flagIcon(name: string, size: number, className?: string): ReactNode;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ void import('flag-icons/css/flag-icons.min.css');
3
+ export function flagIcon(name, size, className) {
4
+ const code = name.toLowerCase();
5
+ return (_jsx("span", { className: `fi fi-${code} ${className ?? ''}`, style: { width: size, height: size * 0.75, display: 'inline-block', borderRadius: 2 } }));
6
+ }
@@ -0,0 +1,2 @@
1
+ import type { ReactNode } from 'react';
2
+ export declare function lucideIcon(name: string, size: number, className?: string, strokeWidth?: number): ReactNode;
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { IdCard, Antenna, Plane, Plus, Globe, Sprout, CookingPot, SlidersHorizontal, Ticket, Hospital, Hotel, User, Users, Pill, ClipboardList, Radio, RadioTower, Camera, Package, BatteryFull, Link, Monitor, Rocket, Bus, Shield, PlaneTakeoff, Satellite, FlaskConical, Stethoscope, Soup, Glasses, Puzzle, Settings, AlertTriangle, Hand, MapPin, Gauge, DoorOpen, PaintRoller, Zap, Calendar, Clock, CalendarClock, ArrowLeftRight, ArrowUp, ArrowDown, Bug, Check, Droplet, Folder, FolderOutput, Ghost, House, Info, Landmark, Layers, Play, Radar, Receipt, RefreshCw, Ruler, Square, Wallet, Wifi, X, Star, Minus, Activity, Bot, Search, LogOut, Trash2, Beaker, Bed, Box, CalendarDays, Carrot, Circle, Clapperboard, Code, CreditCard, HardDrive, Hash, Image, Key, Languages, List, ListChecks, MessageCircle, Network, NotebookPen, Route, Rows3, Server, ShieldCheck, ShoppingCart, Store, Tag, Terminal, Type, Upload, } from 'lucide-react';
3
+ const REGISTRY = {
4
+ 'id-card': IdCard,
5
+ antenna: Antenna,
6
+ plane: Plane,
7
+ plus: Plus,
8
+ globe: Globe,
9
+ sprout: Sprout,
10
+ 'cooking-pot': CookingPot,
11
+ 'sliders-horizontal': SlidersHorizontal,
12
+ ticket: Ticket,
13
+ hospital: Hospital,
14
+ hotel: Hotel,
15
+ user: User,
16
+ users: Users,
17
+ pill: Pill,
18
+ 'clipboard-list': ClipboardList,
19
+ radio: Radio,
20
+ 'radio-tower': RadioTower,
21
+ camera: Camera,
22
+ package: Package,
23
+ 'battery-full': BatteryFull,
24
+ link: Link,
25
+ monitor: Monitor,
26
+ rocket: Rocket,
27
+ bus: Bus,
28
+ shield: Shield,
29
+ 'plane-takeoff': PlaneTakeoff,
30
+ satellite: Satellite,
31
+ 'flask-conical': FlaskConical,
32
+ stethoscope: Stethoscope,
33
+ soup: Soup,
34
+ glasses: Glasses,
35
+ puzzle: Puzzle,
36
+ settings: Settings,
37
+ 'alert-triangle': AlertTriangle,
38
+ hand: Hand,
39
+ 'map-pin': MapPin,
40
+ gauge: Gauge,
41
+ 'door-open': DoorOpen,
42
+ 'paint-roller': PaintRoller,
43
+ zap: Zap,
44
+ calendar: Calendar,
45
+ clock: Clock,
46
+ 'calendar-clock': CalendarClock,
47
+ 'arrow-left-right': ArrowLeftRight,
48
+ 'arrow-up': ArrowUp,
49
+ 'arrow-down': ArrowDown,
50
+ bug: Bug,
51
+ check: Check,
52
+ droplet: Droplet,
53
+ folder: Folder,
54
+ 'folder-output': FolderOutput,
55
+ ghost: Ghost,
56
+ house: House,
57
+ info: Info,
58
+ landmark: Landmark,
59
+ layers: Layers,
60
+ play: Play,
61
+ radar: Radar,
62
+ receipt: Receipt,
63
+ 'refresh-cw': RefreshCw,
64
+ ruler: Ruler,
65
+ square: Square,
66
+ wallet: Wallet,
67
+ wifi: Wifi,
68
+ x: X,
69
+ star: Star,
70
+ minus: Minus,
71
+ activity: Activity,
72
+ bot: Bot,
73
+ search: Search,
74
+ 'log-out': LogOut,
75
+ 'trash-2': Trash2,
76
+ beaker: Beaker,
77
+ bed: Bed,
78
+ box: Box,
79
+ 'calendar-days': CalendarDays,
80
+ carrot: Carrot,
81
+ circle: Circle,
82
+ clapperboard: Clapperboard,
83
+ code: Code,
84
+ 'credit-card': CreditCard,
85
+ 'hard-drive': HardDrive,
86
+ hash: Hash,
87
+ image: Image,
88
+ key: Key,
89
+ languages: Languages,
90
+ list: List,
91
+ 'list-checks': ListChecks,
92
+ 'message-circle': MessageCircle,
93
+ network: Network,
94
+ 'notebook-pen': NotebookPen,
95
+ route: Route,
96
+ 'rows-3': Rows3,
97
+ server: Server,
98
+ 'shield-check': ShieldCheck,
99
+ 'shopping-cart': ShoppingCart,
100
+ store: Store,
101
+ tag: Tag,
102
+ terminal: Terminal,
103
+ type: Type,
104
+ upload: Upload,
105
+ };
106
+ export function lucideIcon(name, size, className, strokeWidth) {
107
+ const Cmp = REGISTRY[name];
108
+ if (!Cmp)
109
+ return null;
110
+ return _jsx(Cmp, { size: size, className: className, strokeWidth: strokeWidth });
111
+ }
@@ -0,0 +1,4 @@
1
+ import type { ReactNode } from 'react';
2
+ export type IconProvider = (name: string, size: number, className?: string, strokeWidth?: number) => ReactNode;
3
+ export declare const providers: Record<string, IconProvider>;
4
+ export declare function resolveIcon(raw: string, size: number, className?: string, strokeWidth?: number): ReactNode | undefined;