tempest-react-sdk 0.46.0 → 0.48.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 (371) hide show
  1. package/dist/components/AppBar/use-sticky-body-warning.cjs +1 -1
  2. package/dist/components/AppBar/use-sticky-body-warning.cjs.map +1 -1
  3. package/dist/components/AppBar/use-sticky-body-warning.js +5 -8
  4. package/dist/components/AppBar/use-sticky-body-warning.js.map +1 -1
  5. package/dist/components/DataTable/use-dev-warnings.cjs +1 -1
  6. package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -1
  7. package/dist/components/DataTable/use-dev-warnings.js +8 -7
  8. package/dist/components/DataTable/use-dev-warnings.js.map +1 -1
  9. package/dist/components/Sidebar/Sidebar.cjs +1 -1
  10. package/dist/components/Sidebar/Sidebar.cjs.map +1 -1
  11. package/dist/components/Sidebar/Sidebar.js +91 -38
  12. package/dist/components/Sidebar/Sidebar.js.map +1 -1
  13. package/dist/components/Sidebar/Sidebar.module.cjs +1 -1
  14. package/dist/components/Sidebar/Sidebar.module.cjs.map +1 -1
  15. package/dist/components/Sidebar/Sidebar.module.js +12 -8
  16. package/dist/components/Sidebar/Sidebar.module.js.map +1 -1
  17. package/dist/http/api-client.cjs +1 -1
  18. package/dist/http/api-client.cjs.map +1 -1
  19. package/dist/http/api-client.js +45 -31
  20. package/dist/http/api-client.js.map +1 -1
  21. package/dist/http/describe-api-error.cjs +1 -1
  22. package/dist/http/describe-api-error.cjs.map +1 -1
  23. package/dist/http/describe-api-error.js +11 -7
  24. package/dist/http/describe-api-error.js.map +1 -1
  25. package/dist/http/errors.cjs +1 -1
  26. package/dist/http/errors.cjs.map +1 -1
  27. package/dist/http/errors.js +38 -21
  28. package/dist/http/errors.js.map +1 -1
  29. package/dist/http/use-describe-api-error.cjs +1 -1
  30. package/dist/http/use-describe-api-error.cjs.map +1 -1
  31. package/dist/http/use-describe-api-error.js +14 -10
  32. package/dist/http/use-describe-api-error.js.map +1 -1
  33. package/dist/icons/Icon.cjs +1 -1
  34. package/dist/icons/Icon.cjs.map +1 -1
  35. package/dist/icons/Icon.js +17 -18
  36. package/dist/icons/Icon.js.map +1 -1
  37. package/dist/icons/IconPicker.cjs +2 -0
  38. package/dist/icons/IconPicker.cjs.map +1 -0
  39. package/dist/icons/IconPicker.js +49 -0
  40. package/dist/icons/IconPicker.js.map +1 -0
  41. package/dist/icons/IconPicker.module.cjs +2 -0
  42. package/dist/icons/IconPicker.module.cjs.map +1 -0
  43. package/dist/icons/IconPicker.module.js +10 -0
  44. package/dist/icons/IconPicker.module.js.map +1 -0
  45. package/dist/icons/alias.cjs +2 -0
  46. package/dist/icons/alias.cjs.map +1 -0
  47. package/dist/icons/alias.js +9 -0
  48. package/dist/icons/alias.js.map +1 -0
  49. package/dist/icons/generated/loaders.cjs +1 -1
  50. package/dist/icons/generated/loaders.cjs.map +1 -1
  51. package/dist/icons/generated/loaders.js +273 -28
  52. package/dist/icons/generated/loaders.js.map +1 -1
  53. package/dist/icons/generated/shard-00.cjs +2 -0
  54. package/dist/icons/generated/shard-00.cjs.map +1 -0
  55. package/dist/icons/generated/shard-00.js +48 -0
  56. package/dist/icons/generated/shard-00.js.map +1 -0
  57. package/dist/icons/generated/shard-01.cjs +2 -0
  58. package/dist/icons/generated/shard-01.cjs.map +1 -0
  59. package/dist/icons/generated/shard-01.js +48 -0
  60. package/dist/icons/generated/shard-01.js.map +1 -0
  61. package/dist/icons/generated/shard-02.cjs +2 -0
  62. package/dist/icons/generated/shard-02.cjs.map +1 -0
  63. package/dist/icons/generated/shard-02.js +48 -0
  64. package/dist/icons/generated/shard-02.js.map +1 -0
  65. package/dist/icons/generated/shard-03.cjs +2 -0
  66. package/dist/icons/generated/shard-03.cjs.map +1 -0
  67. package/dist/icons/generated/shard-03.js +48 -0
  68. package/dist/icons/generated/shard-03.js.map +1 -0
  69. package/dist/icons/generated/shard-04.cjs +2 -0
  70. package/dist/icons/generated/shard-04.cjs.map +1 -0
  71. package/dist/icons/generated/shard-04.js +48 -0
  72. package/dist/icons/generated/shard-04.js.map +1 -0
  73. package/dist/icons/generated/shard-05.cjs +2 -0
  74. package/dist/icons/generated/shard-05.cjs.map +1 -0
  75. package/dist/icons/generated/shard-05.js +48 -0
  76. package/dist/icons/generated/shard-05.js.map +1 -0
  77. package/dist/icons/generated/shard-06.cjs +2 -0
  78. package/dist/icons/generated/shard-06.cjs.map +1 -0
  79. package/dist/icons/generated/shard-06.js +48 -0
  80. package/dist/icons/generated/shard-06.js.map +1 -0
  81. package/dist/icons/generated/shard-07.cjs +2 -0
  82. package/dist/icons/generated/shard-07.cjs.map +1 -0
  83. package/dist/icons/generated/shard-07.js +48 -0
  84. package/dist/icons/generated/shard-07.js.map +1 -0
  85. package/dist/icons/generated/shard-08.cjs +2 -0
  86. package/dist/icons/generated/shard-08.cjs.map +1 -0
  87. package/dist/icons/generated/shard-08.js +48 -0
  88. package/dist/icons/generated/shard-08.js.map +1 -0
  89. package/dist/icons/generated/shard-09.cjs +2 -0
  90. package/dist/icons/generated/shard-09.cjs.map +1 -0
  91. package/dist/icons/generated/shard-09.js +48 -0
  92. package/dist/icons/generated/shard-09.js.map +1 -0
  93. package/dist/icons/generated/shard-10.cjs +2 -0
  94. package/dist/icons/generated/shard-10.cjs.map +1 -0
  95. package/dist/icons/generated/shard-10.js +48 -0
  96. package/dist/icons/generated/shard-10.js.map +1 -0
  97. package/dist/icons/generated/shard-11.cjs +2 -0
  98. package/dist/icons/generated/shard-11.cjs.map +1 -0
  99. package/dist/icons/generated/shard-11.js +48 -0
  100. package/dist/icons/generated/shard-11.js.map +1 -0
  101. package/dist/icons/generated/shard-12.cjs +2 -0
  102. package/dist/icons/generated/shard-12.cjs.map +1 -0
  103. package/dist/icons/generated/shard-12.js +48 -0
  104. package/dist/icons/generated/shard-12.js.map +1 -0
  105. package/dist/icons/generated/shard-13.cjs +2 -0
  106. package/dist/icons/generated/shard-13.cjs.map +1 -0
  107. package/dist/icons/generated/shard-13.js +48 -0
  108. package/dist/icons/generated/shard-13.js.map +1 -0
  109. package/dist/icons/generated/shard-14.cjs +2 -0
  110. package/dist/icons/generated/shard-14.cjs.map +1 -0
  111. package/dist/icons/generated/shard-14.js +48 -0
  112. package/dist/icons/generated/shard-14.js.map +1 -0
  113. package/dist/icons/generated/shard-15.cjs +2 -0
  114. package/dist/icons/generated/shard-15.cjs.map +1 -0
  115. package/dist/icons/generated/shard-15.js +48 -0
  116. package/dist/icons/generated/shard-15.js.map +1 -0
  117. package/dist/icons/generated/shard-16.cjs +2 -0
  118. package/dist/icons/generated/shard-16.cjs.map +1 -0
  119. package/dist/icons/generated/shard-16.js +48 -0
  120. package/dist/icons/generated/shard-16.js.map +1 -0
  121. package/dist/icons/generated/shard-17.cjs +2 -0
  122. package/dist/icons/generated/shard-17.cjs.map +1 -0
  123. package/dist/icons/generated/shard-17.js +48 -0
  124. package/dist/icons/generated/shard-17.js.map +1 -0
  125. package/dist/icons/generated/shard-18.cjs +2 -0
  126. package/dist/icons/generated/shard-18.cjs.map +1 -0
  127. package/dist/icons/generated/shard-18.js +48 -0
  128. package/dist/icons/generated/shard-18.js.map +1 -0
  129. package/dist/icons/generated/shard-19.cjs +2 -0
  130. package/dist/icons/generated/shard-19.cjs.map +1 -0
  131. package/dist/icons/generated/shard-19.js +48 -0
  132. package/dist/icons/generated/shard-19.js.map +1 -0
  133. package/dist/icons/generated/shard-20.cjs +2 -0
  134. package/dist/icons/generated/shard-20.cjs.map +1 -0
  135. package/dist/icons/generated/shard-20.js +48 -0
  136. package/dist/icons/generated/shard-20.js.map +1 -0
  137. package/dist/icons/generated/shard-21.cjs +2 -0
  138. package/dist/icons/generated/shard-21.cjs.map +1 -0
  139. package/dist/icons/generated/shard-21.js +48 -0
  140. package/dist/icons/generated/shard-21.js.map +1 -0
  141. package/dist/icons/generated/shard-22.cjs +2 -0
  142. package/dist/icons/generated/shard-22.cjs.map +1 -0
  143. package/dist/icons/generated/shard-22.js +48 -0
  144. package/dist/icons/generated/shard-22.js.map +1 -0
  145. package/dist/icons/generated/shard-23.cjs +2 -0
  146. package/dist/icons/generated/shard-23.cjs.map +1 -0
  147. package/dist/icons/generated/shard-23.js +48 -0
  148. package/dist/icons/generated/shard-23.js.map +1 -0
  149. package/dist/icons/generated/shard-24.cjs +2 -0
  150. package/dist/icons/generated/shard-24.cjs.map +1 -0
  151. package/dist/icons/generated/shard-24.js +48 -0
  152. package/dist/icons/generated/shard-24.js.map +1 -0
  153. package/dist/icons/generated/shard-25.cjs +2 -0
  154. package/dist/icons/generated/shard-25.cjs.map +1 -0
  155. package/dist/icons/generated/shard-25.js +48 -0
  156. package/dist/icons/generated/shard-25.js.map +1 -0
  157. package/dist/icons/generated/shard-26.cjs +2 -0
  158. package/dist/icons/generated/shard-26.cjs.map +1 -0
  159. package/dist/icons/generated/shard-26.js +48 -0
  160. package/dist/icons/generated/shard-26.js.map +1 -0
  161. package/dist/icons/generated/shard-27.cjs +2 -0
  162. package/dist/icons/generated/shard-27.cjs.map +1 -0
  163. package/dist/icons/generated/shard-27.js +48 -0
  164. package/dist/icons/generated/shard-27.js.map +1 -0
  165. package/dist/icons/generated/shard-28.cjs +2 -0
  166. package/dist/icons/generated/shard-28.cjs.map +1 -0
  167. package/dist/icons/generated/shard-28.js +48 -0
  168. package/dist/icons/generated/shard-28.js.map +1 -0
  169. package/dist/icons/generated/shard-29.cjs +2 -0
  170. package/dist/icons/generated/shard-29.cjs.map +1 -0
  171. package/dist/icons/generated/shard-29.js +48 -0
  172. package/dist/icons/generated/shard-29.js.map +1 -0
  173. package/dist/icons/generated/shard-30.cjs +2 -0
  174. package/dist/icons/generated/shard-30.cjs.map +1 -0
  175. package/dist/icons/generated/shard-30.js +48 -0
  176. package/dist/icons/generated/shard-30.js.map +1 -0
  177. package/dist/icons/generated/shard-31.cjs +2 -0
  178. package/dist/icons/generated/shard-31.cjs.map +1 -0
  179. package/dist/icons/generated/shard-31.js +48 -0
  180. package/dist/icons/generated/shard-31.js.map +1 -0
  181. package/dist/icons/generated/shard-32.cjs +2 -0
  182. package/dist/icons/generated/shard-32.cjs.map +1 -0
  183. package/dist/icons/generated/shard-32.js +48 -0
  184. package/dist/icons/generated/shard-32.js.map +1 -0
  185. package/dist/icons/generated/shard-33.cjs +2 -0
  186. package/dist/icons/generated/shard-33.cjs.map +1 -0
  187. package/dist/icons/generated/shard-33.js +48 -0
  188. package/dist/icons/generated/shard-33.js.map +1 -0
  189. package/dist/icons/generated/shard-34.cjs +2 -0
  190. package/dist/icons/generated/shard-34.cjs.map +1 -0
  191. package/dist/icons/generated/shard-34.js +48 -0
  192. package/dist/icons/generated/shard-34.js.map +1 -0
  193. package/dist/icons/generated/shard-35.cjs +2 -0
  194. package/dist/icons/generated/shard-35.cjs.map +1 -0
  195. package/dist/icons/generated/shard-35.js +48 -0
  196. package/dist/icons/generated/shard-35.js.map +1 -0
  197. package/dist/icons/generated/shard-36.cjs +2 -0
  198. package/dist/icons/generated/shard-36.cjs.map +1 -0
  199. package/dist/icons/generated/shard-36.js +48 -0
  200. package/dist/icons/generated/shard-36.js.map +1 -0
  201. package/dist/icons/generated/shard-37.cjs +2 -0
  202. package/dist/icons/generated/shard-37.cjs.map +1 -0
  203. package/dist/icons/generated/shard-37.js +48 -0
  204. package/dist/icons/generated/shard-37.js.map +1 -0
  205. package/dist/icons/generated/shard-38.cjs +2 -0
  206. package/dist/icons/generated/shard-38.cjs.map +1 -0
  207. package/dist/icons/generated/shard-38.js +48 -0
  208. package/dist/icons/generated/shard-38.js.map +1 -0
  209. package/dist/icons/generated/shard-39.cjs +2 -0
  210. package/dist/icons/generated/shard-39.cjs.map +1 -0
  211. package/dist/icons/generated/shard-39.js +48 -0
  212. package/dist/icons/generated/shard-39.js.map +1 -0
  213. package/dist/icons/generated/shard-40.cjs +2 -0
  214. package/dist/icons/generated/shard-40.cjs.map +1 -0
  215. package/dist/icons/generated/shard-40.js +48 -0
  216. package/dist/icons/generated/shard-40.js.map +1 -0
  217. package/dist/icons/generated/shard-41.cjs +2 -0
  218. package/dist/icons/generated/shard-41.cjs.map +1 -0
  219. package/dist/icons/generated/shard-41.js +48 -0
  220. package/dist/icons/generated/shard-41.js.map +1 -0
  221. package/dist/icons/generated/shard-42.cjs +2 -0
  222. package/dist/icons/generated/shard-42.cjs.map +1 -0
  223. package/dist/icons/generated/shard-42.js +48 -0
  224. package/dist/icons/generated/shard-42.js.map +1 -0
  225. package/dist/icons/generated/shard-43.cjs +2 -0
  226. package/dist/icons/generated/shard-43.cjs.map +1 -0
  227. package/dist/icons/generated/shard-43.js +48 -0
  228. package/dist/icons/generated/shard-43.js.map +1 -0
  229. package/dist/icons/generated/shard-44.cjs +2 -0
  230. package/dist/icons/generated/shard-44.cjs.map +1 -0
  231. package/dist/icons/generated/shard-44.js +15 -0
  232. package/dist/icons/generated/shard-44.js.map +1 -0
  233. package/dist/icons/material-symbols.cjs +1 -1
  234. package/dist/icons/material-symbols.cjs.map +1 -1
  235. package/dist/icons/material-symbols.js +109 -1
  236. package/dist/icons/material-symbols.js.map +1 -1
  237. package/dist/icons/normalize-icon-name.cjs +2 -0
  238. package/dist/icons/normalize-icon-name.cjs.map +1 -0
  239. package/dist/icons/normalize-icon-name.js +9 -0
  240. package/dist/icons/normalize-icon-name.js.map +1 -0
  241. package/dist/icons/shard-cache.cjs +1 -1
  242. package/dist/icons/shard-cache.cjs.map +1 -1
  243. package/dist/icons/shard-cache.js +85 -32
  244. package/dist/icons/shard-cache.js.map +1 -1
  245. package/dist/icons/validate-icon-name.cjs +2 -0
  246. package/dist/icons/validate-icon-name.cjs.map +1 -0
  247. package/dist/icons/validate-icon-name.js +11 -0
  248. package/dist/icons/validate-icon-name.js.map +1 -0
  249. package/dist/icons-virtual-id.d.ts +24 -0
  250. package/dist/icons-virtual.cjs +2 -0
  251. package/dist/icons-virtual.cjs.map +1 -0
  252. package/dist/icons-virtual.d.ts +30 -22
  253. package/dist/icons-virtual.js +6 -0
  254. package/dist/icons-virtual.js.map +1 -0
  255. package/dist/icons.cjs +1 -1
  256. package/dist/icons.d.ts +269 -32
  257. package/dist/icons.js +11 -7
  258. package/dist/styles.css +1 -1
  259. package/dist/tempest-react-sdk.cjs +1 -1
  260. package/dist/tempest-react-sdk.d.ts +95 -28
  261. package/dist/tempest-react-sdk.js +106 -106
  262. package/dist/utils/dev-mode.cjs +2 -0
  263. package/dist/utils/dev-mode.cjs.map +1 -0
  264. package/dist/utils/dev-mode.js +12 -0
  265. package/dist/utils/dev-mode.js.map +1 -0
  266. package/dist/vite/tempest-icons.cjs +4 -4
  267. package/dist/vite/tempest-icons.cjs.map +1 -1
  268. package/dist/vite/tempest-icons.js +26 -26
  269. package/dist/vite/tempest-icons.js.map +1 -1
  270. package/dist/vite.d.ts +1 -1
  271. package/package.json +5 -2
  272. package/dist/icons/generated/shard-a.cjs +0 -2
  273. package/dist/icons/generated/shard-a.cjs.map +0 -1
  274. package/dist/icons/generated/shard-a.js +0 -114
  275. package/dist/icons/generated/shard-a.js.map +0 -1
  276. package/dist/icons/generated/shard-b.cjs +0 -2
  277. package/dist/icons/generated/shard-b.cjs.map +0 -1
  278. package/dist/icons/generated/shard-b.js +0 -158
  279. package/dist/icons/generated/shard-b.js.map +0 -1
  280. package/dist/icons/generated/shard-c.cjs +0 -2
  281. package/dist/icons/generated/shard-c.cjs.map +0 -1
  282. package/dist/icons/generated/shard-c.js +0 -269
  283. package/dist/icons/generated/shard-c.js.map +0 -1
  284. package/dist/icons/generated/shard-d.cjs +0 -2
  285. package/dist/icons/generated/shard-d.cjs.map +0 -1
  286. package/dist/icons/generated/shard-d.js +0 -62
  287. package/dist/icons/generated/shard-d.js.map +0 -1
  288. package/dist/icons/generated/shard-e.cjs +0 -2
  289. package/dist/icons/generated/shard-e.cjs.map +0 -1
  290. package/dist/icons/generated/shard-e.js +0 -33
  291. package/dist/icons/generated/shard-e.js.map +0 -1
  292. package/dist/icons/generated/shard-f.cjs +0 -2
  293. package/dist/icons/generated/shard-f.cjs.map +0 -1
  294. package/dist/icons/generated/shard-f.js +0 -145
  295. package/dist/icons/generated/shard-f.js.map +0 -1
  296. package/dist/icons/generated/shard-g.cjs +0 -2
  297. package/dist/icons/generated/shard-g.cjs.map +0 -1
  298. package/dist/icons/generated/shard-g.js +0 -61
  299. package/dist/icons/generated/shard-g.js.map +0 -1
  300. package/dist/icons/generated/shard-h.cjs +0 -2
  301. package/dist/icons/generated/shard-h.cjs.map +0 -1
  302. package/dist/icons/generated/shard-h.js +0 -62
  303. package/dist/icons/generated/shard-h.js.map +0 -1
  304. package/dist/icons/generated/shard-i.cjs +0 -2
  305. package/dist/icons/generated/shard-i.cjs.map +0 -1
  306. package/dist/icons/generated/shard-i.js +0 -30
  307. package/dist/icons/generated/shard-i.js.map +0 -1
  308. package/dist/icons/generated/shard-j.cjs +0 -2
  309. package/dist/icons/generated/shard-j.cjs.map +0 -1
  310. package/dist/icons/generated/shard-j.js +0 -10
  311. package/dist/icons/generated/shard-j.js.map +0 -1
  312. package/dist/icons/generated/shard-k.cjs +0 -2
  313. package/dist/icons/generated/shard-k.cjs.map +0 -1
  314. package/dist/icons/generated/shard-k.js +0 -16
  315. package/dist/icons/generated/shard-k.js.map +0 -1
  316. package/dist/icons/generated/shard-l.cjs +0 -2
  317. package/dist/icons/generated/shard-l.cjs.map +0 -1
  318. package/dist/icons/generated/shard-l.js +0 -92
  319. package/dist/icons/generated/shard-l.js.map +0 -1
  320. package/dist/icons/generated/shard-m.cjs +0 -2
  321. package/dist/icons/generated/shard-m.cjs.map +0 -1
  322. package/dist/icons/generated/shard-m.js +0 -143
  323. package/dist/icons/generated/shard-m.js.map +0 -1
  324. package/dist/icons/generated/shard-n.cjs +0 -2
  325. package/dist/icons/generated/shard-n.cjs.map +0 -1
  326. package/dist/icons/generated/shard-n.js +0 -24
  327. package/dist/icons/generated/shard-n.js.map +0 -1
  328. package/dist/icons/generated/shard-o.cjs +0 -2
  329. package/dist/icons/generated/shard-o.cjs.map +0 -1
  330. package/dist/icons/generated/shard-o.js +0 -17
  331. package/dist/icons/generated/shard-o.js.map +0 -1
  332. package/dist/icons/generated/shard-p.cjs +0 -2
  333. package/dist/icons/generated/shard-p.cjs.map +0 -1
  334. package/dist/icons/generated/shard-p.js +0 -114
  335. package/dist/icons/generated/shard-p.js.map +0 -1
  336. package/dist/icons/generated/shard-q.cjs +0 -2
  337. package/dist/icons/generated/shard-q.cjs.map +0 -1
  338. package/dist/icons/generated/shard-q.js +0 -10
  339. package/dist/icons/generated/shard-q.js.map +0 -1
  340. package/dist/icons/generated/shard-r.cjs +0 -2
  341. package/dist/icons/generated/shard-r.cjs.map +0 -1
  342. package/dist/icons/generated/shard-r.js +0 -79
  343. package/dist/icons/generated/shard-r.js.map +0 -1
  344. package/dist/icons/generated/shard-s.cjs +0 -2
  345. package/dist/icons/generated/shard-s.cjs.map +0 -1
  346. package/dist/icons/generated/shard-s.js +0 -256
  347. package/dist/icons/generated/shard-s.js.map +0 -1
  348. package/dist/icons/generated/shard-t.cjs +0 -2
  349. package/dist/icons/generated/shard-t.cjs.map +0 -1
  350. package/dist/icons/generated/shard-t.js +0 -109
  351. package/dist/icons/generated/shard-t.js.map +0 -1
  352. package/dist/icons/generated/shard-u.cjs +0 -2
  353. package/dist/icons/generated/shard-u.cjs.map +0 -1
  354. package/dist/icons/generated/shard-u.js +0 -50
  355. package/dist/icons/generated/shard-u.js.map +0 -1
  356. package/dist/icons/generated/shard-v.cjs +0 -2
  357. package/dist/icons/generated/shard-v.cjs.map +0 -1
  358. package/dist/icons/generated/shard-v.js +0 -30
  359. package/dist/icons/generated/shard-v.js.map +0 -1
  360. package/dist/icons/generated/shard-w.cjs +0 -2
  361. package/dist/icons/generated/shard-w.cjs.map +0 -1
  362. package/dist/icons/generated/shard-w.js +0 -48
  363. package/dist/icons/generated/shard-w.js.map +0 -1
  364. package/dist/icons/generated/shard-x.cjs +0 -2
  365. package/dist/icons/generated/shard-x.cjs.map +0 -1
  366. package/dist/icons/generated/shard-x.js +0 -10
  367. package/dist/icons/generated/shard-x.js.map +0 -1
  368. package/dist/icons/generated/shard-z.cjs +0 -2
  369. package/dist/icons/generated/shard-z.cjs.map +0 -1
  370. package/dist/icons/generated/shard-z.js +0 -25
  371. package/dist/icons/generated/shard-z.js.map +0 -1
@@ -1,2 +1,2 @@
1
- var e=`circle-question-mark`,t={brush:`brush`,build:`wrench`,code:`code`,delivery_dining:`bike`,electrical_services:`plug-zap`,format_paint:`paint-roller`,gavel:`gavel`,handyman:`wrench`,hardware:`wrench`,key:`key`,lock:`lock`,mic:`mic`,palette:`palette`,pedal_bike:`bike`,plumbing:`shower-head`,router:`router`,settings:`settings`,shield:`shield`,smartphone:`smartphone`,tv:`tv`,two_wheeler:`bike`,warehouse:`warehouse`};function n(n,r=e){return n?t[n.trim().toLowerCase()]??r:r}exports.MATERIAL_SYMBOL_FALLBACK=e,exports.fromMaterialSymbol=n,exports.materialToLucide=t;
1
+ var e=`circle-question-mark`,t={ac_unit:`snowflake`,account_balance:`landmark`,add:`plus`,balance:`scale`,bar_chart:`chart-column`,battery_full:`battery-full`,bluetooth:`bluetooth`,bolt:`zap`,brush:`brush`,build:`wrench`,cake:`cake`,calculate:`calculator`,campaign:`megaphone`,car_repair:`car`,carpenter:`hammer`,chair:`armchair`,chat:`message-circle`,check:`check`,child_care:`baby`,cleaning_services:`spray-can`,close:`x`,cloud:`cloud`,code:`code`,computer:`monitor`,construction:`hard-hat`,content_cut:`scissors`,credit_card:`credit-card`,dashboard:`layout-dashboard`,delete:`trash-2`,delivery_dining:`bike`,dentistry:`face-slightly-smiling`,description:`file-text`,directions_car:`car`,door_front:`door-open`,download:`download`,edit:`pencil`,electrical_services:`plug-zap`,error:`circle-x`,event:`calendar`,favorite:`heart`,fitness_center:`dumbbell`,flight:`plane`,folder:`folder`,format_paint:`paint-roller`,forum:`messages-square`,gavel:`gavel`,grass:`sprout`,group:`users`,groups:`users`,handyman:`wrench`,hardware:`wrench`,help:`circle-question-mark`,history:`rotate-ccw-clock`,home:`house`,hotel:`bed-double`,image:`image`,info:`info`,iron:`shirt`,key:`key`,kitchen:`refrigerator`,laptop:`laptop`,local_bar:`wine`,local_cafe:`coffee`,local_florist:`flower`,local_gas_station:`fuel`,local_laundry_service:`washing-machine`,local_shipping:`truck`,local_taxi:`car-taxi-front`,location_on:`map-pin`,lock:`lock`,lock_open:`lock-open`,login:`log-in`,logout:`log-out`,mail:`mail`,map:`map`,medical_services:`stethoscope`,menu:`menu`,mic:`mic`,music_note:`music`,notifications:`bell`,palette:`palette`,payments:`banknote`,pedal_bike:`bike`,person:`user`,pest_control:`bug`,pets:`paw-print`,phone:`phone`,phone_iphone:`smartphone`,photo_camera:`camera`,pie_chart:`chart-pie`,plumbing:`shower-head`,print:`printer`,receipt_long:`receipt`,restaurant:`utensils`,roofing:`house`,router:`router`,savings:`piggy-bank`,schedule:`clock`,school:`graduation-cap`,search:`search`,security:`shield-check`,settings:`settings`,share:`share-2`,shield:`shield`,shopping_bag:`shopping-bag`,shopping_cart:`shopping-cart`,smartphone:`smartphone`,soap:`soap-dispenser-droplet`,spa:`flower-2`,star:`star`,store:`store`,storefront:`store`,support_agent:`headset`,sync:`refresh-cw`,today:`calendar-days`,translate:`languages`,trending_up:`trending-up`,tv:`tv`,two_wheeler:`bike`,upload:`upload`,vaccines:`syringe`,verified:`badge-check`,videocam:`video`,visibility:`eye`,warehouse:`warehouse`,warning:`triangle-alert`,water_drop:`droplet`,wifi:`wifi`,work:`briefcase`,yard:`trees`};function n(n,r=e){return n?t[n.trim().toLowerCase()]??r:r}exports.MATERIAL_SYMBOL_FALLBACK=e,exports.fromMaterialSymbol=n,exports.materialToLucide=t;
2
2
  //# sourceMappingURL=material-symbols.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"material-symbols.cjs","names":[],"sources":["../../src/icons/material-symbols.ts"],"sourcesContent":["import type { IconName } from \"./generated/icon-name\";\n\n/**\n * The slug `fromMaterialSymbol` falls back to when a code is unknown.\n *\n * A neutral glyph rather than nothing: a category created in an admin with a\n * code this table has not learned yet still has to draw something, or it opens a\n * hole in the grid and the bug reads as a layout problem instead of a missing\n * mapping.\n *\n * Lucide's `circle-help` is a deprecated alias of this slug. `<Icon>` resolves\n * aliases, so both render — but the bridge emits the canonical name, since a\n * value that gets persisted should not be one lucide has already renamed.\n */\nexport const MATERIAL_SYMBOL_FALLBACK: IconName = \"circle-question-mark\";\n\n/**\n * Material Symbols code → lucide slug, for backends that store `icon_code`.\n *\n * Every Python backend we write stores a category icon as a Material Symbol\n * (`build`, `format_paint`, `electrical_services`) — the vocabulary Flutter,\n * Android and the administrative seeds already speak. The SDK speaks lucide in\n * kebab-case. The two lists do not meet, and the failure is nastier than an\n * empty screen: a handful of codes collide by accident, so roughly one row in\n * ten draws the right icon and the bug reads as \"some icons went missing\".\n *\n * **This is a seed table, not the full vocabulary.** Material Symbols ships\n * ~3600 names and almost none of them will ever appear in an `icon_code` of\n * ours. It grows on demand, one hand-written pair at a time — a map generated by\n * name heuristics gets it badly wrong, starting with `build`, which is a wrench\n * in Material Symbols and not anything to do with construction.\n *\n * **Approximations, deliberate and not one-to-one:**\n *\n * - `plumbing` → `shower-head`, because lucide has no pipe.\n * - `build`, `handyman` and `hardware` all land on `wrench` — Material Symbols\n * distinguishes the tools, lucide does not.\n * - `pedal_bike`, `two_wheeler` and `delivery_dining` all land on `bike`.\n *\n * The thirteen identity pairs are here on purpose. Their names happen to match\n * in both vocabularies, so they already render today — leaving them out would\n * send them to {@link MATERIAL_SYMBOL_FALLBACK} and make this bridge a\n * regression for exactly the codes that used to work.\n *\n * @see fromMaterialSymbol — the lookup you normally call.\n */\nexport const materialToLucide: Readonly<Record<string, IconName>> = {\n brush: \"brush\",\n build: \"wrench\",\n code: \"code\",\n delivery_dining: \"bike\",\n electrical_services: \"plug-zap\",\n format_paint: \"paint-roller\",\n gavel: \"gavel\",\n handyman: \"wrench\",\n hardware: \"wrench\",\n key: \"key\",\n lock: \"lock\",\n mic: \"mic\",\n palette: \"palette\",\n pedal_bike: \"bike\",\n plumbing: \"shower-head\",\n router: \"router\",\n settings: \"settings\",\n shield: \"shield\",\n smartphone: \"smartphone\",\n tv: \"tv\",\n two_wheeler: \"bike\",\n warehouse: \"warehouse\",\n};\n\n/**\n * Translate a Material Symbols code into a lucide slug, always returning one.\n *\n * Never returns `undefined`: an unknown code resolves to `fallback`, so a row\n * whose `icon_code` this table has not learned yet still renders. The input is\n * trimmed and lower-cased before lookup, because a seed written by hand is the\n * kind of source that carries stray whitespace and the odd capital.\n *\n * Nothing else in `/icons` imports this module, so an app that does not store\n * Material Symbols never pays for the table.\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code)} size={20} />\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code, \"folder\")} size={20} />\n *\n * @param code - A Material Symbols name, or `null`/`undefined` for a row that has none.\n * @param fallback - Slug to use when `code` is empty or unknown. Defaults to {@link MATERIAL_SYMBOL_FALLBACK}.\n * @returns A lucide slug `<Icon>` can render.\n */\nexport function fromMaterialSymbol(\n code: string | null | undefined,\n fallback: IconName = MATERIAL_SYMBOL_FALLBACK,\n): IconName {\n if (!code) return fallback;\n return materialToLucide[code.trim().toLowerCase()] ?? fallback;\n}\n"],"mappings":"AAcA,IAAa,EAAqC,uBAgCrC,EAAuD,CAChE,MAAO,QACP,MAAO,SACP,KAAM,OACN,gBAAiB,OACjB,oBAAqB,WACrB,aAAc,eACd,MAAO,QACP,SAAU,SACV,SAAU,SACV,IAAK,MACL,KAAM,OACN,IAAK,MACL,QAAS,UACT,WAAY,OACZ,SAAU,cACV,OAAQ,SACR,SAAU,WACV,OAAQ,SACR,WAAY,aACZ,GAAI,KACJ,YAAa,OACb,UAAW,WACf,EAuBA,SAAgB,EACZ,EACA,EAAqB,EACb,CAER,OADK,EACE,EAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,IAAM,EADpC,CAEtB"}
1
+ {"version":3,"file":"material-symbols.cjs","names":[],"sources":["../../src/icons/material-symbols.ts"],"sourcesContent":["import type { IconName } from \"./generated/icon-name\";\n\n/**\n * The slug `fromMaterialSymbol` falls back to when a code is unknown.\n *\n * A neutral glyph rather than nothing: a category created in an admin with a\n * code this table has not learned yet still has to draw something, or it opens a\n * hole in the grid and the bug reads as a layout problem instead of a missing\n * mapping.\n *\n * Lucide's `circle-help` is a deprecated alias of this slug. `<Icon>` resolves\n * aliases, so both render — but the bridge emits the canonical name, since a\n * value that gets persisted should not be one lucide has already renamed.\n */\nexport const MATERIAL_SYMBOL_FALLBACK: IconName = \"circle-question-mark\";\n\n/**\n * Material Symbols code → lucide slug, for backends that store `icon_code`.\n *\n * Every Python backend we write stores a category icon as a Material Symbol\n * (`build`, `format_paint`, `electrical_services`) — the vocabulary Flutter,\n * Android and the administrative seeds already speak. The SDK speaks lucide in\n * kebab-case. The two lists do not meet, and the failure is nastier than an\n * empty screen: a handful of codes collide by accident, so roughly one row in\n * ten draws the right icon and the bug reads as \"some icons went missing\".\n *\n * **Still not the full vocabulary.** Material Symbols ships ~3600 names and\n * almost none of them will ever appear in an `icon_code` of ours, so this grows\n * on demand, one hand-written pair at a time — a map generated by name\n * heuristics gets it badly wrong, starting with `build`, which is a wrench in\n * Material Symbols and nothing to do with construction. What is here covers the\n * trades lot it started as plus the vocabulary an administrative panel actually\n * uses: navigation, money, dates, media, and the service categories a seed\n * tends to carry.\n *\n * Every target is checked mechanically against the slug list by\n * `material-symbols.test.ts`, so a pair pointing at a name lucide does not ship\n * — or at one it has since deprecated — fails the suite instead of reaching a\n * grid. What no test can check is whether the *chosen* icon is the right\n * metaphor, which is why pairs go in by hand.\n *\n * **Approximations, deliberate and not one-to-one** (the full list lives in\n * `docs/icons.md`):\n *\n * - `plumbing` → `shower-head`, because lucide has no pipe.\n * - `build`, `handyman` and `hardware` all land on `wrench` — Material Symbols\n * distinguishes the tools, lucide does not.\n * - `pedal_bike`, `two_wheeler` and `delivery_dining` all land on `bike`.\n * - `dentistry` → `face-slightly-smiling`, since lucide ships no tooth.\n * - `iron` → `shirt` and `cleaning_services` → `spray-can`: the activity, not\n * the implement.\n * - `roofing` → `house`, the same glyph as `home`, because lucide has no roof.\n *\n * The identity pairs are here on purpose. Their names happen to match in both\n * vocabularies, so they already render today — leaving them out would send them\n * to {@link MATERIAL_SYMBOL_FALLBACK} and make this bridge a regression for\n * exactly the codes that used to work.\n *\n * @see fromMaterialSymbol — the lookup you normally call.\n */\nexport const materialToLucide: Readonly<Record<string, IconName>> = {\n ac_unit: \"snowflake\",\n account_balance: \"landmark\",\n add: \"plus\",\n balance: \"scale\",\n bar_chart: \"chart-column\",\n battery_full: \"battery-full\",\n bluetooth: \"bluetooth\",\n bolt: \"zap\",\n brush: \"brush\",\n build: \"wrench\",\n cake: \"cake\",\n calculate: \"calculator\",\n campaign: \"megaphone\",\n car_repair: \"car\",\n carpenter: \"hammer\",\n chair: \"armchair\",\n chat: \"message-circle\",\n check: \"check\",\n child_care: \"baby\",\n cleaning_services: \"spray-can\",\n close: \"x\",\n cloud: \"cloud\",\n code: \"code\",\n computer: \"monitor\",\n construction: \"hard-hat\",\n content_cut: \"scissors\",\n credit_card: \"credit-card\",\n dashboard: \"layout-dashboard\",\n delete: \"trash-2\",\n delivery_dining: \"bike\",\n dentistry: \"face-slightly-smiling\",\n description: \"file-text\",\n directions_car: \"car\",\n door_front: \"door-open\",\n download: \"download\",\n edit: \"pencil\",\n electrical_services: \"plug-zap\",\n error: \"circle-x\",\n event: \"calendar\",\n favorite: \"heart\",\n fitness_center: \"dumbbell\",\n flight: \"plane\",\n folder: \"folder\",\n format_paint: \"paint-roller\",\n forum: \"messages-square\",\n gavel: \"gavel\",\n grass: \"sprout\",\n group: \"users\",\n groups: \"users\",\n handyman: \"wrench\",\n hardware: \"wrench\",\n help: \"circle-question-mark\",\n history: \"rotate-ccw-clock\",\n home: \"house\",\n hotel: \"bed-double\",\n image: \"image\",\n info: \"info\",\n iron: \"shirt\",\n key: \"key\",\n kitchen: \"refrigerator\",\n laptop: \"laptop\",\n local_bar: \"wine\",\n local_cafe: \"coffee\",\n local_florist: \"flower\",\n local_gas_station: \"fuel\",\n local_laundry_service: \"washing-machine\",\n local_shipping: \"truck\",\n local_taxi: \"car-taxi-front\",\n location_on: \"map-pin\",\n lock: \"lock\",\n lock_open: \"lock-open\",\n login: \"log-in\",\n logout: \"log-out\",\n mail: \"mail\",\n map: \"map\",\n medical_services: \"stethoscope\",\n menu: \"menu\",\n mic: \"mic\",\n music_note: \"music\",\n notifications: \"bell\",\n palette: \"palette\",\n payments: \"banknote\",\n pedal_bike: \"bike\",\n person: \"user\",\n pest_control: \"bug\",\n pets: \"paw-print\",\n phone: \"phone\",\n phone_iphone: \"smartphone\",\n photo_camera: \"camera\",\n pie_chart: \"chart-pie\",\n plumbing: \"shower-head\",\n print: \"printer\",\n receipt_long: \"receipt\",\n restaurant: \"utensils\",\n roofing: \"house\",\n router: \"router\",\n savings: \"piggy-bank\",\n schedule: \"clock\",\n school: \"graduation-cap\",\n search: \"search\",\n security: \"shield-check\",\n settings: \"settings\",\n share: \"share-2\",\n shield: \"shield\",\n shopping_bag: \"shopping-bag\",\n shopping_cart: \"shopping-cart\",\n smartphone: \"smartphone\",\n soap: \"soap-dispenser-droplet\",\n spa: \"flower-2\",\n star: \"star\",\n store: \"store\",\n storefront: \"store\",\n support_agent: \"headset\",\n sync: \"refresh-cw\",\n today: \"calendar-days\",\n translate: \"languages\",\n trending_up: \"trending-up\",\n tv: \"tv\",\n two_wheeler: \"bike\",\n upload: \"upload\",\n vaccines: \"syringe\",\n verified: \"badge-check\",\n videocam: \"video\",\n visibility: \"eye\",\n warehouse: \"warehouse\",\n warning: \"triangle-alert\",\n water_drop: \"droplet\",\n wifi: \"wifi\",\n work: \"briefcase\",\n yard: \"trees\",\n};\n\n/**\n * Translate a Material Symbols code into a lucide slug, always returning one.\n *\n * Never returns `undefined`: an unknown code resolves to `fallback`, so a row\n * whose `icon_code` this table has not learned yet still renders. The input is\n * trimmed and lower-cased before lookup, because a seed written by hand is the\n * kind of source that carries stray whitespace and the odd capital.\n *\n * Nothing else in `/icons` imports this module, so an app that does not store\n * Material Symbols never pays for the table.\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code)} size={20} />\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code, \"folder\")} size={20} />\n *\n * @param code - A Material Symbols name, or `null`/`undefined` for a row that has none.\n * @param fallback - Slug to use when `code` is empty or unknown. Defaults to {@link MATERIAL_SYMBOL_FALLBACK}.\n * @returns A lucide slug `<Icon>` can render.\n */\nexport function fromMaterialSymbol(\n code: string | null | undefined,\n fallback: IconName = MATERIAL_SYMBOL_FALLBACK,\n): IconName {\n if (!code) return fallback;\n return materialToLucide[code.trim().toLowerCase()] ?? fallback;\n}\n"],"mappings":"AAcA,IAAa,EAAqC,uBA8CrC,EAAuD,CAChE,QAAS,YACT,gBAAiB,WACjB,IAAK,OACL,QAAS,QACT,UAAW,eACX,aAAc,eACd,UAAW,YACX,KAAM,MACN,MAAO,QACP,MAAO,SACP,KAAM,OACN,UAAW,aACX,SAAU,YACV,WAAY,MACZ,UAAW,SACX,MAAO,WACP,KAAM,iBACN,MAAO,QACP,WAAY,OACZ,kBAAmB,YACnB,MAAO,IACP,MAAO,QACP,KAAM,OACN,SAAU,UACV,aAAc,WACd,YAAa,WACb,YAAa,cACb,UAAW,mBACX,OAAQ,UACR,gBAAiB,OACjB,UAAW,wBACX,YAAa,YACb,eAAgB,MAChB,WAAY,YACZ,SAAU,WACV,KAAM,SACN,oBAAqB,WACrB,MAAO,WACP,MAAO,WACP,SAAU,QACV,eAAgB,WAChB,OAAQ,QACR,OAAQ,SACR,aAAc,eACd,MAAO,kBACP,MAAO,QACP,MAAO,SACP,MAAO,QACP,OAAQ,QACR,SAAU,SACV,SAAU,SACV,KAAM,uBACN,QAAS,mBACT,KAAM,QACN,MAAO,aACP,MAAO,QACP,KAAM,OACN,KAAM,QACN,IAAK,MACL,QAAS,eACT,OAAQ,SACR,UAAW,OACX,WAAY,SACZ,cAAe,SACf,kBAAmB,OACnB,sBAAuB,kBACvB,eAAgB,QAChB,WAAY,iBACZ,YAAa,UACb,KAAM,OACN,UAAW,YACX,MAAO,SACP,OAAQ,UACR,KAAM,OACN,IAAK,MACL,iBAAkB,cAClB,KAAM,OACN,IAAK,MACL,WAAY,QACZ,cAAe,OACf,QAAS,UACT,SAAU,WACV,WAAY,OACZ,OAAQ,OACR,aAAc,MACd,KAAM,YACN,MAAO,QACP,aAAc,aACd,aAAc,SACd,UAAW,YACX,SAAU,cACV,MAAO,UACP,aAAc,UACd,WAAY,WACZ,QAAS,QACT,OAAQ,SACR,QAAS,aACT,SAAU,QACV,OAAQ,iBACR,OAAQ,SACR,SAAU,eACV,SAAU,WACV,MAAO,UACP,OAAQ,SACR,aAAc,eACd,cAAe,gBACf,WAAY,aACZ,KAAM,yBACN,IAAK,WACL,KAAM,OACN,MAAO,QACP,WAAY,QACZ,cAAe,UACf,KAAM,aACN,MAAO,gBACP,UAAW,YACX,YAAa,cACb,GAAI,KACJ,YAAa,OACb,OAAQ,SACR,SAAU,UACV,SAAU,cACV,SAAU,QACV,WAAY,MACZ,UAAW,YACX,QAAS,iBACT,WAAY,UACZ,KAAM,OACN,KAAM,YACN,KAAM,OACV,EAuBA,SAAgB,EACZ,EACA,EAAqB,EACb,CAER,OADK,EACE,EAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,IAAM,EADpC,CAEtB"}
@@ -1,27 +1,135 @@
1
1
  //#region src/icons/material-symbols.ts
2
2
  var e = "circle-question-mark", t = {
3
+ ac_unit: "snowflake",
4
+ account_balance: "landmark",
5
+ add: "plus",
6
+ balance: "scale",
7
+ bar_chart: "chart-column",
8
+ battery_full: "battery-full",
9
+ bluetooth: "bluetooth",
10
+ bolt: "zap",
3
11
  brush: "brush",
4
12
  build: "wrench",
13
+ cake: "cake",
14
+ calculate: "calculator",
15
+ campaign: "megaphone",
16
+ car_repair: "car",
17
+ carpenter: "hammer",
18
+ chair: "armchair",
19
+ chat: "message-circle",
20
+ check: "check",
21
+ child_care: "baby",
22
+ cleaning_services: "spray-can",
23
+ close: "x",
24
+ cloud: "cloud",
5
25
  code: "code",
26
+ computer: "monitor",
27
+ construction: "hard-hat",
28
+ content_cut: "scissors",
29
+ credit_card: "credit-card",
30
+ dashboard: "layout-dashboard",
31
+ delete: "trash-2",
6
32
  delivery_dining: "bike",
33
+ dentistry: "face-slightly-smiling",
34
+ description: "file-text",
35
+ directions_car: "car",
36
+ door_front: "door-open",
37
+ download: "download",
38
+ edit: "pencil",
7
39
  electrical_services: "plug-zap",
40
+ error: "circle-x",
41
+ event: "calendar",
42
+ favorite: "heart",
43
+ fitness_center: "dumbbell",
44
+ flight: "plane",
45
+ folder: "folder",
8
46
  format_paint: "paint-roller",
47
+ forum: "messages-square",
9
48
  gavel: "gavel",
49
+ grass: "sprout",
50
+ group: "users",
51
+ groups: "users",
10
52
  handyman: "wrench",
11
53
  hardware: "wrench",
54
+ help: "circle-question-mark",
55
+ history: "rotate-ccw-clock",
56
+ home: "house",
57
+ hotel: "bed-double",
58
+ image: "image",
59
+ info: "info",
60
+ iron: "shirt",
12
61
  key: "key",
62
+ kitchen: "refrigerator",
63
+ laptop: "laptop",
64
+ local_bar: "wine",
65
+ local_cafe: "coffee",
66
+ local_florist: "flower",
67
+ local_gas_station: "fuel",
68
+ local_laundry_service: "washing-machine",
69
+ local_shipping: "truck",
70
+ local_taxi: "car-taxi-front",
71
+ location_on: "map-pin",
13
72
  lock: "lock",
73
+ lock_open: "lock-open",
74
+ login: "log-in",
75
+ logout: "log-out",
76
+ mail: "mail",
77
+ map: "map",
78
+ medical_services: "stethoscope",
79
+ menu: "menu",
14
80
  mic: "mic",
81
+ music_note: "music",
82
+ notifications: "bell",
15
83
  palette: "palette",
84
+ payments: "banknote",
16
85
  pedal_bike: "bike",
86
+ person: "user",
87
+ pest_control: "bug",
88
+ pets: "paw-print",
89
+ phone: "phone",
90
+ phone_iphone: "smartphone",
91
+ photo_camera: "camera",
92
+ pie_chart: "chart-pie",
17
93
  plumbing: "shower-head",
94
+ print: "printer",
95
+ receipt_long: "receipt",
96
+ restaurant: "utensils",
97
+ roofing: "house",
18
98
  router: "router",
99
+ savings: "piggy-bank",
100
+ schedule: "clock",
101
+ school: "graduation-cap",
102
+ search: "search",
103
+ security: "shield-check",
19
104
  settings: "settings",
105
+ share: "share-2",
20
106
  shield: "shield",
107
+ shopping_bag: "shopping-bag",
108
+ shopping_cart: "shopping-cart",
21
109
  smartphone: "smartphone",
110
+ soap: "soap-dispenser-droplet",
111
+ spa: "flower-2",
112
+ star: "star",
113
+ store: "store",
114
+ storefront: "store",
115
+ support_agent: "headset",
116
+ sync: "refresh-cw",
117
+ today: "calendar-days",
118
+ translate: "languages",
119
+ trending_up: "trending-up",
22
120
  tv: "tv",
23
121
  two_wheeler: "bike",
24
- warehouse: "warehouse"
122
+ upload: "upload",
123
+ vaccines: "syringe",
124
+ verified: "badge-check",
125
+ videocam: "video",
126
+ visibility: "eye",
127
+ warehouse: "warehouse",
128
+ warning: "triangle-alert",
129
+ water_drop: "droplet",
130
+ wifi: "wifi",
131
+ work: "briefcase",
132
+ yard: "trees"
25
133
  };
26
134
  function n(n, r = e) {
27
135
  return n ? t[n.trim().toLowerCase()] ?? r : r;
@@ -1 +1 @@
1
- {"version":3,"file":"material-symbols.js","names":[],"sources":["../../src/icons/material-symbols.ts"],"sourcesContent":["import type { IconName } from \"./generated/icon-name\";\n\n/**\n * The slug `fromMaterialSymbol` falls back to when a code is unknown.\n *\n * A neutral glyph rather than nothing: a category created in an admin with a\n * code this table has not learned yet still has to draw something, or it opens a\n * hole in the grid and the bug reads as a layout problem instead of a missing\n * mapping.\n *\n * Lucide's `circle-help` is a deprecated alias of this slug. `<Icon>` resolves\n * aliases, so both render — but the bridge emits the canonical name, since a\n * value that gets persisted should not be one lucide has already renamed.\n */\nexport const MATERIAL_SYMBOL_FALLBACK: IconName = \"circle-question-mark\";\n\n/**\n * Material Symbols code → lucide slug, for backends that store `icon_code`.\n *\n * Every Python backend we write stores a category icon as a Material Symbol\n * (`build`, `format_paint`, `electrical_services`) — the vocabulary Flutter,\n * Android and the administrative seeds already speak. The SDK speaks lucide in\n * kebab-case. The two lists do not meet, and the failure is nastier than an\n * empty screen: a handful of codes collide by accident, so roughly one row in\n * ten draws the right icon and the bug reads as \"some icons went missing\".\n *\n * **This is a seed table, not the full vocabulary.** Material Symbols ships\n * ~3600 names and almost none of them will ever appear in an `icon_code` of\n * ours. It grows on demand, one hand-written pair at a time — a map generated by\n * name heuristics gets it badly wrong, starting with `build`, which is a wrench\n * in Material Symbols and not anything to do with construction.\n *\n * **Approximations, deliberate and not one-to-one:**\n *\n * - `plumbing` → `shower-head`, because lucide has no pipe.\n * - `build`, `handyman` and `hardware` all land on `wrench` — Material Symbols\n * distinguishes the tools, lucide does not.\n * - `pedal_bike`, `two_wheeler` and `delivery_dining` all land on `bike`.\n *\n * The thirteen identity pairs are here on purpose. Their names happen to match\n * in both vocabularies, so they already render today — leaving them out would\n * send them to {@link MATERIAL_SYMBOL_FALLBACK} and make this bridge a\n * regression for exactly the codes that used to work.\n *\n * @see fromMaterialSymbol — the lookup you normally call.\n */\nexport const materialToLucide: Readonly<Record<string, IconName>> = {\n brush: \"brush\",\n build: \"wrench\",\n code: \"code\",\n delivery_dining: \"bike\",\n electrical_services: \"plug-zap\",\n format_paint: \"paint-roller\",\n gavel: \"gavel\",\n handyman: \"wrench\",\n hardware: \"wrench\",\n key: \"key\",\n lock: \"lock\",\n mic: \"mic\",\n palette: \"palette\",\n pedal_bike: \"bike\",\n plumbing: \"shower-head\",\n router: \"router\",\n settings: \"settings\",\n shield: \"shield\",\n smartphone: \"smartphone\",\n tv: \"tv\",\n two_wheeler: \"bike\",\n warehouse: \"warehouse\",\n};\n\n/**\n * Translate a Material Symbols code into a lucide slug, always returning one.\n *\n * Never returns `undefined`: an unknown code resolves to `fallback`, so a row\n * whose `icon_code` this table has not learned yet still renders. The input is\n * trimmed and lower-cased before lookup, because a seed written by hand is the\n * kind of source that carries stray whitespace and the odd capital.\n *\n * Nothing else in `/icons` imports this module, so an app that does not store\n * Material Symbols never pays for the table.\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code)} size={20} />\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code, \"folder\")} size={20} />\n *\n * @param code - A Material Symbols name, or `null`/`undefined` for a row that has none.\n * @param fallback - Slug to use when `code` is empty or unknown. Defaults to {@link MATERIAL_SYMBOL_FALLBACK}.\n * @returns A lucide slug `<Icon>` can render.\n */\nexport function fromMaterialSymbol(\n code: string | null | undefined,\n fallback: IconName = MATERIAL_SYMBOL_FALLBACK,\n): IconName {\n if (!code) return fallback;\n return materialToLucide[code.trim().toLowerCase()] ?? fallback;\n}\n"],"mappings":";AAcA,IAAa,IAAqC,wBAgCrC,IAAuD;CAChE,OAAO;CACP,OAAO;CACP,MAAM;CACN,iBAAiB;CACjB,qBAAqB;CACrB,cAAc;CACd,OAAO;CACP,UAAU;CACV,UAAU;CACV,KAAK;CACL,MAAM;CACN,KAAK;CACL,SAAS;CACT,YAAY;CACZ,UAAU;CACV,QAAQ;CACR,UAAU;CACV,QAAQ;CACR,YAAY;CACZ,IAAI;CACJ,aAAa;CACb,WAAW;AACf;AAuBA,SAAgB,EACZ,GACA,IAAqB,GACb;CAER,OADK,IACE,EAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,MAAM,IADpC;AAEtB"}
1
+ {"version":3,"file":"material-symbols.js","names":[],"sources":["../../src/icons/material-symbols.ts"],"sourcesContent":["import type { IconName } from \"./generated/icon-name\";\n\n/**\n * The slug `fromMaterialSymbol` falls back to when a code is unknown.\n *\n * A neutral glyph rather than nothing: a category created in an admin with a\n * code this table has not learned yet still has to draw something, or it opens a\n * hole in the grid and the bug reads as a layout problem instead of a missing\n * mapping.\n *\n * Lucide's `circle-help` is a deprecated alias of this slug. `<Icon>` resolves\n * aliases, so both render — but the bridge emits the canonical name, since a\n * value that gets persisted should not be one lucide has already renamed.\n */\nexport const MATERIAL_SYMBOL_FALLBACK: IconName = \"circle-question-mark\";\n\n/**\n * Material Symbols code → lucide slug, for backends that store `icon_code`.\n *\n * Every Python backend we write stores a category icon as a Material Symbol\n * (`build`, `format_paint`, `electrical_services`) — the vocabulary Flutter,\n * Android and the administrative seeds already speak. The SDK speaks lucide in\n * kebab-case. The two lists do not meet, and the failure is nastier than an\n * empty screen: a handful of codes collide by accident, so roughly one row in\n * ten draws the right icon and the bug reads as \"some icons went missing\".\n *\n * **Still not the full vocabulary.** Material Symbols ships ~3600 names and\n * almost none of them will ever appear in an `icon_code` of ours, so this grows\n * on demand, one hand-written pair at a time — a map generated by name\n * heuristics gets it badly wrong, starting with `build`, which is a wrench in\n * Material Symbols and nothing to do with construction. What is here covers the\n * trades lot it started as plus the vocabulary an administrative panel actually\n * uses: navigation, money, dates, media, and the service categories a seed\n * tends to carry.\n *\n * Every target is checked mechanically against the slug list by\n * `material-symbols.test.ts`, so a pair pointing at a name lucide does not ship\n * — or at one it has since deprecated — fails the suite instead of reaching a\n * grid. What no test can check is whether the *chosen* icon is the right\n * metaphor, which is why pairs go in by hand.\n *\n * **Approximations, deliberate and not one-to-one** (the full list lives in\n * `docs/icons.md`):\n *\n * - `plumbing` → `shower-head`, because lucide has no pipe.\n * - `build`, `handyman` and `hardware` all land on `wrench` — Material Symbols\n * distinguishes the tools, lucide does not.\n * - `pedal_bike`, `two_wheeler` and `delivery_dining` all land on `bike`.\n * - `dentistry` → `face-slightly-smiling`, since lucide ships no tooth.\n * - `iron` → `shirt` and `cleaning_services` → `spray-can`: the activity, not\n * the implement.\n * - `roofing` → `house`, the same glyph as `home`, because lucide has no roof.\n *\n * The identity pairs are here on purpose. Their names happen to match in both\n * vocabularies, so they already render today — leaving them out would send them\n * to {@link MATERIAL_SYMBOL_FALLBACK} and make this bridge a regression for\n * exactly the codes that used to work.\n *\n * @see fromMaterialSymbol — the lookup you normally call.\n */\nexport const materialToLucide: Readonly<Record<string, IconName>> = {\n ac_unit: \"snowflake\",\n account_balance: \"landmark\",\n add: \"plus\",\n balance: \"scale\",\n bar_chart: \"chart-column\",\n battery_full: \"battery-full\",\n bluetooth: \"bluetooth\",\n bolt: \"zap\",\n brush: \"brush\",\n build: \"wrench\",\n cake: \"cake\",\n calculate: \"calculator\",\n campaign: \"megaphone\",\n car_repair: \"car\",\n carpenter: \"hammer\",\n chair: \"armchair\",\n chat: \"message-circle\",\n check: \"check\",\n child_care: \"baby\",\n cleaning_services: \"spray-can\",\n close: \"x\",\n cloud: \"cloud\",\n code: \"code\",\n computer: \"monitor\",\n construction: \"hard-hat\",\n content_cut: \"scissors\",\n credit_card: \"credit-card\",\n dashboard: \"layout-dashboard\",\n delete: \"trash-2\",\n delivery_dining: \"bike\",\n dentistry: \"face-slightly-smiling\",\n description: \"file-text\",\n directions_car: \"car\",\n door_front: \"door-open\",\n download: \"download\",\n edit: \"pencil\",\n electrical_services: \"plug-zap\",\n error: \"circle-x\",\n event: \"calendar\",\n favorite: \"heart\",\n fitness_center: \"dumbbell\",\n flight: \"plane\",\n folder: \"folder\",\n format_paint: \"paint-roller\",\n forum: \"messages-square\",\n gavel: \"gavel\",\n grass: \"sprout\",\n group: \"users\",\n groups: \"users\",\n handyman: \"wrench\",\n hardware: \"wrench\",\n help: \"circle-question-mark\",\n history: \"rotate-ccw-clock\",\n home: \"house\",\n hotel: \"bed-double\",\n image: \"image\",\n info: \"info\",\n iron: \"shirt\",\n key: \"key\",\n kitchen: \"refrigerator\",\n laptop: \"laptop\",\n local_bar: \"wine\",\n local_cafe: \"coffee\",\n local_florist: \"flower\",\n local_gas_station: \"fuel\",\n local_laundry_service: \"washing-machine\",\n local_shipping: \"truck\",\n local_taxi: \"car-taxi-front\",\n location_on: \"map-pin\",\n lock: \"lock\",\n lock_open: \"lock-open\",\n login: \"log-in\",\n logout: \"log-out\",\n mail: \"mail\",\n map: \"map\",\n medical_services: \"stethoscope\",\n menu: \"menu\",\n mic: \"mic\",\n music_note: \"music\",\n notifications: \"bell\",\n palette: \"palette\",\n payments: \"banknote\",\n pedal_bike: \"bike\",\n person: \"user\",\n pest_control: \"bug\",\n pets: \"paw-print\",\n phone: \"phone\",\n phone_iphone: \"smartphone\",\n photo_camera: \"camera\",\n pie_chart: \"chart-pie\",\n plumbing: \"shower-head\",\n print: \"printer\",\n receipt_long: \"receipt\",\n restaurant: \"utensils\",\n roofing: \"house\",\n router: \"router\",\n savings: \"piggy-bank\",\n schedule: \"clock\",\n school: \"graduation-cap\",\n search: \"search\",\n security: \"shield-check\",\n settings: \"settings\",\n share: \"share-2\",\n shield: \"shield\",\n shopping_bag: \"shopping-bag\",\n shopping_cart: \"shopping-cart\",\n smartphone: \"smartphone\",\n soap: \"soap-dispenser-droplet\",\n spa: \"flower-2\",\n star: \"star\",\n store: \"store\",\n storefront: \"store\",\n support_agent: \"headset\",\n sync: \"refresh-cw\",\n today: \"calendar-days\",\n translate: \"languages\",\n trending_up: \"trending-up\",\n tv: \"tv\",\n two_wheeler: \"bike\",\n upload: \"upload\",\n vaccines: \"syringe\",\n verified: \"badge-check\",\n videocam: \"video\",\n visibility: \"eye\",\n warehouse: \"warehouse\",\n warning: \"triangle-alert\",\n water_drop: \"droplet\",\n wifi: \"wifi\",\n work: \"briefcase\",\n yard: \"trees\",\n};\n\n/**\n * Translate a Material Symbols code into a lucide slug, always returning one.\n *\n * Never returns `undefined`: an unknown code resolves to `fallback`, so a row\n * whose `icon_code` this table has not learned yet still renders. The input is\n * trimmed and lower-cased before lookup, because a seed written by hand is the\n * kind of source that carries stray whitespace and the odd capital.\n *\n * Nothing else in `/icons` imports this module, so an app that does not store\n * Material Symbols never pays for the table.\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code)} size={20} />\n *\n * @example\n * <Icon name={fromMaterialSymbol(category.icon_code, \"folder\")} size={20} />\n *\n * @param code - A Material Symbols name, or `null`/`undefined` for a row that has none.\n * @param fallback - Slug to use when `code` is empty or unknown. Defaults to {@link MATERIAL_SYMBOL_FALLBACK}.\n * @returns A lucide slug `<Icon>` can render.\n */\nexport function fromMaterialSymbol(\n code: string | null | undefined,\n fallback: IconName = MATERIAL_SYMBOL_FALLBACK,\n): IconName {\n if (!code) return fallback;\n return materialToLucide[code.trim().toLowerCase()] ?? fallback;\n}\n"],"mappings":";AAcA,IAAa,IAAqC,wBA8CrC,IAAuD;CAChE,SAAS;CACT,iBAAiB;CACjB,KAAK;CACL,SAAS;CACT,WAAW;CACX,cAAc;CACd,WAAW;CACX,MAAM;CACN,OAAO;CACP,OAAO;CACP,MAAM;CACN,WAAW;CACX,UAAU;CACV,YAAY;CACZ,WAAW;CACX,OAAO;CACP,MAAM;CACN,OAAO;CACP,YAAY;CACZ,mBAAmB;CACnB,OAAO;CACP,OAAO;CACP,MAAM;CACN,UAAU;CACV,cAAc;CACd,aAAa;CACb,aAAa;CACb,WAAW;CACX,QAAQ;CACR,iBAAiB;CACjB,WAAW;CACX,aAAa;CACb,gBAAgB;CAChB,YAAY;CACZ,UAAU;CACV,MAAM;CACN,qBAAqB;CACrB,OAAO;CACP,OAAO;CACP,UAAU;CACV,gBAAgB;CAChB,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,QAAQ;CACR,UAAU;CACV,UAAU;CACV,MAAM;CACN,SAAS;CACT,MAAM;CACN,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,KAAK;CACL,SAAS;CACT,QAAQ;CACR,WAAW;CACX,YAAY;CACZ,eAAe;CACf,mBAAmB;CACnB,uBAAuB;CACvB,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,MAAM;CACN,WAAW;CACX,OAAO;CACP,QAAQ;CACR,MAAM;CACN,KAAK;CACL,kBAAkB;CAClB,MAAM;CACN,KAAK;CACL,YAAY;CACZ,eAAe;CACf,SAAS;CACT,UAAU;CACV,YAAY;CACZ,QAAQ;CACR,cAAc;CACd,MAAM;CACN,OAAO;CACP,cAAc;CACd,cAAc;CACd,WAAW;CACX,UAAU;CACV,OAAO;CACP,cAAc;CACd,YAAY;CACZ,SAAS;CACT,QAAQ;CACR,SAAS;CACT,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,UAAU;CACV,OAAO;CACP,QAAQ;CACR,cAAc;CACd,eAAe;CACf,YAAY;CACZ,MAAM;CACN,KAAK;CACL,MAAM;CACN,OAAO;CACP,YAAY;CACZ,eAAe;CACf,MAAM;CACN,OAAO;CACP,WAAW;CACX,aAAa;CACb,IAAI;CACJ,aAAa;CACb,QAAQ;CACR,UAAU;CACV,UAAU;CACV,UAAU;CACV,YAAY;CACZ,WAAW;CACX,SAAS;CACT,YAAY;CACZ,MAAM;CACN,MAAM;CACN,MAAM;AACV;AAuBA,SAAgB,EACZ,GACA,IAAqB,GACb;CAER,OADK,IACE,EAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,MAAM,IADpC;AAEtB"}
@@ -0,0 +1,2 @@
1
+ const e=require("./alias.cjs");function t(t){return e.resolveIconAlias(t.trim().toLowerCase().replaceAll(`_`,`-`))}exports.normalizeIconName=t;
2
+ //# sourceMappingURL=normalize-icon-name.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-icon-name.cjs","names":[],"sources":["../../src/icons/normalize-icon-name.ts"],"sourcesContent":["import { resolveIconAlias } from \"./alias\";\n\n/**\n * Clean up an icon code and resolve it to the slug lucide actually ships.\n *\n * Every backend that stores an `icon_code` stores it dirty: `snake_case` left over\n * from an old form, a capital or a stray space from a hand-typed value, and slugs\n * lucide has since deprecated. Each app was writing the same three-step cleanup\n * before rendering — trim, lower-case, `_` → `-`, then `resolveIconAlias` — which\n * is code that should not exist outside the SDK.\n *\n * Note that this does **not** check whether the result is a real icon: the point is\n * to produce the canonical spelling, and deciding what to do with an unknown name\n * belongs to the caller. Pair it with `isIconName` when you need that answer, or\n * let `<Icon>` render its `fallback`.\n *\n * @example\n * normalizeIconName(\" Alert_Circle \"); // \"circle-alert\"\n * normalizeIconName(\"shopping_cart\"); // \"shopping-cart\"\n *\n * @param code - Any stored icon code.\n * @returns The canonical, lucide-spelled slug.\n */\nexport function normalizeIconName(code: string): string {\n return resolveIconAlias(code.trim().toLowerCase().replaceAll(\"_\", \"-\"));\n}\n"],"mappings":"+BAuBA,SAAgB,EAAkB,EAAsB,CACpD,OAAO,EAAA,iBAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,IAAK,GAAG,CAAC,CAC1E"}
@@ -0,0 +1,9 @@
1
+ import { resolveIconAlias as e } from "./alias.js";
2
+ //#region src/icons/normalize-icon-name.ts
3
+ function t(t) {
4
+ return e(t.trim().toLowerCase().replaceAll("_", "-"));
5
+ }
6
+ //#endregion
7
+ export { t as normalizeIconName };
8
+
9
+ //# sourceMappingURL=normalize-icon-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-icon-name.js","names":[],"sources":["../../src/icons/normalize-icon-name.ts"],"sourcesContent":["import { resolveIconAlias } from \"./alias\";\n\n/**\n * Clean up an icon code and resolve it to the slug lucide actually ships.\n *\n * Every backend that stores an `icon_code` stores it dirty: `snake_case` left over\n * from an old form, a capital or a stray space from a hand-typed value, and slugs\n * lucide has since deprecated. Each app was writing the same three-step cleanup\n * before rendering — trim, lower-case, `_` → `-`, then `resolveIconAlias` — which\n * is code that should not exist outside the SDK.\n *\n * Note that this does **not** check whether the result is a real icon: the point is\n * to produce the canonical spelling, and deciding what to do with an unknown name\n * belongs to the caller. Pair it with `isIconName` when you need that answer, or\n * let `<Icon>` render its `fallback`.\n *\n * @example\n * normalizeIconName(\" Alert_Circle \"); // \"circle-alert\"\n * normalizeIconName(\"shopping_cart\"); // \"shopping-cart\"\n *\n * @param code - Any stored icon code.\n * @returns The canonical, lucide-spelled slug.\n */\nexport function normalizeIconName(code: string): string {\n return resolveIconAlias(code.trim().toLowerCase().replaceAll(\"_\", \"-\"));\n}\n"],"mappings":";;AAuBA,SAAgB,EAAkB,GAAsB;CACpD,OAAO,EAAiB,EAAK,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC;AAC1E"}
@@ -1,2 +1,2 @@
1
- const e=require("./generated/aliases.cjs"),t=require("./generated/loaders.cjs");var n=new Map,r=new Map,i=new Set,a=new Set;function o(t){return e.iconAliases[t]??t}function s(e){return n.get(o(e))}function c(e){let s=o(e);if(n.has(s))return Promise.resolve();let c=s[0]??``,l=t.shardLoaders[c];if(!l)return Promise.resolve();let u=r.get(c);if(u)return u;let d=l().then(e=>{for(let[t,r]of Object.entries(e.default))n.set(t,r)}).catch(()=>void 0).finally(()=>{r.delete(c),i.add(c);for(let e of a)e()});return r.set(c,d),d}function l(e){let r=o(e);if(n.has(r))return`ready`;let a=r[0]??``;return t.shardLoaders[a]?i.has(a)?`missing`:`loading`:`missing`}async function u(e){await Promise.all(e.map(c))}function d(e){return a.add(e),()=>a.delete(e)}exports.iconStatus=l,exports.loadIcon=c,exports.peekIcon=s,exports.preloadIcons=u,exports.resolveIconAlias=o,exports.subscribeToIcons=d;
1
+ const e=require("../utils/dev-mode.cjs"),t=require("./alias.cjs"),n=require("./generated/loaders.cjs");var r=new Map,i=new Map;function a(e){if(e===``||e<n.iconShards[0].from)return;let t=0,r=n.iconShards.length-1;for(;t<r;){let i=Math.ceil((t+r)/2);n.iconShards[i].from<=e?t=i:r=i-1}return n.iconShards[t]}var o=new Set,s=new Map,c=[100,400],l=1e4,u=new Set,d=new Set;function f(e){let n=!1;for(let[i,a]of Object.entries(e)){let e=t.resolveIconAlias(i);r.get(e)!==a&&(r.set(e,a),n=!0)}if(n)for(let e of d)e()}function p(e){return r.get(t.resolveIconAlias(e))}function m(e){let n=t.resolveIconAlias(e);if(r.has(n))return Promise.resolve();let o=a(n);if(!o)return Promise.resolve();let c=i.get(o.id);if(c)return c;let u=s.get(o.id);if(u!==void 0&&performance.now()-u<l)return Promise.resolve();let f=h(o,n).finally(()=>{i.delete(o.id);for(let e of d)e()});return i.set(o.id,f),f}async function h(e,t){let n;for(let t=0;t<=c.length;t+=1)try{let t=await e.load();for(let[e,n]of Object.entries(t.default))r.set(e,n);o.add(e.id),s.delete(e.id);return}catch(e){n=e;let r=c[t];if(r===void 0)break;await g(r)}s.set(e.id,performance.now()),_({shard:e.id,slug:t,attempts:c.length+1,error:n})}function g(e){return new Promise(t=>setTimeout(t,e))}function _(t){if(u.size===0){e.isDevBuild()&&y(t);return}for(let e of u)e(t)}var v=new Set;function y({shard:e,slug:t,attempts:n}){v.has(e)||(v.add(e),console.warn(`[tempest-react-sdk] icon shard "${e}" failed to load after ${n} attempts (first asked for by "${t}"). The usual cause is a deploy that rotated hashed chunk names while this tab was open. Subscribe with \`subscribeToIconErrors\` to report it and reload.`))}function b(e){return u.add(e),()=>u.delete(e)}function x(e){let n=t.resolveIconAlias(e);if(r.has(n))return`ready`;let i=a(n);return!i||o.has(i.id)?`missing`:s.has(i.id)?`error`:`loading`}async function S(e){await Promise.all(e.map(m))}function C(e){return d.add(e),()=>d.delete(e)}exports.iconStatus=x,exports.loadIcon=m,exports.peekIcon=p,exports.preloadIcons=S,exports.registerIcons=f,exports.subscribeToIconErrors=b,exports.subscribeToIcons=C;
2
2
  //# sourceMappingURL=shard-cache.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"shard-cache.cjs","names":[],"sources":["../../src/icons/shard-cache.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\n\nimport { iconAliases } from \"./generated/aliases\";\nimport { shardLoaders } from \"./generated/loaders\";\n\n/**\n * Slugs resolved so far, across every shard already fetched.\n *\n * Module-level and readable **synchronously**, which is the whole point: once a\n * page has rendered one icon whose slug starts with `s`, every other `s` icon is\n * already in memory and paints on its first frame. A cache that could only be\n * read from an effect would flash a fallback for each new icon, which is the\n * behavior `lucide-react`'s own `DynamicIcon` has.\n */\nconst resolved = new Map<string, LucideIcon>();\n\n/** In-flight shard fetches, so N icons from one shard trigger one import. */\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * Initial letters whose shard has already settled.\n *\n * Needed to tell \"still loading\" from \"no such icon\": until the shard arrives,\n * absence from `resolved` proves nothing. Only once the letter is in here does a\n * missing slug mean the name is genuinely wrong — which is what lets `Icon` warn\n * about a typo without also warning on every icon mid-flight.\n */\nconst settledLetters = new Set<string>();\n\n/** Callbacks to run after a shard lands, so mounted `<Icon>`s re-render. */\nconst listeners = new Set<() => void>();\n\n/**\n * Map a slug to the canonical slug that owns the icon.\n *\n * Lucide keeps 257 deprecated aliases (`alert-circle` → `circle-alert`), and a\n * slug persisted in a database years ago is exactly the case this feature exists\n * for, so an alias must keep resolving after a lucide bump renames it.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The canonical slug.\n */\nexport function resolveIconAlias(slug: string): string {\n return iconAliases[slug] ?? slug;\n}\n\n/**\n * Read an icon out of the cache without triggering a fetch.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The icon component, or `undefined` when its shard is not loaded yet.\n */\nexport function peekIcon(slug: string): LucideIcon | undefined {\n return resolved.get(resolveIconAlias(slug));\n}\n\n/**\n * Load the shard that owns `slug`, if it is not loaded or loading already.\n *\n * Resolves without error for an unknown slug: a name that came from an API is\n * data, not a programming mistake, so the caller renders its fallback instead of\n * seeing an exception thrown mid-render.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns A promise that settles once the shard is in the cache.\n */\nexport function loadIcon(slug: string): Promise<void> {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return Promise.resolve();\n\n const letter = canonical[0] ?? \"\";\n const loader = shardLoaders[letter];\n if (!loader) return Promise.resolve();\n\n const pending = inFlight.get(letter);\n if (pending) return pending;\n\n const promise = loader()\n .then((mod) => {\n for (const [name, icon] of Object.entries(mod.default)) resolved.set(name, icon);\n })\n .catch(() => undefined)\n .finally(() => {\n inFlight.delete(letter);\n settledLetters.add(letter);\n for (const listener of listeners) listener();\n });\n inFlight.set(letter, promise);\n return promise;\n}\n\n/**\n * Whether a slug is ready, still loading, or not an icon at all.\n *\n * `\"missing\"` is only reported once that is actually knowable: either lucide has\n * no icons under that initial letter, or the letter's shard already settled\n * without the slug in it.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The slug's resolution state.\n */\nexport function iconStatus(slug: string): \"ready\" | \"loading\" | \"missing\" {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return \"ready\";\n const letter = canonical[0] ?? \"\";\n if (!shardLoaders[letter]) return \"missing\";\n return settledLetters.has(letter) ? \"missing\" : \"loading\";\n}\n\n/**\n * Warm the cache for slugs you know you are about to render.\n *\n * Useful right before opening a menu or a picker: the shards land while the user\n * is still reaching for it, so nothing flashes a fallback.\n *\n * @param slugs - Icon slugs to preload.\n * @returns A promise that settles when every needed shard is in the cache.\n */\nexport async function preloadIcons(slugs: readonly string[]): Promise<void> {\n await Promise.all(slugs.map(loadIcon));\n}\n\n/**\n * Subscribe to shard arrivals.\n *\n * @param listener - Called after each shard lands.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIcons(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n"],"mappings":"gFAcA,IAAM,EAAW,IAAI,IAGf,EAAW,IAAI,IAUf,EAAiB,IAAI,IAGrB,EAAY,IAAI,IAYtB,SAAgB,EAAiB,EAAsB,CACnD,OAAO,EAAA,YAAY,IAAS,CAChC,CAQA,SAAgB,EAAS,EAAsC,CAC3D,OAAO,EAAS,IAAI,EAAiB,CAAI,CAAC,CAC9C,CAYA,SAAgB,EAAS,EAA6B,CAClD,IAAM,EAAY,EAAiB,CAAI,EACvC,GAAI,EAAS,IAAI,CAAS,EAAG,OAAO,QAAQ,QAAQ,EAEpD,IAAM,EAAS,EAAU,IAAM,GACzB,EAAS,EAAA,aAAa,GAC5B,GAAI,CAAC,EAAQ,OAAO,QAAQ,QAAQ,EAEpC,IAAM,EAAU,EAAS,IAAI,CAAM,EACnC,GAAI,EAAS,OAAO,EAEpB,IAAM,EAAU,EAAO,CAAC,CACnB,KAAM,GAAQ,CACX,IAAK,GAAM,CAAC,EAAM,KAAS,OAAO,QAAQ,EAAI,OAAO,EAAG,EAAS,IAAI,EAAM,CAAI,CACnF,CAAC,CAAC,CACD,UAAY,IAAA,EAAS,CAAC,CACtB,YAAc,CACX,EAAS,OAAO,CAAM,EACtB,EAAe,IAAI,CAAM,EACzB,IAAK,IAAM,KAAY,EAAW,EAAS,CAC/C,CAAC,EAEL,OADA,EAAS,IAAI,EAAQ,CAAO,EACrB,CACX,CAYA,SAAgB,EAAW,EAA+C,CACtE,IAAM,EAAY,EAAiB,CAAI,EACvC,GAAI,EAAS,IAAI,CAAS,EAAG,MAAO,QACpC,IAAM,EAAS,EAAU,IAAM,GAE/B,OADK,EAAA,aAAa,GACX,EAAe,IAAI,CAAM,EAAI,UAAY,UADd,SAEtC,CAWA,eAAsB,EAAa,EAAyC,CACxE,MAAM,QAAQ,IAAI,EAAM,IAAI,CAAQ,CAAC,CACzC,CAQA,SAAgB,EAAiB,EAAkC,CAE/D,OADA,EAAU,IAAI,CAAQ,MACT,EAAU,OAAO,CAAQ,CAC1C"}
1
+ {"version":3,"file":"shard-cache.cjs","names":[],"sources":["../../src/icons/shard-cache.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\n\nimport { isDevBuild } from \"../utils/dev-mode\";\nimport { resolveIconAlias } from \"./alias\";\nimport { iconShards, type IconShard } from \"./generated/loaders\";\n\n/**\n * Slugs resolved so far, across every shard already fetched.\n *\n * Module-level and readable **synchronously**, which is the whole point: once a\n * page has rendered one icon, every other icon in that shard's range is already in\n * memory and paints on its first frame. A cache that could only be read from an\n * effect would flash a fallback for each new icon, which is the behavior\n * `lucide-react`'s own `DynamicIcon` has.\n */\nconst resolved = new Map<string, LucideIcon>();\n\n/** In-flight shard fetches, so N icons from one shard trigger one import. */\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * Find the shard that owns a slug.\n *\n * The shards are contiguous, sorted ranges, so this is a binary search over their\n * lower bounds — 45 entries in the index rather than the 2000-entry slug→chunk map\n * that costs 120 KB in a main chunk.\n *\n * A slug sorting before the first range belongs to no shard, which is knowable\n * without any fetch: `\"0-not-an-icon\"` cannot be a lucide name.\n *\n * @param canonical - A canonical slug, aliases already resolved.\n * @returns The owning shard, or `undefined` when no range can hold it.\n */\nfunction shardFor(canonical: string): IconShard | undefined {\n if (canonical === \"\" || canonical < iconShards[0].from) return undefined;\n\n let low = 0;\n let high = iconShards.length - 1;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n if (iconShards[mid].from <= canonical) low = mid;\n else high = mid - 1;\n }\n return iconShards[low];\n}\n\n/**\n * Shard ids whose chunk actually arrived.\n *\n * Needed to tell \"still loading\" from \"no such icon\": until the shard arrives,\n * absence from `resolved` proves nothing. Only once the shard is in here does a\n * missing slug mean the name is genuinely wrong — which is what lets `Icon` warn\n * about a typo without also warning on every icon mid-flight.\n *\n * A shard that *failed* deliberately does not land here. Collapsing \"the chunk\n * 404'd\" into \"no such icon\" is what made a stale deploy look like a typo.\n */\nconst loadedShards = new Set<string>();\n\n/**\n * Shards whose fetch gave up, and when.\n *\n * The timestamp is what stops a permanent fallback: `useIcon` re-runs its effect\n * on every miss, so a shard is retried on a later render — after a cooldown, so a\n * chunk that is genuinely gone cannot turn into a request loop.\n */\nconst failedShards = new Map<string, number>();\n\n/**\n * Backoff before each retry, in milliseconds.\n *\n * Two retries, both fast, because the failure this exists for is a transient one:\n * a flaky connection, or a chunk whose CDN edge has not caught up. A 404 from a\n * deploy that rotated hashed filenames is *not* fixed by retrying — for that, the\n * error subscription is the signal, and the app reloads.\n */\nconst RETRY_DELAYS = [100, 400] as const;\n\n/** How long a failed shard is left alone before another render may retry it. */\nconst RETRY_COOLDOWN_MS = 10_000;\n\n/** What a shard failure reports to whoever subscribed. */\nexport interface IconLoadError {\n /** The shard key whose chunk could not be fetched. */\n shard: string;\n /** The slug whose render asked for it. */\n slug: string;\n /** Attempts made before giving up, retries included. */\n attempts: number;\n /** The last rejection from the dynamic import. */\n error: unknown;\n}\n\n/** Callbacks to run when a shard fetch gives up. */\nconst errorListeners = new Set<(detail: IconLoadError) => void>();\n\n/** Callbacks to run after a shard lands, so mounted `<Icon>`s re-render. */\nconst listeners = new Set<() => void>();\n\n/**\n * Make icon components resolvable by slug, with no provider and no plugin.\n *\n * Call it once from an entrypoint. The icons land in the same table a fetched\n * shard fills, so every `<Icon>` below — including one that renders before the\n * call, since registering notifies subscribers — resolves them synchronously and\n * never issues a request.\n *\n * This is the whole setup for a closed catalog: an admin panel with twenty known\n * icons pays two lines instead of a build plugin plus a provider. `IconProvider`\n * stays for what is genuinely tree-scoped — the `size`/`strokeWidth` defaults and\n * a registry that must override the global one for one subtree.\n *\n * A slug lucide does not ship is registered as-is, which is how an app adds its\n * own artwork to the same `<Icon name>` call site.\n *\n * @example\n * import { registerIcons } from \"tempest-react-sdk/icons\";\n * import { Save, Trash2 } from \"lucide-react\";\n *\n * registerIcons({ save: Save, \"trash-2\": Trash2 });\n *\n * @param icons - Slug → icon component. Deprecated slugs are stored under the\n * canonical name, so both spellings resolve.\n */\nexport function registerIcons(icons: Readonly<Record<string, LucideIcon>>): void {\n let changed = false;\n for (const [slug, icon] of Object.entries(icons)) {\n const canonical = resolveIconAlias(slug);\n if (resolved.get(canonical) === icon) continue;\n resolved.set(canonical, icon);\n changed = true;\n }\n if (!changed) return;\n for (const listener of listeners) listener();\n}\n\n/**\n * Read an icon out of the cache without triggering a fetch.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The icon component, or `undefined` when its shard is not loaded yet.\n */\nexport function peekIcon(slug: string): LucideIcon | undefined {\n return resolved.get(resolveIconAlias(slug));\n}\n\n/**\n * Load the shard that owns `slug`, if it is not loaded or loading already.\n *\n * Resolves without error for an unknown slug: a name that came from an API is\n * data, not a programming mistake, so the caller renders its fallback instead of\n * seeing an exception thrown mid-render.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns A promise that settles once the shard is in the cache.\n */\nexport function loadIcon(slug: string): Promise<void> {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return Promise.resolve();\n\n const shard = shardFor(canonical);\n if (!shard) return Promise.resolve();\n\n const pending = inFlight.get(shard.id);\n if (pending) return pending;\n\n const failedAt = failedShards.get(shard.id);\n if (failedAt !== undefined && performance.now() - failedAt < RETRY_COOLDOWN_MS) {\n return Promise.resolve();\n }\n\n const promise = fetchShard(shard, canonical).finally(() => {\n inFlight.delete(shard.id);\n for (const listener of listeners) listener();\n });\n inFlight.set(shard.id, promise);\n return promise;\n}\n\n/**\n * Fetch one shard, retrying a couple of times before giving up.\n *\n * Never rejects: an icon whose chunk did not arrive is a rendering outcome, not a\n * programming mistake, so the caller keeps showing its fallback. What it does\n * instead of swallowing the failure is record it — so `iconStatus` can say\n * `\"error\"` rather than lying with `\"missing\"` — and report it to whoever\n * subscribed.\n *\n * @param shard - The shard being fetched.\n * @param slug - The canonical slug whose render asked for it, for the report.\n * @returns A promise that settles once the attempts are done.\n */\nasync function fetchShard(shard: IconShard, slug: string): Promise<void> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= RETRY_DELAYS.length; attempt += 1) {\n try {\n const mod = await shard.load();\n for (const [name, icon] of Object.entries(mod.default)) resolved.set(name, icon);\n loadedShards.add(shard.id);\n failedShards.delete(shard.id);\n return;\n } catch (error) {\n lastError = error;\n const backoff = RETRY_DELAYS[attempt];\n if (backoff === undefined) break;\n await sleep(backoff);\n }\n }\n\n failedShards.set(shard.id, performance.now());\n reportIconLoadError({\n shard: shard.id,\n slug,\n attempts: RETRY_DELAYS.length + 1,\n error: lastError,\n });\n}\n\n/**\n * Wait, as a promise.\n *\n * @param ms - Delay in milliseconds.\n * @returns A promise resolved after the delay.\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Hand a shard failure to whoever is listening.\n *\n * With no subscriber the failure would be silent, which is the state this\n * replaces — so in a dev build it warns instead. An app that wired the\n * subscription up owns the reporting from then on and gets no console noise.\n *\n * @param detail - What failed.\n */\nfunction reportIconLoadError(detail: IconLoadError): void {\n if (errorListeners.size === 0) {\n if (isDevBuild()) warnShardFailure(detail);\n return;\n }\n for (const listener of errorListeners) listener(detail);\n}\n\nconst warnedShards = new Set<string>();\n\n/**\n * Warn once per shard that failed to load.\n *\n * Once, because every `<Icon>` under that letter re-triggers the path and a\n * warning per icon would bury the console.\n *\n * @param detail - What failed.\n */\nfunction warnShardFailure({ shard, slug, attempts }: IconLoadError): void {\n if (warnedShards.has(shard)) return;\n warnedShards.add(shard);\n console.warn(\n `[tempest-react-sdk] icon shard \"${shard}\" failed to load after ${attempts} attempts ` +\n `(first asked for by \"${slug}\"). The usual cause is a deploy that rotated hashed ` +\n `chunk names while this tab was open. Subscribe with \\`subscribeToIconErrors\\` to ` +\n `report it and reload.`,\n );\n}\n\n/**\n * Subscribe to shard fetches that gave up.\n *\n * The failure is routine in a long-lived tab: a deploy rotates hashed chunk\n * names, the old asset leaves the CDN, and the next icon that needs it 404s. That\n * used to end in a permanent fallback with no signal — nothing for the user,\n * nothing for observability. Subscribing is what turns it into both.\n *\n * @example\n * import { subscribeToIconErrors } from \"tempest-react-sdk/icons\";\n *\n * subscribeToIconErrors(({ shard, error }) => {\n * Sentry.captureException(error, { tags: { iconShard: shard } });\n * promptReloadForStaleChunks();\n * });\n *\n * @param listener - Called once per shard that gave up.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIconErrors(listener: (detail: IconLoadError) => void): () => void {\n errorListeners.add(listener);\n return () => errorListeners.delete(listener);\n}\n\n/**\n * Whether a slug is ready, loading, unknown, or unreachable.\n *\n * `\"missing\"` is only reported once that is actually knowable: either lucide has\n * no icons under that initial letter, or the letter's shard **arrived** without\n * the slug in it. A shard that failed to load reports `\"error\"` instead — the two\n * used to collapse into `\"missing\"`, which turned a stale deploy into what looked\n * like a typo and made `Icon` warn about a name that is perfectly valid.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The slug's resolution state.\n */\nexport function iconStatus(slug: string): \"ready\" | \"loading\" | \"missing\" | \"error\" {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return \"ready\";\n const shard = shardFor(canonical);\n if (!shard) return \"missing\";\n if (loadedShards.has(shard.id)) return \"missing\";\n return failedShards.has(shard.id) ? \"error\" : \"loading\";\n}\n\n/**\n * Warm the cache for slugs you know you are about to render.\n *\n * Useful right before opening a menu or a picker: the shards land while the user\n * is still reaching for it, so nothing flashes a fallback.\n *\n * @param slugs - Icon slugs to preload.\n * @returns A promise that settles when every needed shard is in the cache.\n */\nexport async function preloadIcons(slugs: readonly string[]): Promise<void> {\n await Promise.all(slugs.map(loadIcon));\n}\n\n/**\n * Subscribe to shard arrivals.\n *\n * @param listener - Called after each shard lands.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIcons(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n"],"mappings":"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"}
@@ -1,41 +1,94 @@
1
- import { iconAliases as e } from "./generated/aliases.js";
2
- import { shardLoaders as t } from "./generated/loaders.js";
1
+ import { isDevBuild as e } from "../utils/dev-mode.js";
2
+ import { resolveIconAlias as t } from "./alias.js";
3
+ import { iconShards as n } from "./generated/loaders.js";
3
4
  //#region src/icons/shard-cache.ts
4
- var n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
5
- function o(t) {
6
- return e[t] ?? t;
7
- }
8
- function s(e) {
9
- return n.get(o(e));
10
- }
11
- function c(e) {
12
- let s = o(e);
13
- if (n.has(s)) return Promise.resolve();
14
- let c = s[0] ?? "", l = t[c];
15
- if (!l) return Promise.resolve();
16
- let u = r.get(c);
17
- if (u) return u;
18
- let d = l().then((e) => {
19
- for (let [t, r] of Object.entries(e.default)) n.set(t, r);
20
- }).catch(() => void 0).finally(() => {
21
- r.delete(c), i.add(c);
22
- for (let e of a) e();
5
+ var r = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
6
+ function a(e) {
7
+ if (e === "" || e < n[0].from) return;
8
+ let t = 0, r = n.length - 1;
9
+ for (; t < r;) {
10
+ let i = Math.ceil((t + r) / 2);
11
+ n[i].from <= e ? t = i : r = i - 1;
12
+ }
13
+ return n[t];
14
+ }
15
+ var o = /* @__PURE__ */ new Set(), s = /* @__PURE__ */ new Map(), c = [100, 400], l = 1e4, u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
16
+ function f(e) {
17
+ let n = !1;
18
+ for (let [i, a] of Object.entries(e)) {
19
+ let e = t(i);
20
+ r.get(e) !== a && (r.set(e, a), n = !0);
21
+ }
22
+ if (n) for (let e of d) e();
23
+ }
24
+ function p(e) {
25
+ return r.get(t(e));
26
+ }
27
+ function m(e) {
28
+ let n = t(e);
29
+ if (r.has(n)) return Promise.resolve();
30
+ let o = a(n);
31
+ if (!o) return Promise.resolve();
32
+ let c = i.get(o.id);
33
+ if (c) return c;
34
+ let u = s.get(o.id);
35
+ if (u !== void 0 && performance.now() - u < l) return Promise.resolve();
36
+ let f = h(o, n).finally(() => {
37
+ i.delete(o.id);
38
+ for (let e of d) e();
39
+ });
40
+ return i.set(o.id, f), f;
41
+ }
42
+ async function h(e, t) {
43
+ let n;
44
+ for (let t = 0; t <= c.length; t += 1) try {
45
+ let t = await e.load();
46
+ for (let [e, n] of Object.entries(t.default)) r.set(e, n);
47
+ o.add(e.id), s.delete(e.id);
48
+ return;
49
+ } catch (e) {
50
+ n = e;
51
+ let r = c[t];
52
+ if (r === void 0) break;
53
+ await g(r);
54
+ }
55
+ s.set(e.id, performance.now()), _({
56
+ shard: e.id,
57
+ slug: t,
58
+ attempts: c.length + 1,
59
+ error: n
23
60
  });
24
- return r.set(c, d), d;
25
61
  }
26
- function l(e) {
27
- let r = o(e);
28
- if (n.has(r)) return "ready";
29
- let a = r[0] ?? "";
30
- return t[a] ? i.has(a) ? "missing" : "loading" : "missing";
62
+ function g(e) {
63
+ return new Promise((t) => setTimeout(t, e));
64
+ }
65
+ function _(t) {
66
+ if (u.size === 0) {
67
+ e() && y(t);
68
+ return;
69
+ }
70
+ for (let e of u) e(t);
71
+ }
72
+ var v = /* @__PURE__ */ new Set();
73
+ function y({ shard: e, slug: t, attempts: n }) {
74
+ v.has(e) || (v.add(e), console.warn(`[tempest-react-sdk] icon shard "${e}" failed to load after ${n} attempts (first asked for by "${t}"). The usual cause is a deploy that rotated hashed chunk names while this tab was open. Subscribe with \`subscribeToIconErrors\` to report it and reload.`));
75
+ }
76
+ function b(e) {
77
+ return u.add(e), () => u.delete(e);
78
+ }
79
+ function x(e) {
80
+ let n = t(e);
81
+ if (r.has(n)) return "ready";
82
+ let i = a(n);
83
+ return !i || o.has(i.id) ? "missing" : s.has(i.id) ? "error" : "loading";
31
84
  }
32
- async function u(e) {
33
- await Promise.all(e.map(c));
85
+ async function S(e) {
86
+ await Promise.all(e.map(m));
34
87
  }
35
- function d(e) {
36
- return a.add(e), () => a.delete(e);
88
+ function C(e) {
89
+ return d.add(e), () => d.delete(e);
37
90
  }
38
91
  //#endregion
39
- export { l as iconStatus, c as loadIcon, s as peekIcon, u as preloadIcons, o as resolveIconAlias, d as subscribeToIcons };
92
+ export { x as iconStatus, m as loadIcon, p as peekIcon, S as preloadIcons, f as registerIcons, b as subscribeToIconErrors, C as subscribeToIcons };
40
93
 
41
94
  //# sourceMappingURL=shard-cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shard-cache.js","names":[],"sources":["../../src/icons/shard-cache.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\n\nimport { iconAliases } from \"./generated/aliases\";\nimport { shardLoaders } from \"./generated/loaders\";\n\n/**\n * Slugs resolved so far, across every shard already fetched.\n *\n * Module-level and readable **synchronously**, which is the whole point: once a\n * page has rendered one icon whose slug starts with `s`, every other `s` icon is\n * already in memory and paints on its first frame. A cache that could only be\n * read from an effect would flash a fallback for each new icon, which is the\n * behavior `lucide-react`'s own `DynamicIcon` has.\n */\nconst resolved = new Map<string, LucideIcon>();\n\n/** In-flight shard fetches, so N icons from one shard trigger one import. */\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * Initial letters whose shard has already settled.\n *\n * Needed to tell \"still loading\" from \"no such icon\": until the shard arrives,\n * absence from `resolved` proves nothing. Only once the letter is in here does a\n * missing slug mean the name is genuinely wrong — which is what lets `Icon` warn\n * about a typo without also warning on every icon mid-flight.\n */\nconst settledLetters = new Set<string>();\n\n/** Callbacks to run after a shard lands, so mounted `<Icon>`s re-render. */\nconst listeners = new Set<() => void>();\n\n/**\n * Map a slug to the canonical slug that owns the icon.\n *\n * Lucide keeps 257 deprecated aliases (`alert-circle` → `circle-alert`), and a\n * slug persisted in a database years ago is exactly the case this feature exists\n * for, so an alias must keep resolving after a lucide bump renames it.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The canonical slug.\n */\nexport function resolveIconAlias(slug: string): string {\n return iconAliases[slug] ?? slug;\n}\n\n/**\n * Read an icon out of the cache without triggering a fetch.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The icon component, or `undefined` when its shard is not loaded yet.\n */\nexport function peekIcon(slug: string): LucideIcon | undefined {\n return resolved.get(resolveIconAlias(slug));\n}\n\n/**\n * Load the shard that owns `slug`, if it is not loaded or loading already.\n *\n * Resolves without error for an unknown slug: a name that came from an API is\n * data, not a programming mistake, so the caller renders its fallback instead of\n * seeing an exception thrown mid-render.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns A promise that settles once the shard is in the cache.\n */\nexport function loadIcon(slug: string): Promise<void> {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return Promise.resolve();\n\n const letter = canonical[0] ?? \"\";\n const loader = shardLoaders[letter];\n if (!loader) return Promise.resolve();\n\n const pending = inFlight.get(letter);\n if (pending) return pending;\n\n const promise = loader()\n .then((mod) => {\n for (const [name, icon] of Object.entries(mod.default)) resolved.set(name, icon);\n })\n .catch(() => undefined)\n .finally(() => {\n inFlight.delete(letter);\n settledLetters.add(letter);\n for (const listener of listeners) listener();\n });\n inFlight.set(letter, promise);\n return promise;\n}\n\n/**\n * Whether a slug is ready, still loading, or not an icon at all.\n *\n * `\"missing\"` is only reported once that is actually knowable: either lucide has\n * no icons under that initial letter, or the letter's shard already settled\n * without the slug in it.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The slug's resolution state.\n */\nexport function iconStatus(slug: string): \"ready\" | \"loading\" | \"missing\" {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return \"ready\";\n const letter = canonical[0] ?? \"\";\n if (!shardLoaders[letter]) return \"missing\";\n return settledLetters.has(letter) ? \"missing\" : \"loading\";\n}\n\n/**\n * Warm the cache for slugs you know you are about to render.\n *\n * Useful right before opening a menu or a picker: the shards land while the user\n * is still reaching for it, so nothing flashes a fallback.\n *\n * @param slugs - Icon slugs to preload.\n * @returns A promise that settles when every needed shard is in the cache.\n */\nexport async function preloadIcons(slugs: readonly string[]): Promise<void> {\n await Promise.all(slugs.map(loadIcon));\n}\n\n/**\n * Subscribe to shard arrivals.\n *\n * @param listener - Called after each shard lands.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIcons(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n"],"mappings":";;;AAcA,IAAM,oBAAW,IAAI,IAAwB,GAGvC,oBAAW,IAAI,IAA2B,GAU1C,oBAAiB,IAAI,IAAY,GAGjC,oBAAY,IAAI,IAAgB;AAYtC,SAAgB,EAAiB,GAAsB;CACnD,OAAO,EAAY,MAAS;AAChC;AAQA,SAAgB,EAAS,GAAsC;CAC3D,OAAO,EAAS,IAAI,EAAiB,CAAI,CAAC;AAC9C;AAYA,SAAgB,EAAS,GAA6B;CAClD,IAAM,IAAY,EAAiB,CAAI;CACvC,IAAI,EAAS,IAAI,CAAS,GAAG,OAAO,QAAQ,QAAQ;CAEpD,IAAM,IAAS,EAAU,MAAM,IACzB,IAAS,EAAa;CAC5B,IAAI,CAAC,GAAQ,OAAO,QAAQ,QAAQ;CAEpC,IAAM,IAAU,EAAS,IAAI,CAAM;CACnC,IAAI,GAAS,OAAO;CAEpB,IAAM,IAAU,EAAO,CAAC,CACnB,MAAM,MAAQ;EACX,KAAK,IAAM,CAAC,GAAM,MAAS,OAAO,QAAQ,EAAI,OAAO,GAAG,EAAS,IAAI,GAAM,CAAI;CACnF,CAAC,CAAC,CACD,YAAY,KAAA,CAAS,CAAC,CACtB,cAAc;EAEX,AADA,EAAS,OAAO,CAAM,GACtB,EAAe,IAAI,CAAM;EACzB,KAAK,IAAM,KAAY,GAAW,EAAS;CAC/C,CAAC;CAEL,OADA,EAAS,IAAI,GAAQ,CAAO,GACrB;AACX;AAYA,SAAgB,EAAW,GAA+C;CACtE,IAAM,IAAY,EAAiB,CAAI;CACvC,IAAI,EAAS,IAAI,CAAS,GAAG,OAAO;CACpC,IAAM,IAAS,EAAU,MAAM;CAE/B,OADK,EAAa,KACX,EAAe,IAAI,CAAM,IAAI,YAAY,YADd;AAEtC;AAWA,eAAsB,EAAa,GAAyC;CACxE,MAAM,QAAQ,IAAI,EAAM,IAAI,CAAQ,CAAC;AACzC;AAQA,SAAgB,EAAiB,GAAkC;CAE/D,OADA,EAAU,IAAI,CAAQ,SACT,EAAU,OAAO,CAAQ;AAC1C"}
1
+ {"version":3,"file":"shard-cache.js","names":[],"sources":["../../src/icons/shard-cache.ts"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\n\nimport { isDevBuild } from \"../utils/dev-mode\";\nimport { resolveIconAlias } from \"./alias\";\nimport { iconShards, type IconShard } from \"./generated/loaders\";\n\n/**\n * Slugs resolved so far, across every shard already fetched.\n *\n * Module-level and readable **synchronously**, which is the whole point: once a\n * page has rendered one icon, every other icon in that shard's range is already in\n * memory and paints on its first frame. A cache that could only be read from an\n * effect would flash a fallback for each new icon, which is the behavior\n * `lucide-react`'s own `DynamicIcon` has.\n */\nconst resolved = new Map<string, LucideIcon>();\n\n/** In-flight shard fetches, so N icons from one shard trigger one import. */\nconst inFlight = new Map<string, Promise<void>>();\n\n/**\n * Find the shard that owns a slug.\n *\n * The shards are contiguous, sorted ranges, so this is a binary search over their\n * lower bounds — 45 entries in the index rather than the 2000-entry slug→chunk map\n * that costs 120 KB in a main chunk.\n *\n * A slug sorting before the first range belongs to no shard, which is knowable\n * without any fetch: `\"0-not-an-icon\"` cannot be a lucide name.\n *\n * @param canonical - A canonical slug, aliases already resolved.\n * @returns The owning shard, or `undefined` when no range can hold it.\n */\nfunction shardFor(canonical: string): IconShard | undefined {\n if (canonical === \"\" || canonical < iconShards[0].from) return undefined;\n\n let low = 0;\n let high = iconShards.length - 1;\n while (low < high) {\n const mid = Math.ceil((low + high) / 2);\n if (iconShards[mid].from <= canonical) low = mid;\n else high = mid - 1;\n }\n return iconShards[low];\n}\n\n/**\n * Shard ids whose chunk actually arrived.\n *\n * Needed to tell \"still loading\" from \"no such icon\": until the shard arrives,\n * absence from `resolved` proves nothing. Only once the shard is in here does a\n * missing slug mean the name is genuinely wrong — which is what lets `Icon` warn\n * about a typo without also warning on every icon mid-flight.\n *\n * A shard that *failed* deliberately does not land here. Collapsing \"the chunk\n * 404'd\" into \"no such icon\" is what made a stale deploy look like a typo.\n */\nconst loadedShards = new Set<string>();\n\n/**\n * Shards whose fetch gave up, and when.\n *\n * The timestamp is what stops a permanent fallback: `useIcon` re-runs its effect\n * on every miss, so a shard is retried on a later render — after a cooldown, so a\n * chunk that is genuinely gone cannot turn into a request loop.\n */\nconst failedShards = new Map<string, number>();\n\n/**\n * Backoff before each retry, in milliseconds.\n *\n * Two retries, both fast, because the failure this exists for is a transient one:\n * a flaky connection, or a chunk whose CDN edge has not caught up. A 404 from a\n * deploy that rotated hashed filenames is *not* fixed by retrying — for that, the\n * error subscription is the signal, and the app reloads.\n */\nconst RETRY_DELAYS = [100, 400] as const;\n\n/** How long a failed shard is left alone before another render may retry it. */\nconst RETRY_COOLDOWN_MS = 10_000;\n\n/** What a shard failure reports to whoever subscribed. */\nexport interface IconLoadError {\n /** The shard key whose chunk could not be fetched. */\n shard: string;\n /** The slug whose render asked for it. */\n slug: string;\n /** Attempts made before giving up, retries included. */\n attempts: number;\n /** The last rejection from the dynamic import. */\n error: unknown;\n}\n\n/** Callbacks to run when a shard fetch gives up. */\nconst errorListeners = new Set<(detail: IconLoadError) => void>();\n\n/** Callbacks to run after a shard lands, so mounted `<Icon>`s re-render. */\nconst listeners = new Set<() => void>();\n\n/**\n * Make icon components resolvable by slug, with no provider and no plugin.\n *\n * Call it once from an entrypoint. The icons land in the same table a fetched\n * shard fills, so every `<Icon>` below — including one that renders before the\n * call, since registering notifies subscribers — resolves them synchronously and\n * never issues a request.\n *\n * This is the whole setup for a closed catalog: an admin panel with twenty known\n * icons pays two lines instead of a build plugin plus a provider. `IconProvider`\n * stays for what is genuinely tree-scoped — the `size`/`strokeWidth` defaults and\n * a registry that must override the global one for one subtree.\n *\n * A slug lucide does not ship is registered as-is, which is how an app adds its\n * own artwork to the same `<Icon name>` call site.\n *\n * @example\n * import { registerIcons } from \"tempest-react-sdk/icons\";\n * import { Save, Trash2 } from \"lucide-react\";\n *\n * registerIcons({ save: Save, \"trash-2\": Trash2 });\n *\n * @param icons - Slug → icon component. Deprecated slugs are stored under the\n * canonical name, so both spellings resolve.\n */\nexport function registerIcons(icons: Readonly<Record<string, LucideIcon>>): void {\n let changed = false;\n for (const [slug, icon] of Object.entries(icons)) {\n const canonical = resolveIconAlias(slug);\n if (resolved.get(canonical) === icon) continue;\n resolved.set(canonical, icon);\n changed = true;\n }\n if (!changed) return;\n for (const listener of listeners) listener();\n}\n\n/**\n * Read an icon out of the cache without triggering a fetch.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The icon component, or `undefined` when its shard is not loaded yet.\n */\nexport function peekIcon(slug: string): LucideIcon | undefined {\n return resolved.get(resolveIconAlias(slug));\n}\n\n/**\n * Load the shard that owns `slug`, if it is not loaded or loading already.\n *\n * Resolves without error for an unknown slug: a name that came from an API is\n * data, not a programming mistake, so the caller renders its fallback instead of\n * seeing an exception thrown mid-render.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns A promise that settles once the shard is in the cache.\n */\nexport function loadIcon(slug: string): Promise<void> {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return Promise.resolve();\n\n const shard = shardFor(canonical);\n if (!shard) return Promise.resolve();\n\n const pending = inFlight.get(shard.id);\n if (pending) return pending;\n\n const failedAt = failedShards.get(shard.id);\n if (failedAt !== undefined && performance.now() - failedAt < RETRY_COOLDOWN_MS) {\n return Promise.resolve();\n }\n\n const promise = fetchShard(shard, canonical).finally(() => {\n inFlight.delete(shard.id);\n for (const listener of listeners) listener();\n });\n inFlight.set(shard.id, promise);\n return promise;\n}\n\n/**\n * Fetch one shard, retrying a couple of times before giving up.\n *\n * Never rejects: an icon whose chunk did not arrive is a rendering outcome, not a\n * programming mistake, so the caller keeps showing its fallback. What it does\n * instead of swallowing the failure is record it — so `iconStatus` can say\n * `\"error\"` rather than lying with `\"missing\"` — and report it to whoever\n * subscribed.\n *\n * @param shard - The shard being fetched.\n * @param slug - The canonical slug whose render asked for it, for the report.\n * @returns A promise that settles once the attempts are done.\n */\nasync function fetchShard(shard: IconShard, slug: string): Promise<void> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= RETRY_DELAYS.length; attempt += 1) {\n try {\n const mod = await shard.load();\n for (const [name, icon] of Object.entries(mod.default)) resolved.set(name, icon);\n loadedShards.add(shard.id);\n failedShards.delete(shard.id);\n return;\n } catch (error) {\n lastError = error;\n const backoff = RETRY_DELAYS[attempt];\n if (backoff === undefined) break;\n await sleep(backoff);\n }\n }\n\n failedShards.set(shard.id, performance.now());\n reportIconLoadError({\n shard: shard.id,\n slug,\n attempts: RETRY_DELAYS.length + 1,\n error: lastError,\n });\n}\n\n/**\n * Wait, as a promise.\n *\n * @param ms - Delay in milliseconds.\n * @returns A promise resolved after the delay.\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Hand a shard failure to whoever is listening.\n *\n * With no subscriber the failure would be silent, which is the state this\n * replaces — so in a dev build it warns instead. An app that wired the\n * subscription up owns the reporting from then on and gets no console noise.\n *\n * @param detail - What failed.\n */\nfunction reportIconLoadError(detail: IconLoadError): void {\n if (errorListeners.size === 0) {\n if (isDevBuild()) warnShardFailure(detail);\n return;\n }\n for (const listener of errorListeners) listener(detail);\n}\n\nconst warnedShards = new Set<string>();\n\n/**\n * Warn once per shard that failed to load.\n *\n * Once, because every `<Icon>` under that letter re-triggers the path and a\n * warning per icon would bury the console.\n *\n * @param detail - What failed.\n */\nfunction warnShardFailure({ shard, slug, attempts }: IconLoadError): void {\n if (warnedShards.has(shard)) return;\n warnedShards.add(shard);\n console.warn(\n `[tempest-react-sdk] icon shard \"${shard}\" failed to load after ${attempts} attempts ` +\n `(first asked for by \"${slug}\"). The usual cause is a deploy that rotated hashed ` +\n `chunk names while this tab was open. Subscribe with \\`subscribeToIconErrors\\` to ` +\n `report it and reload.`,\n );\n}\n\n/**\n * Subscribe to shard fetches that gave up.\n *\n * The failure is routine in a long-lived tab: a deploy rotates hashed chunk\n * names, the old asset leaves the CDN, and the next icon that needs it 404s. That\n * used to end in a permanent fallback with no signal — nothing for the user,\n * nothing for observability. Subscribing is what turns it into both.\n *\n * @example\n * import { subscribeToIconErrors } from \"tempest-react-sdk/icons\";\n *\n * subscribeToIconErrors(({ shard, error }) => {\n * Sentry.captureException(error, { tags: { iconShard: shard } });\n * promptReloadForStaleChunks();\n * });\n *\n * @param listener - Called once per shard that gave up.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIconErrors(listener: (detail: IconLoadError) => void): () => void {\n errorListeners.add(listener);\n return () => errorListeners.delete(listener);\n}\n\n/**\n * Whether a slug is ready, loading, unknown, or unreachable.\n *\n * `\"missing\"` is only reported once that is actually knowable: either lucide has\n * no icons under that initial letter, or the letter's shard **arrived** without\n * the slug in it. A shard that failed to load reports `\"error\"` instead — the two\n * used to collapse into `\"missing\"`, which turned a stale deploy into what looked\n * like a typo and made `Icon` warn about a name that is perfectly valid.\n *\n * @param slug - Any icon slug, canonical or deprecated.\n * @returns The slug's resolution state.\n */\nexport function iconStatus(slug: string): \"ready\" | \"loading\" | \"missing\" | \"error\" {\n const canonical = resolveIconAlias(slug);\n if (resolved.has(canonical)) return \"ready\";\n const shard = shardFor(canonical);\n if (!shard) return \"missing\";\n if (loadedShards.has(shard.id)) return \"missing\";\n return failedShards.has(shard.id) ? \"error\" : \"loading\";\n}\n\n/**\n * Warm the cache for slugs you know you are about to render.\n *\n * Useful right before opening a menu or a picker: the shards land while the user\n * is still reaching for it, so nothing flashes a fallback.\n *\n * @param slugs - Icon slugs to preload.\n * @returns A promise that settles when every needed shard is in the cache.\n */\nexport async function preloadIcons(slugs: readonly string[]): Promise<void> {\n await Promise.all(slugs.map(loadIcon));\n}\n\n/**\n * Subscribe to shard arrivals.\n *\n * @param listener - Called after each shard lands.\n * @returns An unsubscribe function.\n */\nexport function subscribeToIcons(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./normalize-icon-name.cjs"),t=require("./is-icon-name.cjs");var n=`Ícone inexistente. Use um slug do lucide, em kebab-case.`;function r(n,r){if(n.trim()!==``)return t.isIconName(e.normalizeIconName(n))?void 0:r??`Ícone inexistente. Use um slug do lucide, em kebab-case.`}exports.DEFAULT_ICON_PICKER_MESSAGE=n,exports.validateIconName=r;
2
+ //# sourceMappingURL=validate-icon-name.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-icon-name.cjs","names":[],"sources":["../../src/icons/validate-icon-name.ts"],"sourcesContent":["import { isIconName } from \"./is-icon-name\";\nimport { normalizeIconName } from \"./normalize-icon-name\";\n\n/** The default message for a slug lucide does not ship. */\nexport const DEFAULT_ICON_PICKER_MESSAGE =\n \"Ícone inexistente. Use um slug do lucide, em kebab-case.\";\n\n/**\n * Validate an icon slug the way `IconPicker` does.\n *\n * Its own module rather than living next to the component: a file that exports\n * both a component and other values breaks Fast Refresh in a consuming dev\n * server, which is what `react-refresh/only-export-components` guards and why\n * `icon-context.ts` is split off from `IconProvider` too.\n *\n * Exported because the picker is not the only place a slug is checked: a form\n * built on react-hook-form or zod validates before submitting, and duplicating\n * the rule there is how the two drift apart.\n *\n * Empty passes — \"no icon chosen\" is a `required` question, not a spelling one,\n * and conflating them would make the field impossible to clear.\n *\n * @example\n * // react-hook-form\n * register(\"icon\", { validate: (value) => validateIconName(value) ?? true });\n *\n * @example\n * // zod\n * z.string().refine((value) => !validateIconName(value), { message: \"Ícone inexistente\" });\n *\n * @param value - The slug to check, in any spelling the picker accepts.\n * @param message - Overrides the default message.\n * @returns The message when the slug does not exist, `undefined` when it is fine.\n */\nexport function validateIconName(value: string, message?: string): string | undefined {\n if (value.trim() === \"\") return undefined;\n return isIconName(normalizeIconName(value))\n ? undefined\n : (message ?? DEFAULT_ICON_PICKER_MESSAGE);\n}\n"],"mappings":"6EAIA,IAAa,EACT,2DA6BJ,SAAgB,EAAiB,EAAe,EAAsC,CAC9E,KAAM,KAAK,IAAM,GACrB,OAAO,EAAA,WAAW,EAAA,kBAAkB,CAAK,CAAC,EACpC,IAAA,GACC,GAAA,0DACX"}
@@ -0,0 +1,11 @@
1
+ import { normalizeIconName as e } from "./normalize-icon-name.js";
2
+ import { isIconName as t } from "./is-icon-name.js";
3
+ //#region src/icons/validate-icon-name.ts
4
+ var n = "Ícone inexistente. Use um slug do lucide, em kebab-case.";
5
+ function r(n, r) {
6
+ if (n.trim() !== "") return t(e(n)) ? void 0 : r ?? "Ícone inexistente. Use um slug do lucide, em kebab-case.";
7
+ }
8
+ //#endregion
9
+ export { n as DEFAULT_ICON_PICKER_MESSAGE, r as validateIconName };
10
+
11
+ //# sourceMappingURL=validate-icon-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-icon-name.js","names":[],"sources":["../../src/icons/validate-icon-name.ts"],"sourcesContent":["import { isIconName } from \"./is-icon-name\";\nimport { normalizeIconName } from \"./normalize-icon-name\";\n\n/** The default message for a slug lucide does not ship. */\nexport const DEFAULT_ICON_PICKER_MESSAGE =\n \"Ícone inexistente. Use um slug do lucide, em kebab-case.\";\n\n/**\n * Validate an icon slug the way `IconPicker` does.\n *\n * Its own module rather than living next to the component: a file that exports\n * both a component and other values breaks Fast Refresh in a consuming dev\n * server, which is what `react-refresh/only-export-components` guards and why\n * `icon-context.ts` is split off from `IconProvider` too.\n *\n * Exported because the picker is not the only place a slug is checked: a form\n * built on react-hook-form or zod validates before submitting, and duplicating\n * the rule there is how the two drift apart.\n *\n * Empty passes — \"no icon chosen\" is a `required` question, not a spelling one,\n * and conflating them would make the field impossible to clear.\n *\n * @example\n * // react-hook-form\n * register(\"icon\", { validate: (value) => validateIconName(value) ?? true });\n *\n * @example\n * // zod\n * z.string().refine((value) => !validateIconName(value), { message: \"Ícone inexistente\" });\n *\n * @param value - The slug to check, in any spelling the picker accepts.\n * @param message - Overrides the default message.\n * @returns The message when the slug does not exist, `undefined` when it is fine.\n */\nexport function validateIconName(value: string, message?: string): string | undefined {\n if (value.trim() === \"\") return undefined;\n return isIconName(normalizeIconName(value))\n ? undefined\n : (message ?? DEFAULT_ICON_PICKER_MESSAGE);\n}\n"],"mappings":";;;AAIA,IAAa,IACT;AA6BJ,SAAgB,EAAiB,GAAe,GAAsC;CAC9E,MAAM,KAAK,MAAM,IACrB,OAAO,EAAW,EAAkB,CAAK,CAAC,IACpC,KAAA,IACC,KAAA;AACX"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Types for the legacy `virtual:tempest-icons` module id.
3
+ *
4
+ * Kept for apps that already import that spelling. New code should import
5
+ * `tempest-react-sdk/icons/virtual` instead, which is a real module in the
6
+ * package: it needs no ambient declaration, and it resolves outside a Vite build
7
+ * with the plugin — to an empty registry — rather than failing to resolve at all.
8
+ *
9
+ * Reaching this declaration takes no setup: `dist/icons.d.ts` and
10
+ * `dist/icons-virtual.d.ts` both reference it, so importing anything from
11
+ * `tempest-react-sdk/icons` is enough.
12
+ */
13
+ declare module "virtual:tempest-icons" {
14
+ import type { LucideIcon } from "lucide-react";
15
+
16
+ /**
17
+ * Every icon slug found as a literal in the scanned source, mapped to the
18
+ * statically imported lucide component.
19
+ *
20
+ * Pass it to `IconProvider`'s `registry` prop. Slugs resolved from here cost
21
+ * no extra request — they are ordinary imports the bundler tree-shakes.
22
+ */
23
+ export const staticIcons: Record<string, LucideIcon>;
24
+ }
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={};exports.staticIcons=e;
2
+ //# sourceMappingURL=icons-virtual.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons-virtual.cjs","names":[],"sources":["../src/icons/virtual.ts"],"sourcesContent":["import type { IconRegistry } from \"./icon-context\";\n\n/**\n * The static icon registry, empty until a build plugin fills it in.\n *\n * `tempestIcons()` resolves this module id to the table it generated from the\n * slugs your source mentions. Every other runner — vitest without the plugin,\n * `tsx`, a Storybook builder, a Node script that imports a component — gets this\n * stub, so the import always resolves and `<Icon>` falls back to fetching shards.\n *\n * That fallback is why the stub exists: before it, an app that imported the\n * registry could not be loaded outside a Vite build with the plugin installed,\n * and the failure was the whole module graph refusing to resolve rather than one\n * icon going missing.\n *\n * @example\n * import { IconProvider } from \"tempest-react-sdk/icons\";\n * import { staticIcons } from \"tempest-react-sdk/icons/virtual\";\n *\n * <IconProvider registry={staticIcons}>\n * <App />\n * </IconProvider>\n */\nexport const staticIcons: IconRegistry = {};\n"],"mappings":"mEAuBA,IAAa,EAA4B,CAAC"}