@7pmlabs/design-system 1.0.10 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (429) hide show
  1. package/README.md +57 -6
  2. package/dist/design-system.css +1 -1
  3. package/dist/design-system.js +66 -60
  4. package/dist/design-system100.js +4 -5
  5. package/dist/design-system100.js.map +1 -1
  6. package/dist/design-system101.js +53 -506
  7. package/dist/design-system101.js.map +1 -1
  8. package/dist/{design-system93.js → design-system102.js} +1 -1
  9. package/dist/design-system102.js.map +1 -0
  10. package/dist/design-system103.js +13 -5
  11. package/dist/design-system103.js.map +1 -1
  12. package/dist/design-system104.js +109 -7
  13. package/dist/design-system104.js.map +1 -1
  14. package/dist/design-system106.js +9 -0
  15. package/dist/design-system106.js.map +1 -0
  16. package/dist/design-system107.js +206 -6
  17. package/dist/design-system107.js.map +1 -1
  18. package/dist/design-system109.js +9 -0
  19. package/dist/design-system109.js.map +1 -0
  20. package/dist/design-system110.js +507 -6
  21. package/dist/design-system110.js.map +1 -1
  22. package/dist/design-system112.js +8 -0
  23. package/dist/design-system112.js.map +1 -0
  24. package/dist/design-system113.js +7 -5
  25. package/dist/design-system113.js.map +1 -1
  26. package/dist/design-system114.js +209 -9
  27. package/dist/design-system114.js.map +1 -1
  28. package/dist/design-system116.js +9 -0
  29. package/dist/design-system116.js.map +1 -0
  30. package/dist/design-system117.js +224 -6
  31. package/dist/design-system117.js.map +1 -1
  32. package/dist/design-system119.js +9 -0
  33. package/dist/design-system119.js.map +1 -0
  34. package/dist/design-system12.js.map +1 -1
  35. package/dist/design-system120.js +163 -5
  36. package/dist/design-system120.js.map +1 -1
  37. package/dist/design-system122.js +5 -90
  38. package/dist/design-system122.js.map +1 -1
  39. package/dist/design-system123.js +12 -0
  40. package/dist/design-system123.js.map +1 -0
  41. package/dist/design-system124.js +274 -5
  42. package/dist/design-system124.js.map +1 -1
  43. package/dist/design-system126.js +9 -0
  44. package/dist/design-system126.js.map +1 -0
  45. package/dist/design-system127.js +16 -5
  46. package/dist/design-system127.js.map +1 -1
  47. package/dist/design-system129.js +8 -0
  48. package/dist/design-system129.js.map +1 -0
  49. package/dist/design-system130.js +12 -5
  50. package/dist/design-system130.js.map +1 -1
  51. package/dist/design-system131.js +76 -137
  52. package/dist/design-system131.js.map +1 -1
  53. package/dist/design-system133.js +1 -1
  54. package/dist/design-system133.js.map +1 -1
  55. package/dist/design-system134.js +37 -90
  56. package/dist/design-system134.js.map +1 -1
  57. package/dist/design-system136.js +1 -1
  58. package/dist/design-system136.js.map +1 -1
  59. package/dist/design-system137.js +226 -20
  60. package/dist/design-system137.js.map +1 -1
  61. package/dist/design-system139.js +4 -5
  62. package/dist/design-system139.js.map +1 -1
  63. package/dist/design-system140.js +151 -9
  64. package/dist/design-system140.js.map +1 -1
  65. package/dist/design-system142.js +3 -2
  66. package/dist/design-system142.js.map +1 -1
  67. package/dist/design-system143.js +93 -19
  68. package/dist/design-system143.js.map +1 -1
  69. package/dist/design-system145.js +5 -158
  70. package/dist/design-system145.js.map +1 -1
  71. package/dist/design-system146.js +12 -0
  72. package/dist/design-system146.js.map +1 -0
  73. package/dist/design-system147.js +37 -5
  74. package/dist/design-system147.js.map +1 -1
  75. package/dist/design-system148.js +4 -307
  76. package/dist/design-system148.js.map +1 -1
  77. package/dist/design-system149.js +24 -0
  78. package/dist/{design-system144.js.map → design-system149.js.map} +1 -1
  79. package/dist/design-system150.js +2 -3
  80. package/dist/design-system150.js.map +1 -1
  81. package/dist/design-system151.js +131 -213
  82. package/dist/design-system151.js.map +1 -1
  83. package/dist/design-system153.js +1 -1
  84. package/dist/design-system153.js.map +1 -1
  85. package/dist/design-system154.js +278 -160
  86. package/dist/design-system154.js.map +1 -1
  87. package/dist/design-system156.js +1 -1
  88. package/dist/design-system156.js.map +1 -1
  89. package/dist/design-system157.js +240 -3
  90. package/dist/design-system157.js.map +1 -1
  91. package/dist/design-system159.js +8 -0
  92. package/dist/design-system159.js.map +1 -0
  93. package/dist/design-system16.js.map +1 -1
  94. package/dist/design-system160.js +189 -6
  95. package/dist/design-system160.js.map +1 -1
  96. package/dist/design-system162.js +8 -0
  97. package/dist/design-system162.js.map +1 -0
  98. package/dist/design-system163.js +3 -6
  99. package/dist/design-system163.js.map +1 -1
  100. package/dist/design-system164.js +46 -57
  101. package/dist/design-system164.js.map +1 -1
  102. package/dist/design-system166.js +2 -2
  103. package/dist/design-system166.js.map +1 -1
  104. package/dist/design-system167.js +44 -170
  105. package/dist/design-system167.js.map +1 -1
  106. package/dist/design-system169.js +2 -2
  107. package/dist/design-system169.js.map +1 -1
  108. package/dist/design-system170.js +55 -101
  109. package/dist/design-system170.js.map +1 -1
  110. package/dist/design-system172.js +5 -4
  111. package/dist/design-system172.js.map +1 -1
  112. package/dist/design-system173.js +182 -11
  113. package/dist/design-system173.js.map +1 -1
  114. package/dist/design-system175.js +9 -0
  115. package/dist/design-system175.js.map +1 -0
  116. package/dist/design-system176.js +115 -6
  117. package/dist/design-system176.js.map +1 -1
  118. package/dist/design-system178.js +8 -0
  119. package/dist/design-system178.js.map +1 -0
  120. package/dist/design-system179.js +11 -5
  121. package/dist/design-system179.js.map +1 -1
  122. package/dist/design-system180.js +444 -70
  123. package/dist/design-system180.js.map +1 -1
  124. package/dist/design-system182.js +5 -4
  125. package/dist/design-system182.js.map +1 -1
  126. package/dist/design-system183.js +21 -21
  127. package/dist/design-system183.js.map +1 -1
  128. package/dist/design-system185.js +1 -1
  129. package/dist/design-system185.js.map +1 -1
  130. package/dist/design-system186.js +85 -25
  131. package/dist/design-system186.js.map +1 -1
  132. package/dist/design-system188.js +1 -1
  133. package/dist/design-system188.js.map +1 -1
  134. package/dist/design-system189.js +7 -5
  135. package/dist/design-system189.js.map +1 -1
  136. package/dist/design-system19.js.map +1 -1
  137. package/dist/design-system191.js +1 -1
  138. package/dist/design-system191.js.map +1 -1
  139. package/dist/design-system192.js +20 -23
  140. package/dist/design-system192.js.map +1 -1
  141. package/dist/design-system194.js +1 -1
  142. package/dist/design-system194.js.map +1 -1
  143. package/dist/design-system195.js +24 -323
  144. package/dist/design-system195.js.map +1 -1
  145. package/dist/design-system197.js +1 -1
  146. package/dist/design-system197.js.map +1 -1
  147. package/dist/design-system198.js +19 -88
  148. package/dist/design-system198.js.map +1 -1
  149. package/dist/design-system200.js +1 -1
  150. package/dist/design-system200.js.map +1 -1
  151. package/dist/design-system201.js +330 -17
  152. package/dist/design-system201.js.map +1 -1
  153. package/dist/design-system203.js +5 -3
  154. package/dist/design-system203.js.map +1 -1
  155. package/dist/design-system204.js +88 -407
  156. package/dist/design-system204.js.map +1 -1
  157. package/dist/design-system206.js +1 -1
  158. package/dist/design-system206.js.map +1 -1
  159. package/dist/design-system207.js +17 -106
  160. package/dist/design-system207.js.map +1 -1
  161. package/dist/{design-system202.js → design-system208.js} +2 -2
  162. package/dist/{design-system202.js.map → design-system208.js.map} +1 -1
  163. package/dist/design-system209.js +3 -6
  164. package/dist/design-system209.js.map +1 -1
  165. package/dist/design-system210.js +403 -90
  166. package/dist/design-system210.js.map +1 -1
  167. package/dist/design-system212.js +4 -5
  168. package/dist/design-system212.js.map +1 -1
  169. package/dist/design-system213.js +45 -723
  170. package/dist/design-system213.js.map +1 -1
  171. package/dist/design-system215.js +1 -1
  172. package/dist/design-system215.js.map +1 -1
  173. package/dist/design-system216.js +88 -11
  174. package/dist/design-system216.js.map +1 -1
  175. package/dist/design-system217.js +4 -525
  176. package/dist/design-system217.js.map +1 -1
  177. package/dist/design-system218.js +111 -0
  178. package/dist/design-system218.js.map +1 -0
  179. package/dist/design-system22.js.map +1 -1
  180. package/dist/design-system220.js +6 -3
  181. package/dist/design-system220.js.map +1 -1
  182. package/dist/design-system221.js +103 -43
  183. package/dist/design-system221.js.map +1 -1
  184. package/dist/design-system223.js +6 -283
  185. package/dist/design-system223.js.map +1 -1
  186. package/dist/design-system224.js +740 -0
  187. package/dist/design-system224.js.map +1 -0
  188. package/dist/design-system226.js +5 -119
  189. package/dist/design-system226.js.map +1 -1
  190. package/dist/{design-system60.js → design-system227.js} +6 -8
  191. package/dist/design-system227.js.map +1 -0
  192. package/dist/design-system228.js +525 -5
  193. package/dist/design-system228.js.map +1 -1
  194. package/dist/{design-system219.js → design-system230.js} +2 -2
  195. package/dist/{design-system219.js.map → design-system230.js.map} +1 -1
  196. package/dist/design-system231.js +3 -5
  197. package/dist/design-system231.js.map +1 -1
  198. package/dist/design-system232.js +42 -50
  199. package/dist/design-system232.js.map +1 -1
  200. package/dist/design-system233.js +1 -1
  201. package/dist/design-system233.js.map +1 -1
  202. package/dist/design-system234.js +254 -141
  203. package/dist/design-system234.js.map +1 -1
  204. package/dist/design-system236.js +1 -1
  205. package/dist/design-system236.js.map +1 -1
  206. package/dist/design-system237.js +119 -7
  207. package/dist/design-system237.js.map +1 -1
  208. package/dist/design-system239.js +8 -0
  209. package/dist/design-system239.js.map +1 -0
  210. package/dist/design-system240.js +112 -5
  211. package/dist/design-system240.js.map +1 -1
  212. package/dist/design-system242.js +8 -0
  213. package/dist/design-system242.js.map +1 -0
  214. package/dist/design-system243.js +54 -6
  215. package/dist/design-system243.js.map +1 -1
  216. package/dist/design-system244.js +4 -7
  217. package/dist/design-system244.js.map +1 -1
  218. package/dist/design-system245.js +139 -343
  219. package/dist/design-system245.js.map +1 -1
  220. package/dist/design-system247.js +4 -5
  221. package/dist/design-system247.js.map +1 -1
  222. package/dist/design-system248.js +10 -0
  223. package/dist/design-system248.js.map +1 -0
  224. package/dist/{design-system238.js → design-system249.js} +2 -2
  225. package/dist/design-system249.js.map +1 -0
  226. package/dist/design-system25.js.map +1 -1
  227. package/dist/design-system251.js +8 -0
  228. package/dist/design-system251.js.map +1 -0
  229. package/dist/{design-system241.js → design-system252.js} +1 -1
  230. package/dist/design-system252.js.map +1 -0
  231. package/dist/design-system254.js +9 -0
  232. package/dist/design-system254.js.map +1 -0
  233. package/dist/design-system255.js +12 -0
  234. package/dist/design-system255.js.map +1 -0
  235. package/dist/design-system256.js +769 -0
  236. package/dist/design-system256.js.map +1 -0
  237. package/dist/design-system258.js +9 -0
  238. package/dist/design-system258.js.map +1 -0
  239. package/dist/design-system259.js +10 -0
  240. package/dist/design-system259.js.map +1 -0
  241. package/dist/design-system260.js +377 -0
  242. package/dist/design-system260.js.map +1 -0
  243. package/dist/design-system262.js +9 -0
  244. package/dist/design-system262.js.map +1 -0
  245. package/dist/design-system28.js.map +1 -1
  246. package/dist/design-system3.js.map +1 -1
  247. package/dist/design-system30.js +21 -138
  248. package/dist/design-system30.js.map +1 -1
  249. package/dist/design-system32.js +5 -4
  250. package/dist/design-system32.js.map +1 -1
  251. package/dist/design-system33.js +488 -14
  252. package/dist/design-system33.js.map +1 -1
  253. package/dist/design-system35.js +1 -1
  254. package/dist/design-system35.js.map +1 -1
  255. package/dist/design-system36.js +135 -17
  256. package/dist/design-system36.js.map +1 -1
  257. package/dist/design-system38.js +1 -1
  258. package/dist/design-system38.js.map +1 -1
  259. package/dist/design-system39.js +16 -11
  260. package/dist/design-system39.js.map +1 -1
  261. package/dist/design-system4.js.map +1 -1
  262. package/dist/design-system41.js +8 -0
  263. package/dist/design-system41.js.map +1 -0
  264. package/dist/design-system42.js +26 -5
  265. package/dist/design-system42.js.map +1 -1
  266. package/dist/design-system44.js +5 -71
  267. package/dist/design-system44.js.map +1 -1
  268. package/dist/design-system45.js +353 -0
  269. package/dist/design-system45.js.map +1 -0
  270. package/dist/design-system47.js +5 -50
  271. package/dist/design-system47.js.map +1 -1
  272. package/dist/design-system48.js +11 -4
  273. package/dist/design-system48.js.map +1 -1
  274. package/dist/design-system49.js +476 -3
  275. package/dist/design-system49.js.map +1 -1
  276. package/dist/design-system51.js +8 -0
  277. package/dist/design-system51.js.map +1 -0
  278. package/dist/design-system52.js +3 -5
  279. package/dist/design-system52.js.map +1 -1
  280. package/dist/design-system53.js +56 -83
  281. package/dist/design-system53.js.map +1 -1
  282. package/dist/design-system55.js +5 -4
  283. package/dist/design-system55.js.map +1 -1
  284. package/dist/design-system56.js +50 -11
  285. package/dist/design-system56.js.map +1 -1
  286. package/dist/design-system57.js +4 -591
  287. package/dist/design-system57.js.map +1 -1
  288. package/dist/design-system58.js +6 -0
  289. package/dist/design-system58.js.map +1 -0
  290. package/dist/design-system59.js +64 -5
  291. package/dist/design-system59.js.map +1 -1
  292. package/dist/design-system61.js +5 -696
  293. package/dist/design-system61.js.map +1 -1
  294. package/dist/design-system62.js +101 -0
  295. package/dist/design-system62.js.map +1 -0
  296. package/dist/design-system64.js +5 -158
  297. package/dist/design-system64.js.map +1 -1
  298. package/dist/design-system65.js +14 -0
  299. package/dist/design-system65.js.map +1 -0
  300. package/dist/design-system66.js +591 -5
  301. package/dist/design-system66.js.map +1 -1
  302. package/dist/design-system68.js +3 -2
  303. package/dist/design-system68.js.map +1 -1
  304. package/dist/design-system69.js +13 -49
  305. package/dist/design-system69.js.map +1 -1
  306. package/dist/design-system7.js.map +1 -1
  307. package/dist/design-system70.js +699 -0
  308. package/dist/{design-system63.js.map → design-system70.js.map} +1 -1
  309. package/dist/design-system72.js +5 -199
  310. package/dist/design-system72.js.map +1 -1
  311. package/dist/design-system73.js +161 -0
  312. package/dist/design-system73.js.map +1 -0
  313. package/dist/design-system75.js +5 -7
  314. package/dist/design-system75.js.map +1 -1
  315. package/dist/design-system76.js +25 -269
  316. package/dist/design-system76.js.map +1 -1
  317. package/dist/design-system77.js +7 -0
  318. package/dist/design-system77.js.map +1 -0
  319. package/dist/design-system78.js +49 -5
  320. package/dist/design-system78.js.map +1 -1
  321. package/dist/{design-system71.js → design-system80.js} +2 -2
  322. package/dist/{design-system71.js.map → design-system80.js.map} +1 -1
  323. package/dist/design-system81.js +199 -5
  324. package/dist/design-system81.js.map +1 -1
  325. package/dist/design-system83.js +5 -99
  326. package/dist/design-system83.js.map +1 -1
  327. package/dist/design-system84.js +10 -0
  328. package/dist/design-system84.js.map +1 -0
  329. package/dist/design-system85.js +273 -5
  330. package/dist/design-system85.js.map +1 -1
  331. package/dist/design-system87.js +8 -0
  332. package/dist/design-system87.js.map +1 -0
  333. package/dist/design-system88.js +57 -5
  334. package/dist/design-system88.js.map +1 -1
  335. package/dist/design-system90.js +8 -0
  336. package/dist/design-system90.js.map +1 -0
  337. package/dist/design-system91.js +11 -5
  338. package/dist/design-system91.js.map +1 -1
  339. package/dist/design-system92.js +98 -53
  340. package/dist/design-system92.js.map +1 -1
  341. package/dist/design-system94.js +5 -13
  342. package/dist/design-system94.js.map +1 -1
  343. package/dist/design-system95.js +61 -104
  344. package/dist/design-system95.js.map +1 -1
  345. package/dist/design-system97.js +4 -5
  346. package/dist/design-system97.js.map +1 -1
  347. package/dist/design-system98.js +80 -198
  348. package/dist/design-system98.js.map +1 -1
  349. package/dist/types/components/BCalendar/BCalendar.spec.d.ts +1 -0
  350. package/dist/types/components/BCalendar/BCalendar.vue.d.ts +114 -0
  351. package/dist/types/components/BCalendar/index.d.ts +2 -0
  352. package/dist/types/components/BCalendar/types.d.ts +54 -0
  353. package/dist/types/components/BCarousel/BCarousel.spec.d.ts +1 -0
  354. package/dist/types/components/BCarousel/BCarousel.vue.d.ts +133 -0
  355. package/dist/types/components/BCarousel/index.d.ts +2 -0
  356. package/dist/types/components/BCarousel/types.d.ts +15 -0
  357. package/dist/types/components/BDivider/types.d.ts +2 -2
  358. package/dist/types/components/BMasonry/types.d.ts +2 -2
  359. package/dist/types/components/BPagination/BPagination.vue.d.ts +1 -1
  360. package/dist/types/components/BStatistic/BStatistic.spec.d.ts +1 -0
  361. package/dist/types/components/BStatistic/BStatistic.vue.d.ts +44 -0
  362. package/dist/types/components/BStatistic/BStatisticTimer.vue.d.ts +50 -0
  363. package/dist/types/components/BStatistic/index.d.ts +3 -0
  364. package/dist/types/components/BStatistic/types.d.ts +6 -0
  365. package/dist/types/components/BTreeSelect/BTreeSelect.spec.d.ts +1 -0
  366. package/dist/types/components/BTreeSelect/BTreeSelect.vue.d.ts +143 -0
  367. package/dist/types/components/BTreeSelect/index.d.ts +2 -0
  368. package/dist/types/components/BTreeSelect/types.d.ts +77 -0
  369. package/dist/types/components/index.d.ts +4 -0
  370. package/dist/types/types.d.ts +3 -0
  371. package/package.json +18 -15
  372. package/dist/design-system105.js +0 -212
  373. package/dist/design-system105.js.map +0 -1
  374. package/dist/design-system108.js +0 -227
  375. package/dist/design-system108.js.map +0 -1
  376. package/dist/design-system111.js +0 -166
  377. package/dist/design-system111.js.map +0 -1
  378. package/dist/design-system115.js +0 -277
  379. package/dist/design-system115.js.map +0 -1
  380. package/dist/design-system118.js +0 -19
  381. package/dist/design-system118.js.map +0 -1
  382. package/dist/design-system121.js +0 -15
  383. package/dist/design-system121.js.map +0 -1
  384. package/dist/design-system125.js +0 -45
  385. package/dist/design-system125.js.map +0 -1
  386. package/dist/design-system128.js +0 -236
  387. package/dist/design-system128.js.map +0 -1
  388. package/dist/design-system141.js +0 -40
  389. package/dist/design-system141.js.map +0 -1
  390. package/dist/design-system144.js +0 -7
  391. package/dist/design-system158.js +0 -61
  392. package/dist/design-system158.js.map +0 -1
  393. package/dist/design-system161.js +0 -59
  394. package/dist/design-system161.js.map +0 -1
  395. package/dist/design-system174.js +0 -465
  396. package/dist/design-system174.js.map +0 -1
  397. package/dist/design-system177.js +0 -38
  398. package/dist/design-system177.js.map +0 -1
  399. package/dist/design-system222.js +0 -7
  400. package/dist/design-system222.js.map +0 -1
  401. package/dist/design-system225.js +0 -8
  402. package/dist/design-system225.js.map +0 -1
  403. package/dist/design-system229.js +0 -115
  404. package/dist/design-system229.js.map +0 -1
  405. package/dist/design-system238.js.map +0 -1
  406. package/dist/design-system241.js.map +0 -1
  407. package/dist/design-system40.js +0 -479
  408. package/dist/design-system40.js.map +0 -1
  409. package/dist/design-system43.js +0 -6
  410. package/dist/design-system43.js.map +0 -1
  411. package/dist/design-system46.js +0 -9
  412. package/dist/design-system46.js.map +0 -1
  413. package/dist/design-system50.js +0 -67
  414. package/dist/design-system50.js.map +0 -1
  415. package/dist/design-system60.js.map +0 -1
  416. package/dist/design-system63.js +0 -8
  417. package/dist/design-system67.js +0 -32
  418. package/dist/design-system67.js.map +0 -1
  419. package/dist/design-system74.js +0 -8
  420. package/dist/design-system74.js.map +0 -1
  421. package/dist/design-system79.js +0 -60
  422. package/dist/design-system79.js.map +0 -1
  423. package/dist/design-system82.js +0 -14
  424. package/dist/design-system82.js.map +0 -1
  425. package/dist/design-system86.js +0 -69
  426. package/dist/design-system86.js.map +0 -1
  427. package/dist/design-system89.js +0 -91
  428. package/dist/design-system89.js.map +0 -1
  429. package/dist/design-system93.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"design-system66.js","names":[],"sources":["../src/components/BDescriptions/BDescriptions.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CSSProperties, VNode } from 'vue';\nimport { computed, Fragment, useSlots } from 'vue';\n\nimport type { BDescriptionsItem } from './types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n bordered = false,\n colon = true,\n column = 3,\n layout = 'horizontal',\n size = 'default',\n title,\n extra,\n items,\n labelStyle,\n contentStyle,\n} = defineProps<{\n /** Whether to show border around the list. @default false */\n bordered?: boolean;\n /** Whether to show colon after the label. @default true */\n colon?: boolean;\n /** Number of columns per row. @default 3 */\n column?: number;\n /** Layout direction of description items. @default 'horizontal' */\n layout?: 'horizontal' | 'vertical';\n /** Size of the component. @default 'default' */\n size?: 'default' | 'middle' | 'small';\n /** Title of the descriptions block */\n title?: string;\n /** Extra content in the top-right corner */\n extra?: string;\n /** Description items data (alternative to slot-based usage) */\n items?: BDescriptionsItem[];\n /** Default style for all labels */\n labelStyle?: CSSProperties;\n /** Default style for all content cells */\n contentStyle?: CSSProperties;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** BDescriptionsItem children */\n default?: (props: Record<string, never>) => unknown;\n /** Title area. Overrides the `title` prop */\n title?: (props: Record<string, never>) => unknown;\n /** Extra content area. Overrides the `extra` prop */\n extra?: (props: Record<string, never>) => unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst slots = useSlots();\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst hasHeader = computed(() => {\n return !!(title || slots.title || extra || slots.extra);\n});\n\nconst rootClasses = computed(() => [\n 'b-descriptions',\n {\n 'b-descriptions--bordered': bordered,\n 'b-descriptions--vertical': layout === 'vertical',\n 'b-descriptions--horizontal': layout === 'horizontal',\n 'b-descriptions--middle': size === 'middle',\n 'b-descriptions--small': size === 'small',\n 'b-descriptions--colon': colon,\n },\n]);\n\n/**\n * Collect items from the `items` prop or from slot children (BDescriptionsItem VNodes).\n * Each resolved item has: label, children, span, labelStyle, contentStyle, labelSlot, contentSlot.\n */\ninterface ResolvedItem {\n label?: string;\n children?: string;\n span: number;\n labelStyle?: CSSProperties;\n contentStyle?: CSSProperties;\n /** VNode array for the label slot (from BDescriptionsItem slot usage) */\n labelSlot?: VNode[];\n /** VNode array for the content slot (from BDescriptionsItem default slot) */\n contentSlot?: VNode[];\n}\n\nconst resolvedItems = computed<ResolvedItem[]>(() => {\n // If items prop is provided, use it directly\n if (items && items.length > 0) {\n return items.map((item) => ({\n label: item.label,\n children: item.children,\n span: item.span ?? 1,\n labelStyle: item.labelStyle,\n contentStyle: item.contentStyle,\n }));\n }\n\n // Otherwise, extract from default slot VNodes (BDescriptionsItem instances)\n const defaultSlot = slots.default?.();\n if (!defaultSlot) return [];\n\n const result: ResolvedItem[] = [];\n\n function extractItems(vnodes: VNode[]) {\n for (const vnode of vnodes) {\n // Handle fragments (v-for, template wrappers)\n if (vnode.type === Fragment) {\n if (Array.isArray(vnode.children)) {\n extractItems(vnode.children as VNode[]);\n }\n continue;\n }\n\n const props = (vnode.props || {}) as Record<string, unknown>;\n const children = vnode.children as Record<\n string,\n (...args: unknown[]) => VNode | VNode[]\n > | null;\n\n const rawLabel = children?.label?.();\n const rawContent = children?.default?.();\n\n result.push({\n label: props.label as string | undefined,\n span: (props.span as number) ?? 1,\n labelStyle: props.labelStyle as CSSProperties | undefined,\n contentStyle: props.contentStyle as CSSProperties | undefined,\n labelSlot: rawLabel ? (Array.isArray(rawLabel) ? rawLabel : [rawLabel]) : undefined,\n contentSlot: rawContent\n ? Array.isArray(rawContent)\n ? rawContent\n : [rawContent]\n : undefined,\n });\n }\n }\n\n extractItems(defaultSlot);\n return result;\n});\n\n/**\n * Organize items into rows based on the column count.\n * The last item in each row gets its span extended to fill the remaining columns.\n */\ninterface RowData {\n items: Array<ResolvedItem & { effectiveSpan: number }>;\n}\n\nconst rows = computed<RowData[]>(() => {\n const result: RowData[] = [];\n let currentRow: RowData = { items: [] };\n let colsUsed = 0;\n\n for (let i = 0; i < resolvedItems.value.length; i++) {\n const item = resolvedItems.value[i];\n const isLast = i === resolvedItems.value.length - 1;\n let span = Math.min(item.span, column);\n\n // If this item would exceed the row, start a new row\n if (colsUsed + span > column) {\n if (currentRow.items.length > 0) {\n // Fill remaining columns of the previous row\n const lastInRow = currentRow.items[currentRow.items.length - 1];\n lastInRow.effectiveSpan += column - colsUsed;\n result.push(currentRow);\n currentRow = { items: [] };\n colsUsed = 0;\n }\n }\n\n // If this is the last item, it takes up remaining space in the row\n if (isLast) {\n span = column - colsUsed;\n }\n\n currentRow.items.push({ ...item, effectiveSpan: span });\n colsUsed += span;\n\n if (colsUsed >= column) {\n result.push(currentRow);\n currentRow = { items: [] };\n colsUsed = 0;\n }\n }\n\n // Push any remaining items\n if (currentRow.items.length > 0) {\n const lastInRow = currentRow.items[currentRow.items.length - 1];\n lastInRow.effectiveSpan += column - colsUsed;\n result.push(currentRow);\n }\n\n return result;\n});\n\n/**\n * Merge global label/content styles with per-item styles.\n * Item-level styles override global styles.\n */\nfunction mergedLabelStyle(item: ResolvedItem): CSSProperties | undefined {\n if (!labelStyle && !item.labelStyle) return undefined;\n return { ...labelStyle, ...item.labelStyle };\n}\n\nfunction mergedContentStyle(item: ResolvedItem): CSSProperties | undefined {\n if (!contentStyle && !item.contentStyle) return undefined;\n return { ...contentStyle, ...item.contentStyle };\n}\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <!-- Header -->\n <div v-if=\"hasHeader\" class=\"b-descriptions__header\">\n <div v-if=\"title || $slots.title\" class=\"b-descriptions__title\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"extra || $slots.extra\" class=\"b-descriptions__extra\">\n <slot name=\"extra\">{{ extra }}</slot>\n </div>\n </div>\n\n <!-- Body -->\n <div class=\"b-descriptions__body\">\n <!-- Bordered: use a real <table> -->\n <table v-if=\"bordered\" class=\"b-descriptions__table\" role=\"presentation\">\n <tbody>\n <!-- Horizontal layout with border -->\n <template v-if=\"layout === 'horizontal'\">\n <tr v-for=\"(row, rowIndex) in rows\" :key=\"rowIndex\" class=\"b-descriptions__row\">\n <template v-for=\"(item, itemIndex) in row.items\" :key=\"itemIndex\">\n <th\n class=\"b-descriptions__item-label b-descriptions__item-label--bordered\"\n :style=\"mergedLabelStyle(item)\"\n >\n <component\n v-if=\"item.labelSlot && item.labelSlot.length\"\n :is=\"() => item.labelSlot\"\n />\n <template v-else>{{ item.label }}</template>\n </th>\n <td\n class=\"b-descriptions__item-content b-descriptions__item-content--bordered\"\n :colspan=\"item.effectiveSpan * 2 - 1\"\n :style=\"mergedContentStyle(item)\"\n >\n <component\n v-if=\"item.contentSlot && item.contentSlot.length\"\n :is=\"() => item.contentSlot\"\n />\n <template v-else>{{ item.children }}</template>\n </td>\n </template>\n </tr>\n </template>\n\n <!-- Vertical layout with border -->\n <template v-else>\n <template v-for=\"(row, rowIndex) in rows\" :key=\"rowIndex\">\n <tr class=\"b-descriptions__row\">\n <th\n v-for=\"(item, itemIndex) in row.items\"\n :key=\"'label-' + itemIndex\"\n class=\"b-descriptions__item-label b-descriptions__item-label--bordered\"\n :colspan=\"item.effectiveSpan\"\n :style=\"mergedLabelStyle(item)\"\n >\n <component\n v-if=\"item.labelSlot && item.labelSlot.length\"\n :is=\"() => item.labelSlot\"\n />\n <template v-else>{{ item.label }}</template>\n </th>\n </tr>\n <tr class=\"b-descriptions__row\">\n <td\n v-for=\"(item, itemIndex) in row.items\"\n :key=\"'content-' + itemIndex\"\n class=\"b-descriptions__item-content b-descriptions__item-content--bordered\"\n :colspan=\"item.effectiveSpan\"\n :style=\"mergedContentStyle(item)\"\n >\n <component\n v-if=\"item.contentSlot && item.contentSlot.length\"\n :is=\"() => item.contentSlot\"\n />\n <template v-else>{{ item.children }}</template>\n </td>\n </tr>\n </template>\n </template>\n </tbody>\n </table>\n\n <!-- Non-bordered: use a description list -->\n <table v-else class=\"b-descriptions__table\" role=\"presentation\">\n <tbody>\n <!-- Horizontal layout (default) -->\n <template v-if=\"layout === 'horizontal'\">\n <tr v-for=\"(row, rowIndex) in rows\" :key=\"rowIndex\" class=\"b-descriptions__row\">\n <td\n v-for=\"(item, itemIndex) in row.items\"\n :key=\"itemIndex\"\n class=\"b-descriptions__item\"\n :colspan=\"item.effectiveSpan\"\n >\n <span class=\"b-descriptions__item-label\" :style=\"mergedLabelStyle(item)\">\n <component\n v-if=\"item.labelSlot && item.labelSlot.length\"\n :is=\"() => item.labelSlot\"\n />\n <template v-else>{{ item.label }}</template>\n </span>\n <span class=\"b-descriptions__item-content\" :style=\"mergedContentStyle(item)\">\n <component\n v-if=\"item.contentSlot && item.contentSlot.length\"\n :is=\"() => item.contentSlot\"\n />\n <template v-else>{{ item.children }}</template>\n </span>\n </td>\n </tr>\n </template>\n\n <!-- Vertical layout -->\n <template v-else>\n <template v-for=\"(row, rowIndex) in rows\" :key=\"rowIndex\">\n <tr class=\"b-descriptions__row\">\n <td\n v-for=\"(item, itemIndex) in row.items\"\n :key=\"'label-' + itemIndex\"\n class=\"b-descriptions__item\"\n :colspan=\"item.effectiveSpan\"\n >\n <span class=\"b-descriptions__item-label\" :style=\"mergedLabelStyle(item)\">\n <component\n v-if=\"item.labelSlot && item.labelSlot.length\"\n :is=\"() => item.labelSlot\"\n />\n <template v-else>{{ item.label }}</template>\n </span>\n </td>\n </tr>\n <tr class=\"b-descriptions__row\">\n <td\n v-for=\"(item, itemIndex) in row.items\"\n :key=\"'content-' + itemIndex\"\n class=\"b-descriptions__item\"\n :colspan=\"item.effectiveSpan\"\n >\n <span class=\"b-descriptions__item-content\" :style=\"mergedContentStyle(item)\">\n <component\n v-if=\"item.contentSlot && item.contentSlot.length\"\n :is=\"() => item.contentSlot\"\n />\n <template v-else>{{ item.children }}</template>\n </span>\n </td>\n </tr>\n </template>\n </template>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BDescriptions - CSS custom properties (scoped to root)\n ───────────────────────────────────────────── */\n.b-descriptions {\n /* Surface */\n --b-descriptions-bg: oklch(100% 0 0);\n --b-descriptions-color: oklch(20% 0.02 260);\n --b-descriptions-border-color: oklch(88% 0.01 260);\n --b-descriptions-border-radius: 8px;\n --b-descriptions-transition-duration: 200ms;\n\n /* Title */\n --b-descriptions-title-color: oklch(20% 0.02 260);\n --b-descriptions-title-font-size: 16px;\n --b-descriptions-title-font-weight: 600;\n --b-descriptions-title-margin-bottom: 20px;\n\n /* Extra */\n --b-descriptions-extra-color: oklch(45% 0.02 260);\n --b-descriptions-extra-font-size: 14px;\n\n /* Label */\n --b-descriptions-label-color: oklch(40% 0.02 260);\n --b-descriptions-label-bg: oklch(97% 0.005 260);\n --b-descriptions-label-font-weight: 400;\n\n /* Content */\n --b-descriptions-content-color: oklch(20% 0.02 260);\n\n /* Item spacing */\n --b-descriptions-item-padding-bottom: 16px;\n --b-descriptions-item-padding-end: 16px;\n\n /* Colon */\n --b-descriptions-colon-margin-left: 2px;\n --b-descriptions-colon-margin-right: 8px;\n\n /* Bordered cell padding */\n --b-descriptions-cell-padding: 16px 24px;\n --b-descriptions-cell-padding-middle: 12px 20px;\n --b-descriptions-cell-padding-small: 8px 16px;\n\n /* Layout */\n color: var(--b-descriptions-color);\n font-size: 14px;\n line-height: 1.5715;\n box-sizing: border-box;\n}\n\n/* ── Header ── */\n.b-descriptions__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--b-descriptions-title-margin-bottom);\n gap: 16px;\n}\n\n.b-descriptions__title {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--b-descriptions-title-color);\n font-size: var(--b-descriptions-title-font-size);\n font-weight: var(--b-descriptions-title-font-weight);\n line-height: 1.5;\n}\n\n.b-descriptions__extra {\n flex: none;\n color: var(--b-descriptions-extra-color);\n font-size: var(--b-descriptions-extra-font-size);\n}\n\n/* ── Body ── */\n.b-descriptions__body {\n width: 100%;\n overflow: hidden;\n}\n\n/* ── Table ── */\n.b-descriptions__table {\n width: 100%;\n border-collapse: collapse;\n table-layout: auto;\n}\n\n/* ── Bordered table ── */\n.b-descriptions--bordered .b-descriptions__table {\n border: 1px solid var(--b-descriptions-border-color);\n border-radius: var(--b-descriptions-border-radius);\n overflow: hidden;\n}\n\n.b-descriptions--bordered .b-descriptions__row > th,\n.b-descriptions--bordered .b-descriptions__row > td {\n border-inline-end: 1px solid var(--b-descriptions-border-color);\n border-bottom: 1px solid var(--b-descriptions-border-color);\n}\n\n.b-descriptions--bordered .b-descriptions__row > th:last-child,\n.b-descriptions--bordered .b-descriptions__row > td:last-child {\n border-inline-end: none;\n}\n\n.b-descriptions--bordered .b-descriptions__row:last-child > th,\n.b-descriptions--bordered .b-descriptions__row:last-child > td {\n border-bottom: none;\n}\n\n.b-descriptions--bordered .b-descriptions__item-label--bordered {\n padding: var(--b-descriptions-cell-padding);\n background: var(--b-descriptions-label-bg);\n color: var(--b-descriptions-label-color);\n font-weight: var(--b-descriptions-label-font-weight);\n white-space: nowrap;\n}\n\n.b-descriptions--bordered .b-descriptions__item-content--bordered {\n padding: var(--b-descriptions-cell-padding);\n color: var(--b-descriptions-content-color);\n}\n\n/* ── Non-bordered items ── */\n.b-descriptions__item {\n padding-bottom: var(--b-descriptions-item-padding-bottom);\n vertical-align: top;\n}\n\n.b-descriptions__item .b-descriptions__item-label {\n color: var(--b-descriptions-label-color);\n font-weight: var(--b-descriptions-label-font-weight);\n display: inline-block;\n}\n\n.b-descriptions__item .b-descriptions__item-content {\n color: var(--b-descriptions-content-color);\n display: inline-block;\n}\n\n/* ── Colon ── */\n.b-descriptions--colon:not(.b-descriptions--vertical)\n .b-descriptions__item\n .b-descriptions__item-label::after {\n content: ':';\n position: relative;\n margin-inline-start: var(--b-descriptions-colon-margin-left);\n margin-inline-end: var(--b-descriptions-colon-margin-right);\n}\n\n.b-descriptions--colon.b-descriptions--bordered .b-descriptions__item-label--bordered::after {\n content: none;\n}\n\n/* ── Vertical layout ── */\n.b-descriptions--vertical .b-descriptions__item .b-descriptions__item-label {\n display: block;\n padding-bottom: 4px;\n}\n\n.b-descriptions--vertical .b-descriptions__item .b-descriptions__item-content {\n display: block;\n}\n\n/* ── Size: middle ── */\n.b-descriptions--middle .b-descriptions__item {\n padding-bottom: 12px;\n}\n\n.b-descriptions--middle.b-descriptions--bordered .b-descriptions__item-label--bordered,\n.b-descriptions--middle.b-descriptions--bordered .b-descriptions__item-content--bordered {\n padding: var(--b-descriptions-cell-padding-middle);\n}\n\n/* ── Size: small ── */\n.b-descriptions--small .b-descriptions__item {\n padding-bottom: 8px;\n}\n\n.b-descriptions--small.b-descriptions--bordered .b-descriptions__item-label--bordered,\n.b-descriptions--small.b-descriptions--bordered .b-descriptions__item-content--bordered {\n padding: var(--b-descriptions-cell-padding-small);\n}\n\n.b-descriptions--small .b-descriptions__title {\n font-size: 14px;\n}\n\n.b-descriptions--middle .b-descriptions__title {\n font-size: 15px;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-descriptions {\n --b-descriptions-bg: oklch(20% 0.02 260);\n --b-descriptions-color: oklch(88% 0.01 260);\n --b-descriptions-border-color: oklch(35% 0.02 260);\n --b-descriptions-title-color: oklch(92% 0.01 260);\n --b-descriptions-extra-color: oklch(65% 0.01 260);\n --b-descriptions-label-color: oklch(65% 0.01 260);\n --b-descriptions-label-bg: oklch(25% 0.02 260);\n --b-descriptions-content-color: oklch(88% 0.01 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-descriptions {\n --b-descriptions-bg: oklch(20% 0.02 260);\n --b-descriptions-color: oklch(88% 0.01 260);\n --b-descriptions-border-color: oklch(35% 0.02 260);\n --b-descriptions-title-color: oklch(92% 0.01 260);\n --b-descriptions-extra-color: oklch(65% 0.01 260);\n --b-descriptions-label-color: oklch(65% 0.01 260);\n --b-descriptions-label-bg: oklch(25% 0.02 260);\n --b-descriptions-content-color: oklch(88% 0.01 260);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-descriptions {\n --b-descriptions-transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"design-system66.js","names":[],"sources":["../src/components/BColorPicker/BColorPicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from 'vue';\nimport {\n BColorPickerFormat,\n BColorPickerPlacement,\n BColorPickerSize,\n BColorPickerTrigger,\n type BColorHsb,\n type BColorHsl,\n type BColorPickerPreset,\n type BColorRgb,\n} from './types';\n\n// ─────────────────────────────────────────────\n// Props & emits\n// ─────────────────────────────────────────────\nconst {\n modelValue = undefined,\n defaultValue = '#1677ff',\n disabled = false,\n open = undefined,\n trigger = BColorPickerTrigger.Click,\n size = BColorPickerSize.Medium,\n placement = BColorPickerPlacement.BottomLeft,\n format = undefined,\n defaultFormat = BColorPickerFormat.Hex,\n disabledAlpha = false,\n disabledFormat = false,\n showText = false,\n presets = undefined,\n allowClear = false,\n destroyOnHidden = false,\n arrow = true,\n} = defineProps<{\n /** Current color value (v-model). Accepts hex, rgb, hsl strings. */\n modelValue?: string;\n /** Default color when uncontrolled. */\n defaultValue?: string;\n /** Whether the color picker is disabled. */\n disabled?: boolean;\n /** Controlled open state of the popup (v-model:open). */\n open?: boolean;\n /** How the popup is triggered. */\n trigger?: `${BColorPickerTrigger}`;\n /** Size of the trigger button. */\n size?: `${BColorPickerSize}`;\n /** Placement of the popup relative to the trigger. */\n placement?: `${BColorPickerPlacement}`;\n /** Controlled color format. */\n format?: `${BColorPickerFormat}`;\n /** Default color format when uncontrolled. */\n defaultFormat?: `${BColorPickerFormat}`;\n /** Whether to disable the alpha slider. */\n disabledAlpha?: boolean;\n /** Whether to disable format switching. */\n disabledFormat?: boolean;\n /** Whether to show the color text value next to the swatch. */\n showText?: boolean | ((color: string) => string);\n /** Preset color groups. */\n presets?: BColorPickerPreset[];\n /** Whether to allow clearing the color. */\n allowClear?: boolean;\n /** Destroy popup DOM when closed. */\n destroyOnHidden?: boolean;\n /** Whether the popup has an arrow. */\n arrow?: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void;\n (e: 'update:open', value: boolean): void;\n (e: 'change', value: string, css: string): void;\n (e: 'changeComplete', value: string): void;\n (e: 'formatChange', format: `${BColorPickerFormat}`): void;\n (e: 'clear'): void;\n (e: 'openChange', open: boolean): void;\n}>();\n\ndefineSlots<{\n /** Custom trigger element. */\n default?(): unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Color conversion utilities\n// ─────────────────────────────────────────────\n\nfunction hexToRgb(hex: string): BColorRgb {\n let h = hex.replace('#', '');\n let a = 1;\n if (h.length === 4) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n } else if (h.length === 8) {\n a = parseInt(h.slice(6, 8), 16) / 255;\n h = h.slice(0, 6);\n }\n const num = parseInt(h, 16);\n return { r: (num >> 16) & 255, g: (num >> 8) & 255, b: num & 255, a };\n}\n\nfunction rgbToHex(rgb: BColorRgb): string {\n const toHex = (n: number) =>\n Math.round(Math.max(0, Math.min(255, n)))\n .toString(16)\n .padStart(2, '0');\n const hex = `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;\n if (rgb.a < 1) {\n return hex + toHex(Math.round(rgb.a * 255));\n }\n return hex;\n}\n\nfunction rgbToHsb(rgb: BColorRgb): BColorHsb {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n let h = 0;\n const s = max === 0 ? 0 : d / max;\n const v = max;\n if (d !== 0) {\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n return { h: h * 360, s: s * 100, b: v * 100, a: rgb.a };\n}\n\nfunction hsbToRgb(hsb: BColorHsb): BColorRgb {\n const h = hsb.h / 360;\n const s = hsb.s / 100;\n const v = hsb.b / 100;\n let r = 0,\n g = 0,\n b = 0;\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n switch (i % 6) {\n case 0:\n r = v;\n g = t;\n b = p;\n break;\n case 1:\n r = q;\n g = v;\n b = p;\n break;\n case 2:\n r = p;\n g = v;\n b = t;\n break;\n case 3:\n r = p;\n g = q;\n b = v;\n break;\n case 4:\n r = t;\n g = p;\n b = v;\n break;\n case 5:\n r = v;\n g = p;\n b = q;\n break;\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: hsb.a,\n };\n}\n\nfunction rgbToHsl(rgb: BColorRgb): BColorHsl {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100), a: rgb.a };\n}\n\nfunction hslToRgb(hsl: BColorHsl): BColorRgb {\n const h = hsl.h / 360;\n const s = hsl.s / 100;\n const l = hsl.l / 100;\n let r: number, g: number, b: number;\n if (s === 0) {\n r = g = b = l;\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q2 = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p2 = 2 * l - q2;\n r = hue2rgb(p2, q2, h + 1 / 3);\n g = hue2rgb(p2, q2, h);\n b = hue2rgb(p2, q2, h - 1 / 3);\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: hsl.a,\n };\n}\n\nfunction parseColor(input: string): BColorHsb {\n const s = input.trim().toLowerCase();\n\n // HSL string\n const hslMatch = s.match(/hsla?\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (hslMatch) {\n const hsl: BColorHsl = {\n h: parseInt(hslMatch[1]),\n s: parseInt(hslMatch[2]),\n l: parseInt(hslMatch[3]),\n a: hslMatch[4] !== undefined ? parseFloat(hslMatch[4]) : 1,\n };\n return rgbToHsb(hslToRgb(hsl));\n }\n\n // RGB string\n const rgbMatch = s.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (rgbMatch) {\n const rgb: BColorRgb = {\n r: parseInt(rgbMatch[1]),\n g: parseInt(rgbMatch[2]),\n b: parseInt(rgbMatch[3]),\n a: rgbMatch[4] !== undefined ? parseFloat(rgbMatch[4]) : 1,\n };\n return rgbToHsb(rgb);\n }\n\n // HSB string\n const hsbMatch = s.match(/hsb\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (hsbMatch) {\n return {\n h: parseInt(hsbMatch[1]),\n s: parseInt(hsbMatch[2]),\n b: parseInt(hsbMatch[3]),\n a: hsbMatch[4] !== undefined ? parseFloat(hsbMatch[4]) : 1,\n };\n }\n\n // Hex (default)\n return rgbToHsb(hexToRgb(s));\n}\n\nfunction hsbToString(hsb: BColorHsb, fmt: `${BColorPickerFormat}`): string {\n const rgb = hsbToRgb(hsb);\n switch (fmt) {\n case BColorPickerFormat.Hex:\n return rgbToHex(rgb);\n case BColorPickerFormat.Rgb:\n return rgb.a < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${roundTo(rgb.a, 2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n case BColorPickerFormat.Hsl: {\n const hsl = rgbToHsl(rgb);\n return hsl.a < 1\n ? `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${roundTo(hsl.a, 2)})`\n : `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;\n }\n case BColorPickerFormat.Hsb:\n return hsb.a < 1\n ? `hsb(${Math.round(hsb.h)}, ${Math.round(hsb.s)}%, ${Math.round(hsb.b)}%, ${roundTo(hsb.a, 2)})`\n : `hsb(${Math.round(hsb.h)}, ${Math.round(hsb.s)}%, ${Math.round(hsb.b)}%)`;\n default:\n return rgbToHex(rgb);\n }\n}\n\nfunction roundTo(n: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.round(n * factor) / factor;\n}\n\nfunction hsbToCssColor(hsb: BColorHsb): string {\n const rgb = hsbToRgb(hsb);\n return rgb.a < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${roundTo(rgb.a, 2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n}\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst panelId = useId();\n\nconst initialColor = parseColor(modelValue ?? defaultValue);\nconst internalHsb = ref<BColorHsb>({ ...initialColor });\nconst internalFormat = ref<`${BColorPickerFormat}`>(format ?? defaultFormat);\nconst internalOpen = ref(false);\nconst cleared = ref(false);\nconst hasBeenOpened = ref(false);\n\nconst isOpen = computed(() => (open !== undefined ? open : internalOpen.value));\nconst shouldRender = computed(() => {\n if (destroyOnHidden) return isOpen.value;\n return hasBeenOpened.value || isOpen.value;\n});\n\nconst activeFormat = computed(() => format ?? internalFormat.value);\n\nconst colorString = computed(() => hsbToString(internalHsb.value, activeFormat.value));\nconst cssColor = computed(() => hsbToCssColor(internalHsb.value));\n\nconst displayText = computed(() => {\n if (!showText) return '';\n if (typeof showText === 'function') return showText(colorString.value);\n return colorString.value;\n});\n\nwatch(isOpen, (val) => {\n if (val) hasBeenOpened.value = true;\n});\n\nwatch(\n () => modelValue,\n (val) => {\n if (val !== undefined) {\n const parsed = parseColor(val);\n internalHsb.value = parsed;\n cleared.value = false;\n }\n },\n);\n\nwatch(\n () => format,\n (val) => {\n if (val) internalFormat.value = val;\n },\n);\n\n// ─────────────────────────────────────────────\n// Visibility control\n// ─────────────────────────────────────────────\nconst triggerRef = ref<HTMLDivElement | null>(null);\nconst panelRef = ref<HTMLDivElement | null>(null);\n\nlet hoverTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction setOpen(val: boolean) {\n if (disabled) return;\n if (open !== undefined) {\n emit('update:open', val);\n } else {\n internalOpen.value = val;\n }\n emit('openChange', val);\n}\n\nfunction toggleOpen() {\n setOpen(!isOpen.value);\n}\n\nfunction onTriggerClick() {\n if (trigger === BColorPickerTrigger.Click) toggleOpen();\n}\n\nfunction onTriggerMouseEnter() {\n if (trigger === BColorPickerTrigger.Hover) {\n if (hoverTimer) clearTimeout(hoverTimer);\n setOpen(true);\n }\n}\n\nfunction onTriggerMouseLeave() {\n if (trigger === BColorPickerTrigger.Hover) {\n hoverTimer = setTimeout(() => setOpen(false), 150);\n }\n}\n\nfunction onPanelMouseEnter() {\n if (trigger === BColorPickerTrigger.Hover && hoverTimer) {\n clearTimeout(hoverTimer);\n }\n}\n\nfunction onPanelMouseLeave() {\n if (trigger === BColorPickerTrigger.Hover) {\n hoverTimer = setTimeout(() => setOpen(false), 150);\n }\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && isOpen.value) {\n event.preventDefault();\n setOpen(false);\n triggerRef.value?.focus();\n }\n if ((event.key === 'Enter' || event.key === ' ') && !isOpen.value) {\n event.preventDefault();\n setOpen(true);\n }\n}\n\n// Close on outside click\nfunction onDocumentClick(event: MouseEvent) {\n if (!isOpen.value) return;\n const target = event.target as Node;\n if (triggerRef.value?.contains(target) || panelRef.value?.contains(target)) {\n return;\n }\n setOpen(false);\n}\n\nonMounted(() => {\n document.addEventListener('mousedown', onDocumentClick);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', onDocumentClick);\n if (hoverTimer) clearTimeout(hoverTimer);\n});\n\n// Sync controlled open → popover\nwatch(\n () => open,\n (val) => {\n if (val === undefined) return;\n internalOpen.value = val;\n },\n);\n\n// Focus management\nlet previouslyFocusedElement: HTMLElement | null = null;\n\nwatch(isOpen, (val) => {\n if (val) {\n previouslyFocusedElement = document.activeElement as HTMLElement | null;\n nextTick(() => {\n panelRef.value?.focus();\n });\n } else {\n nextTick(() => previouslyFocusedElement?.focus());\n }\n});\n\n// ─────────────────────────────────────────────\n// Saturation panel interaction\n// ─────────────────────────────────────────────\nconst saturationRef = ref<HTMLDivElement | null>(null);\nlet isDraggingSat = false;\n\nfunction updateSaturationFromEvent(event: MouseEvent | TouchEvent) {\n if (!saturationRef.value) return;\n const rect = saturationRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const clientY = 'touches' in event ? event.touches[0].clientY : event.clientY;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const y = Math.max(0, Math.min(1, (clientY - rect.top) / rect.height));\n internalHsb.value = {\n ...internalHsb.value,\n s: x * 100,\n b: (1 - y) * 100,\n };\n emitChange();\n}\n\nfunction onSaturationMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingSat = true;\n updateSaturationFromEvent(event);\n document.addEventListener('mousemove', onSaturationMouseMove);\n document.addEventListener('mouseup', onSaturationMouseUp);\n}\n\nfunction onSaturationMouseMove(event: MouseEvent) {\n if (!isDraggingSat) return;\n updateSaturationFromEvent(event);\n}\n\nfunction onSaturationMouseUp() {\n isDraggingSat = false;\n document.removeEventListener('mousemove', onSaturationMouseMove);\n document.removeEventListener('mouseup', onSaturationMouseUp);\n emitChangeComplete();\n}\n\nfunction onSaturationTouchStart(event: TouchEvent) {\n event.preventDefault();\n isDraggingSat = true;\n updateSaturationFromEvent(event);\n document.addEventListener('touchmove', onSaturationTouchMove);\n document.addEventListener('touchend', onSaturationTouchEnd);\n}\n\nfunction onSaturationTouchMove(event: TouchEvent) {\n if (!isDraggingSat) return;\n updateSaturationFromEvent(event);\n}\n\nfunction onSaturationTouchEnd() {\n isDraggingSat = false;\n document.removeEventListener('touchmove', onSaturationTouchMove);\n document.removeEventListener('touchend', onSaturationTouchEnd);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Hue slider interaction\n// ─────────────────────────────────────────────\nconst hueRef = ref<HTMLDivElement | null>(null);\nlet isDraggingHue = false;\n\nfunction updateHueFromEvent(event: MouseEvent | TouchEvent) {\n if (!hueRef.value) return;\n const rect = hueRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n internalHsb.value = { ...internalHsb.value, h: x * 360 };\n emitChange();\n}\n\nfunction onHueMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingHue = true;\n updateHueFromEvent(event);\n document.addEventListener('mousemove', onHueMouseMove);\n document.addEventListener('mouseup', onHueMouseUp);\n}\n\nfunction onHueMouseMove(event: MouseEvent) {\n if (!isDraggingHue) return;\n updateHueFromEvent(event);\n}\n\nfunction onHueMouseUp() {\n isDraggingHue = false;\n document.removeEventListener('mousemove', onHueMouseMove);\n document.removeEventListener('mouseup', onHueMouseUp);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Alpha slider interaction\n// ─────────────────────────────────────────────\nconst alphaRef = ref<HTMLDivElement | null>(null);\nlet isDraggingAlpha = false;\n\nfunction updateAlphaFromEvent(event: MouseEvent | TouchEvent) {\n if (!alphaRef.value) return;\n const rect = alphaRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n internalHsb.value = { ...internalHsb.value, a: roundTo(x, 2) };\n emitChange();\n}\n\nfunction onAlphaMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingAlpha = true;\n updateAlphaFromEvent(event);\n document.addEventListener('mousemove', onAlphaMouseMove);\n document.addEventListener('mouseup', onAlphaMouseUp);\n}\n\nfunction onAlphaMouseMove(event: MouseEvent) {\n if (!isDraggingAlpha) return;\n updateAlphaFromEvent(event);\n}\n\nfunction onAlphaMouseUp() {\n isDraggingAlpha = false;\n document.removeEventListener('mousemove', onAlphaMouseMove);\n document.removeEventListener('mouseup', onAlphaMouseUp);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Format switching\n// ─────────────────────────────────────────────\nconst formatOrder: `${BColorPickerFormat}`[] = [\n BColorPickerFormat.Hex,\n BColorPickerFormat.Hsb,\n BColorPickerFormat.Rgb,\n BColorPickerFormat.Hsl,\n];\n\nfunction cycleFormat() {\n if (disabledFormat) return;\n const idx = formatOrder.indexOf(activeFormat.value);\n const next = formatOrder[(idx + 1) % formatOrder.length];\n if (format === undefined) {\n internalFormat.value = next;\n }\n emit('formatChange', next);\n}\n\n// ─────────────────────────────────────────────\n// Input handling\n// ─────────────────────────────────────────────\nconst inputValue = computed(() => {\n switch (activeFormat.value) {\n case BColorPickerFormat.Hex:\n return rgbToHex(hsbToRgb(internalHsb.value)).replace('#', '');\n case BColorPickerFormat.Rgb: {\n const rgb = hsbToRgb(internalHsb.value);\n return `${rgb.r}, ${rgb.g}, ${rgb.b}`;\n }\n case BColorPickerFormat.Hsl: {\n const hsl = rgbToHsl(hsbToRgb(internalHsb.value));\n return `${hsl.h}, ${hsl.s}%, ${hsl.l}%`;\n }\n case BColorPickerFormat.Hsb:\n return `${Math.round(internalHsb.value.h)}, ${Math.round(internalHsb.value.s)}%, ${Math.round(internalHsb.value.b)}%`;\n default:\n return '';\n }\n});\n\nconst alphaPercent = computed(() => Math.round(internalHsb.value.a * 100));\n\nfunction onInputChange(event: Event) {\n const val = (event.target as HTMLInputElement).value.trim();\n try {\n let parsed: BColorHsb;\n switch (activeFormat.value) {\n case BColorPickerFormat.Hex:\n parsed = parseColor('#' + val);\n break;\n case BColorPickerFormat.Rgb: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = rgbToHsb({ r: parts[0], g: parts[1], b: parts[2], a: internalHsb.value.a });\n } else return;\n break;\n }\n case BColorPickerFormat.Hsl: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = rgbToHsb(\n hslToRgb({ h: parts[0], s: parts[1], l: parts[2], a: internalHsb.value.a }),\n );\n } else return;\n break;\n }\n case BColorPickerFormat.Hsb: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = { h: parts[0], s: parts[1], b: parts[2], a: internalHsb.value.a };\n } else return;\n break;\n }\n default:\n return;\n }\n internalHsb.value = parsed;\n emitChange();\n emitChangeComplete();\n } catch {\n // Invalid input, ignore\n }\n}\n\nfunction onAlphaInputChange(event: Event) {\n const val = parseInt((event.target as HTMLInputElement).value);\n if (!isNaN(val)) {\n internalHsb.value = { ...internalHsb.value, a: Math.max(0, Math.min(100, val)) / 100 };\n emitChange();\n emitChangeComplete();\n }\n}\n\n// ─────────────────────────────────────────────\n// Preset selection\n// ─────────────────────────────────────────────\nfunction selectPreset(color: string) {\n internalHsb.value = parseColor(color);\n cleared.value = false;\n emitChange();\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Clear\n// ─────────────────────────────────────────────\nfunction onClear() {\n cleared.value = true;\n emit('clear');\n}\n\n// ─────────────────────────────────────────────\n// Emit helpers\n// ─────────────────────────────────────────────\nfunction emitChange() {\n cleared.value = false;\n const str = hsbToString(internalHsb.value, activeFormat.value);\n const css = hsbToCssColor(internalHsb.value);\n emit('update:modelValue', str);\n emit('change', str, css);\n}\n\nfunction emitChangeComplete() {\n const str = hsbToString(internalHsb.value, activeFormat.value);\n emit('changeComplete', str);\n}\n\n// ─────────────────────────────────────────────\n// Computed styles\n// ─────────────────────────────────────────────\nconst anchorName = computed(() => `--b-color-picker-anchor-${componentUID.value}`);\n\nconst saturationStyle = computed(() => ({\n backgroundColor: `hsl(${internalHsb.value.h}, 100%, 50%)`,\n}));\n\nconst saturationHandleStyle = computed(() => ({\n left: `${internalHsb.value.s}%`,\n top: `${100 - internalHsb.value.b}%`,\n}));\n\nconst hueHandleStyle = computed(() => ({\n left: `${(internalHsb.value.h / 360) * 100}%`,\n}));\n\nconst alphaHandleStyle = computed(() => ({\n left: `${internalHsb.value.a * 100}%`,\n}));\n\nconst alphaGradient = computed(() => {\n const rgb = hsbToRgb({ ...internalHsb.value, a: 1 });\n return `linear-gradient(to right, rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0), rgb(${rgb.r}, ${rgb.g}, ${rgb.b}))`;\n});\n\nconst sizeClass = computed(() => {\n switch (size) {\n case BColorPickerSize.Small:\n return 'b-color-picker--sm';\n case BColorPickerSize.Large:\n return 'b-color-picker--lg';\n default:\n return 'b-color-picker--md';\n }\n});\n\n// ─────────────────────────────────────────────\n// Panel keyboard nav\n// ─────────────────────────────────────────────\nfunction onPanelKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.value?.focus();\n }\n}\n\n// ─────────────────────────────────────────────\n// Public API\n// ─────────────────────────────────────────────\ndefineExpose({ open: () => setOpen(true), close: () => setOpen(false) });\n</script>\n\n<template>\n <div class=\"b-color-picker\" :class=\"[sizeClass, { 'b-color-picker--disabled': disabled }]\">\n <!-- Trigger -->\n <div\n ref=\"triggerRef\"\n class=\"b-color-picker__trigger\"\n :style=\"{ anchorName }\"\n role=\"button\"\n :tabindex=\"disabled ? -1 : 0\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? panelId : undefined\"\n :aria-disabled=\"disabled\"\n :aria-label=\"`Color picker: ${colorString}`\"\n aria-haspopup=\"dialog\"\n @click=\"onTriggerClick\"\n @mouseenter=\"onTriggerMouseEnter\"\n @mouseleave=\"onTriggerMouseLeave\"\n @keydown=\"onKeydown\"\n >\n <slot>\n <div class=\"b-color-picker__swatch-wrapper\">\n <div\n class=\"b-color-picker__swatch\"\n :class=\"{ 'b-color-picker__swatch--cleared': cleared && allowClear }\"\n :style=\"{ backgroundColor: cleared ? 'transparent' : cssColor }\"\n />\n </div>\n <span v-if=\"showText\" class=\"b-color-picker__text\">\n {{ displayText }}\n </span>\n </slot>\n </div>\n\n <!-- Panel (popup) -->\n <div\n v-if=\"shouldRender\"\n ref=\"panelRef\"\n :id=\"panelId\"\n class=\"b-color-picker__panel\"\n :class=\"[\n `b-color-picker__panel--${placement}`,\n { 'b-color-picker__panel--open': isOpen, 'b-color-picker__panel--no-arrow': !arrow },\n ]\"\n :style=\"{ positionAnchor: anchorName }\"\n role=\"dialog\"\n :aria-label=\"'Color picker'\"\n tabindex=\"-1\"\n @mouseenter=\"onPanelMouseEnter\"\n @mouseleave=\"onPanelMouseLeave\"\n @keydown=\"onPanelKeydown\"\n >\n <!-- Arrow -->\n <div v-if=\"arrow\" class=\"b-color-picker__arrow\" aria-hidden=\"true\" />\n\n <!-- Saturation panel -->\n <div\n ref=\"saturationRef\"\n class=\"b-color-picker__saturation\"\n :style=\"saturationStyle\"\n role=\"slider\"\n aria-label=\"Color saturation and brightness\"\n :aria-valuetext=\"`Saturation ${Math.round(internalHsb.s)}%, Brightness ${Math.round(internalHsb.b)}%`\"\n tabindex=\"0\"\n @mousedown=\"onSaturationMouseDown\"\n @touchstart.passive=\"onSaturationTouchStart\"\n >\n <div class=\"b-color-picker__saturation-white\" />\n <div class=\"b-color-picker__saturation-black\" />\n <div class=\"b-color-picker__saturation-handle\" :style=\"saturationHandleStyle\" />\n </div>\n\n <!-- Sliders + preview row -->\n <div class=\"b-color-picker__controls\">\n <div class=\"b-color-picker__preview\">\n <div class=\"b-color-picker__preview-color\" :style=\"{ backgroundColor: cssColor }\" />\n </div>\n\n <div class=\"b-color-picker__sliders\">\n <!-- Hue slider -->\n <div\n ref=\"hueRef\"\n class=\"b-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Hue\"\n :aria-valuenow=\"Math.round(internalHsb.h)\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n tabindex=\"0\"\n @mousedown=\"onHueMouseDown\"\n >\n <div class=\"b-color-picker__hue-handle\" :style=\"hueHandleStyle\" />\n </div>\n\n <!-- Alpha slider -->\n <div\n v-if=\"!disabledAlpha\"\n ref=\"alphaRef\"\n class=\"b-color-picker__alpha\"\n :style=\"{ '--b-color-picker-alpha-gradient': alphaGradient }\"\n role=\"slider\"\n aria-label=\"Opacity\"\n :aria-valuenow=\"alphaPercent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n tabindex=\"0\"\n @mousedown=\"onAlphaMouseDown\"\n >\n <div class=\"b-color-picker__alpha-handle\" :style=\"alphaHandleStyle\" />\n </div>\n </div>\n </div>\n\n <!-- Input row -->\n <div class=\"b-color-picker__input-row\">\n <button\n v-if=\"!disabledFormat\"\n class=\"b-color-picker__format-btn\"\n type=\"button\"\n aria-label=\"Switch color format\"\n @click=\"cycleFormat\"\n >\n {{ activeFormat.toUpperCase() }}\n </button>\n <span v-else class=\"b-color-picker__format-label\">\n {{ activeFormat.toUpperCase() }}\n </span>\n\n <input\n class=\"b-color-picker__input\"\n type=\"text\"\n :value=\"inputValue\"\n aria-label=\"Color value\"\n @change=\"onInputChange\"\n />\n\n <input\n v-if=\"!disabledAlpha\"\n class=\"b-color-picker__alpha-input\"\n type=\"text\"\n :value=\"`${alphaPercent}%`\"\n aria-label=\"Alpha percentage\"\n @change=\"onAlphaInputChange\"\n />\n </div>\n\n <!-- Presets -->\n <div v-if=\"presets && presets.length\" class=\"b-color-picker__presets\">\n <div v-for=\"preset in presets\" :key=\"preset.label\" class=\"b-color-picker__preset-group\">\n <div class=\"b-color-picker__preset-label\">{{ preset.label }}</div>\n <div class=\"b-color-picker__preset-colors\">\n <button\n v-for=\"color in preset.colors\"\n :key=\"color\"\n type=\"button\"\n class=\"b-color-picker__preset-color\"\n :style=\"{ backgroundColor: color }\"\n :aria-label=\"`Select color ${color}`\"\n @click=\"selectPreset(color)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Clear button -->\n <div v-if=\"allowClear\" class=\"b-color-picker__clear-row\">\n <button\n type=\"button\"\n class=\"b-color-picker__clear-btn\"\n aria-label=\"Clear color\"\n @click=\"onClear\"\n >\n Clear\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n/* ────────────────────────────────────────────\n CSS Custom Properties (Design Tokens)\n ──────────────────────────────────────────── */\n.b-color-picker {\n --b-color-picker-width: 234px;\n --b-color-picker-handler-size: 16px;\n --b-color-picker-handler-size-sm: 12px;\n --b-color-picker-slider-height: 8px;\n --b-color-picker-preview-size: 28px;\n --b-color-picker-alpha-input-width: 44px;\n --b-color-picker-border-width: 1px;\n --b-color-picker-border-radius: 6px;\n --b-color-picker-border-radius-sm: 4px;\n --b-color-picker-font-size: 14px;\n --b-color-picker-line-height: 1.5714;\n --b-color-picker-bg: #ffffff;\n --b-color-picker-border-color: #d9d9d9;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-color-picker-trigger-height: 32px;\n --b-color-picker-trigger-height-sm: 24px;\n --b-color-picker-trigger-height-lg: 40px;\n --b-color-picker-swatch-size: 16px;\n --b-color-picker-swatch-size-sm: 12px;\n --b-color-picker-swatch-size-lg: 20px;\n --b-color-picker-panel-padding: 12px;\n --b-color-picker-saturation-height: 160px;\n --b-color-picker-color-block-border-radius: 4px;\n --b-color-picker-input-bg: #ffffff;\n --b-color-picker-input-border: #d9d9d9;\n --b-color-picker-text-color: rgba(0, 0, 0, 0.88);\n --b-color-picker-text-color-secondary: rgba(0, 0, 0, 0.65);\n --b-color-picker-gap: 8px;\n --b-color-picker-transition-duration: 200ms;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-color-picker {\n --b-color-picker-bg: #1f1f1f;\n --b-color-picker-border-color: #424242;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.24), 0 3px 6px -4px rgba(0, 0, 0, 0.36),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-color-picker-input-bg: #141414;\n --b-color-picker-input-border: #424242;\n --b-color-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-color-picker-text-color-secondary: rgba(255, 255, 255, 0.65);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-color-picker {\n --b-color-picker-bg: #1f1f1f;\n --b-color-picker-border-color: #424242;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.24), 0 3px 6px -4px rgba(0, 0, 0, 0.36),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-color-picker-input-bg: #141414;\n --b-color-picker-input-border: #424242;\n --b-color-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-color-picker-text-color-secondary: rgba(255, 255, 255, 0.65);\n }\n}\n\n/* ────────────────────────────────────────────\n Root\n ──────────────────────────────────────────── */\n.b-color-picker {\n display: inline-flex;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: var(--b-color-picker-font-size);\n line-height: var(--b-color-picker-line-height);\n}\n\n.b-color-picker--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.b-color-picker--disabled .b-color-picker__trigger {\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Trigger\n ──────────────────────────────────────────── */\n.b-color-picker__trigger {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: var(--b-color-picker-trigger-height);\n padding: 3px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-border-color);\n border-radius: var(--b-color-picker-border-radius);\n cursor: pointer;\n background: var(--b-color-picker-bg);\n transition: border-color var(--b-color-picker-transition-duration);\n outline: none;\n}\n\n.b-color-picker__trigger:hover:not([aria-disabled='true']) {\n border-color: #4096ff;\n}\n\n.b-color-picker__trigger:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n.b-color-picker--sm .b-color-picker__trigger {\n height: var(--b-color-picker-trigger-height-sm);\n padding: 2px;\n}\n\n.b-color-picker--lg .b-color-picker__trigger {\n height: var(--b-color-picker-trigger-height-lg);\n padding: 4px;\n}\n\n.b-color-picker__swatch-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: calc(var(--b-color-picker-trigger-height) - 8px);\n height: calc(var(--b-color-picker-trigger-height) - 8px);\n border-radius: var(--b-color-picker-border-radius-sm);\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n}\n\n.b-color-picker--sm .b-color-picker__swatch-wrapper {\n width: calc(var(--b-color-picker-trigger-height-sm) - 6px);\n height: calc(var(--b-color-picker-trigger-height-sm) - 6px);\n}\n\n.b-color-picker--lg .b-color-picker__swatch-wrapper {\n width: calc(var(--b-color-picker-trigger-height-lg) - 10px);\n height: calc(var(--b-color-picker-trigger-height-lg) - 10px);\n}\n\n.b-color-picker__swatch {\n width: 100%;\n height: 100%;\n border-radius: var(--b-color-picker-border-radius-sm);\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.25);\n}\n\n.b-color-picker__swatch--cleared {\n background: linear-gradient(135deg, transparent 45%, #ff4d4f 45%, #ff4d4f 55%, transparent 55%)\n center/100% 100%;\n}\n\n.b-color-picker__text {\n padding-right: 4px;\n color: var(--b-color-picker-text-color);\n font-size: var(--b-color-picker-font-size);\n user-select: none;\n}\n\n/* ────────────────────────────────────────────\n Panel\n ──────────────────────────────────────────── */\n.b-color-picker__panel {\n position: absolute;\n z-index: 1050;\n width: var(--b-color-picker-width);\n padding: var(--b-color-picker-panel-padding);\n background: var(--b-color-picker-bg);\n border-radius: var(--b-color-picker-border-radius);\n box-shadow: var(--b-color-picker-shadow);\n opacity: 0;\n visibility: hidden;\n transition:\n opacity var(--b-color-picker-transition-duration),\n visibility var(--b-color-picker-transition-duration);\n outline: none;\n}\n\n.b-color-picker__panel--open {\n opacity: 1;\n visibility: visible;\n}\n\n/* Placement */\n.b-color-picker__panel--bottom-left {\n top: calc(100% + var(--b-color-picker-gap));\n left: 0;\n}\n\n.b-color-picker__panel--bottom-center {\n top: calc(100% + var(--b-color-picker-gap));\n left: 50%;\n transform: translateX(-50%);\n}\n\n.b-color-picker__panel--bottom-right {\n top: calc(100% + var(--b-color-picker-gap));\n right: 0;\n}\n\n.b-color-picker__panel--top-left {\n bottom: calc(100% + var(--b-color-picker-gap));\n left: 0;\n}\n\n.b-color-picker__panel--top-center {\n bottom: calc(100% + var(--b-color-picker-gap));\n left: 50%;\n transform: translateX(-50%);\n}\n\n.b-color-picker__panel--top-right {\n bottom: calc(100% + var(--b-color-picker-gap));\n right: 0;\n}\n\n/* ── Arrow ── */\n.b-color-picker__arrow {\n position: absolute;\n width: 8px;\n height: 8px;\n background: var(--b-color-picker-bg);\n transform: rotate(45deg);\n pointer-events: none;\n box-shadow: -2px -2px 5px rgba(0, 0, 0, 0.04);\n}\n\n.b-color-picker__panel--bottom-left .b-color-picker__arrow,\n.b-color-picker__panel--bottom-center .b-color-picker__arrow,\n.b-color-picker__panel--bottom-right .b-color-picker__arrow {\n top: -4px;\n left: 16px;\n}\n\n.b-color-picker__panel--top-left .b-color-picker__arrow,\n.b-color-picker__panel--top-center .b-color-picker__arrow,\n.b-color-picker__panel--top-right .b-color-picker__arrow {\n bottom: -4px;\n left: 16px;\n}\n\n.b-color-picker__panel--no-arrow .b-color-picker__arrow {\n display: none;\n}\n\n/* ────────────────────────────────────────────\n Saturation panel\n ──────────────────────────────────────────── */\n.b-color-picker__saturation {\n position: relative;\n width: 100%;\n height: var(--b-color-picker-saturation-height);\n border-radius: var(--b-color-picker-border-radius-sm);\n cursor: crosshair;\n overflow: hidden;\n touch-action: none;\n}\n\n.b-color-picker__saturation-white {\n position: absolute;\n inset: 0;\n background: linear-gradient(to right, #fff, transparent);\n}\n\n.b-color-picker__saturation-black {\n position: absolute;\n inset: 0;\n background: linear-gradient(to bottom, transparent, #000);\n}\n\n.b-color-picker__saturation-handle {\n position: absolute;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgba(0, 0, 0, 0.2),\n inset 0 0 1px 1px rgba(0, 0, 0, 0.1);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Controls row (preview + sliders)\n ──────────────────────────────────────────── */\n.b-color-picker__controls {\n display: flex;\n align-items: center;\n gap: var(--b-color-picker-gap);\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preview {\n flex-shrink: 0;\n width: var(--b-color-picker-preview-size);\n height: var(--b-color-picker-preview-size);\n border-radius: 50%;\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n overflow: hidden;\n}\n\n.b-color-picker__preview-color {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.15);\n}\n\n.b-color-picker__sliders {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--b-color-picker-gap);\n}\n\n/* ────────────────────────────────────────────\n Hue slider\n ──────────────────────────────────────────── */\n.b-color-picker__hue {\n position: relative;\n height: var(--b-color-picker-slider-height);\n border-radius: calc(var(--b-color-picker-slider-height) / 2);\n background: linear-gradient(\n to right,\n hsl(0, 100%, 50%),\n hsl(60, 100%, 50%),\n hsl(120, 100%, 50%),\n hsl(180, 100%, 50%),\n hsl(240, 100%, 50%),\n hsl(300, 100%, 50%),\n hsl(360, 100%, 50%)\n );\n cursor: pointer;\n touch-action: none;\n outline: none;\n}\n\n.b-color-picker__hue:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 2px;\n}\n\n.b-color-picker__hue-handle {\n position: absolute;\n top: 50%;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Alpha slider\n ──────────────────────────────────────────── */\n.b-color-picker__alpha {\n position: relative;\n height: var(--b-color-picker-slider-height);\n border-radius: calc(var(--b-color-picker-slider-height) / 2);\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n cursor: pointer;\n touch-action: none;\n outline: none;\n}\n\n.b-color-picker__alpha::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--b-color-picker-alpha-gradient);\n}\n\n.b-color-picker__alpha:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 2px;\n}\n\n.b-color-picker__alpha-handle {\n position: absolute;\n top: 50%;\n z-index: 1;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Input row\n ──────────────────────────────────────────── */\n.b-color-picker__input-row {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__format-btn {\n flex-shrink: 0;\n padding: 2px 4px;\n border: none;\n background: transparent;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--b-color-picker-border-radius-sm);\n line-height: 1.5;\n}\n\n.b-color-picker__format-btn:hover {\n background: rgba(0, 0, 0, 0.06);\n}\n\n.b-color-picker__format-btn:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n.b-color-picker__format-label {\n flex-shrink: 0;\n padding: 2px 4px;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 1.5;\n}\n\n.b-color-picker__input {\n flex: 1;\n min-width: 0;\n height: 24px;\n padding: 0 4px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-input-border);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: var(--b-color-picker-input-bg);\n color: var(--b-color-picker-text-color);\n font-size: 12px;\n text-align: center;\n outline: none;\n}\n\n.b-color-picker__input:focus {\n border-color: #4096ff;\n}\n\n.b-color-picker__alpha-input {\n width: var(--b-color-picker-alpha-input-width);\n height: 24px;\n padding: 0 4px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-input-border);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: var(--b-color-picker-input-bg);\n color: var(--b-color-picker-text-color);\n font-size: 12px;\n text-align: center;\n outline: none;\n}\n\n.b-color-picker__alpha-input:focus {\n border-color: #4096ff;\n}\n\n/* ────────────────────────────────────────────\n Presets\n ──────────────────────────────────────────── */\n.b-color-picker__presets {\n margin-top: var(--b-color-picker-gap);\n border-top: 1px solid var(--b-color-picker-border-color);\n padding-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preset-group + .b-color-picker__preset-group {\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preset-label {\n font-size: 12px;\n color: var(--b-color-picker-text-color-secondary);\n margin-bottom: 4px;\n}\n\n.b-color-picker__preset-colors {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.b-color-picker__preset-color {\n width: 20px;\n height: 20px;\n border: none;\n border-radius: var(--b-color-picker-color-block-border-radius);\n cursor: pointer;\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);\n padding: 0;\n transition: transform var(--b-color-picker-transition-duration);\n}\n\n.b-color-picker__preset-color:hover {\n transform: scale(1.2);\n}\n\n.b-color-picker__preset-color:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n/* ────────────────────────────────────────────\n Clear row\n ──────────────────────────────────────────── */\n.b-color-picker__clear-row {\n margin-top: var(--b-color-picker-gap);\n border-top: 1px solid var(--b-color-picker-border-color);\n padding-top: var(--b-color-picker-gap);\n display: flex;\n justify-content: flex-end;\n}\n\n.b-color-picker__clear-btn {\n padding: 2px 8px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-border-color);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: transparent;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n cursor: pointer;\n line-height: 1.5;\n}\n\n.b-color-picker__clear-btn:hover {\n border-color: #4096ff;\n color: #4096ff;\n}\n\n.b-color-picker__clear-btn:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n/* ────────────────────────────────────────────\n Reduced motion\n ──────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n .b-color-picker__panel {\n transition-duration: 0ms;\n }\n\n .b-color-picker__trigger {\n transition-duration: 0ms;\n }\n\n .b-color-picker__preset-color {\n transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import e from "./design-system67.js";
2
- //#region src/components/BDescriptions/BDescriptionsItem.vue
1
+ import e from "./design-system66.js";
2
+ /* empty css */
3
+ //#region src/components/BColorPicker/BColorPicker.vue
3
4
  var t = e;
4
5
  //#endregion
5
6
  export { t as default };
@@ -1 +1 @@
1
- {"version":3,"file":"design-system68.js","names":[],"sources":["../src/components/BDescriptions/BDescriptionsItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { CSSProperties } from 'vue';\nimport { useSlots } from 'vue';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n label,\n span = 1,\n labelStyle,\n contentStyle,\n} = defineProps<{\n /** Label text displayed for this item. Can be overridden by the `label` slot. */\n label?: string;\n /** Number of columns this item spans. @default 1 */\n span?: number;\n /** Inline style applied to the label cell. */\n labelStyle?: CSSProperties;\n /** Inline style applied to the content cell. */\n contentStyle?: CSSProperties;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Main content of the description item */\n default?: (props: Record<string, never>) => unknown;\n /** Custom label content. Overrides the `label` prop */\n label?: (props: Record<string, never>) => unknown;\n}>();\n\nconst slots = useSlots();\n\n// Expose props for parent to read\ndefineExpose({ label, span, labelStyle, contentStyle, slots });\n</script>\n\n<template>\n <!--\n BDescriptionsItem is a data-only component.\n It does not render its own markup; BDescriptions reads its props/slots\n and renders them in a table/list structure.\n This template is used as a fallback if the item is rendered standalone.\n -->\n <div class=\"b-descriptions-item\">\n <span v-if=\"label || $slots.label\" class=\"b-descriptions-item__label\" :style=\"labelStyle\">\n <slot name=\"label\">{{ label }}</slot>\n </span>\n <span class=\"b-descriptions-item__content\" :style=\"contentStyle\">\n <slot />\n </span>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"design-system68.js","names":[],"sources":["../src/components/BColorPicker/BColorPicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, useId, watch } from 'vue';\nimport {\n BColorPickerFormat,\n BColorPickerPlacement,\n BColorPickerSize,\n BColorPickerTrigger,\n type BColorHsb,\n type BColorHsl,\n type BColorPickerPreset,\n type BColorRgb,\n} from './types';\n\n// ─────────────────────────────────────────────\n// Props & emits\n// ─────────────────────────────────────────────\nconst {\n modelValue = undefined,\n defaultValue = '#1677ff',\n disabled = false,\n open = undefined,\n trigger = BColorPickerTrigger.Click,\n size = BColorPickerSize.Medium,\n placement = BColorPickerPlacement.BottomLeft,\n format = undefined,\n defaultFormat = BColorPickerFormat.Hex,\n disabledAlpha = false,\n disabledFormat = false,\n showText = false,\n presets = undefined,\n allowClear = false,\n destroyOnHidden = false,\n arrow = true,\n} = defineProps<{\n /** Current color value (v-model). Accepts hex, rgb, hsl strings. */\n modelValue?: string;\n /** Default color when uncontrolled. */\n defaultValue?: string;\n /** Whether the color picker is disabled. */\n disabled?: boolean;\n /** Controlled open state of the popup (v-model:open). */\n open?: boolean;\n /** How the popup is triggered. */\n trigger?: `${BColorPickerTrigger}`;\n /** Size of the trigger button. */\n size?: `${BColorPickerSize}`;\n /** Placement of the popup relative to the trigger. */\n placement?: `${BColorPickerPlacement}`;\n /** Controlled color format. */\n format?: `${BColorPickerFormat}`;\n /** Default color format when uncontrolled. */\n defaultFormat?: `${BColorPickerFormat}`;\n /** Whether to disable the alpha slider. */\n disabledAlpha?: boolean;\n /** Whether to disable format switching. */\n disabledFormat?: boolean;\n /** Whether to show the color text value next to the swatch. */\n showText?: boolean | ((color: string) => string);\n /** Preset color groups. */\n presets?: BColorPickerPreset[];\n /** Whether to allow clearing the color. */\n allowClear?: boolean;\n /** Destroy popup DOM when closed. */\n destroyOnHidden?: boolean;\n /** Whether the popup has an arrow. */\n arrow?: boolean;\n}>();\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string): void;\n (e: 'update:open', value: boolean): void;\n (e: 'change', value: string, css: string): void;\n (e: 'changeComplete', value: string): void;\n (e: 'formatChange', format: `${BColorPickerFormat}`): void;\n (e: 'clear'): void;\n (e: 'openChange', open: boolean): void;\n}>();\n\ndefineSlots<{\n /** Custom trigger element. */\n default?(): unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Color conversion utilities\n// ─────────────────────────────────────────────\n\nfunction hexToRgb(hex: string): BColorRgb {\n let h = hex.replace('#', '');\n let a = 1;\n if (h.length === 4) {\n h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];\n } else if (h.length === 8) {\n a = parseInt(h.slice(6, 8), 16) / 255;\n h = h.slice(0, 6);\n }\n const num = parseInt(h, 16);\n return { r: (num >> 16) & 255, g: (num >> 8) & 255, b: num & 255, a };\n}\n\nfunction rgbToHex(rgb: BColorRgb): string {\n const toHex = (n: number) =>\n Math.round(Math.max(0, Math.min(255, n)))\n .toString(16)\n .padStart(2, '0');\n const hex = `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;\n if (rgb.a < 1) {\n return hex + toHex(Math.round(rgb.a * 255));\n }\n return hex;\n}\n\nfunction rgbToHsb(rgb: BColorRgb): BColorHsb {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const d = max - min;\n let h = 0;\n const s = max === 0 ? 0 : d / max;\n const v = max;\n if (d !== 0) {\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n return { h: h * 360, s: s * 100, b: v * 100, a: rgb.a };\n}\n\nfunction hsbToRgb(hsb: BColorHsb): BColorRgb {\n const h = hsb.h / 360;\n const s = hsb.s / 100;\n const v = hsb.b / 100;\n let r = 0,\n g = 0,\n b = 0;\n const i = Math.floor(h * 6);\n const f = h * 6 - i;\n const p = v * (1 - s);\n const q = v * (1 - f * s);\n const t = v * (1 - (1 - f) * s);\n switch (i % 6) {\n case 0:\n r = v;\n g = t;\n b = p;\n break;\n case 1:\n r = q;\n g = v;\n b = p;\n break;\n case 2:\n r = p;\n g = v;\n b = t;\n break;\n case 3:\n r = p;\n g = q;\n b = v;\n break;\n case 4:\n r = t;\n g = p;\n b = v;\n break;\n case 5:\n r = v;\n g = p;\n b = q;\n break;\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: hsb.a,\n };\n}\n\nfunction rgbToHsl(rgb: BColorRgb): BColorHsl {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = ((g - b) / d + (g < b ? 6 : 0)) / 6;\n break;\n case g:\n h = ((b - r) / d + 2) / 6;\n break;\n case b:\n h = ((r - g) / d + 4) / 6;\n break;\n }\n }\n return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100), a: rgb.a };\n}\n\nfunction hslToRgb(hsl: BColorHsl): BColorRgb {\n const h = hsl.h / 360;\n const s = hsl.s / 100;\n const l = hsl.l / 100;\n let r: number, g: number, b: number;\n if (s === 0) {\n r = g = b = l;\n } else {\n const hue2rgb = (p: number, q: number, t: number) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q2 = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p2 = 2 * l - q2;\n r = hue2rgb(p2, q2, h + 1 / 3);\n g = hue2rgb(p2, q2, h);\n b = hue2rgb(p2, q2, h - 1 / 3);\n }\n return {\n r: Math.round(r * 255),\n g: Math.round(g * 255),\n b: Math.round(b * 255),\n a: hsl.a,\n };\n}\n\nfunction parseColor(input: string): BColorHsb {\n const s = input.trim().toLowerCase();\n\n // HSL string\n const hslMatch = s.match(/hsla?\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (hslMatch) {\n const hsl: BColorHsl = {\n h: parseInt(hslMatch[1]),\n s: parseInt(hslMatch[2]),\n l: parseInt(hslMatch[3]),\n a: hslMatch[4] !== undefined ? parseFloat(hslMatch[4]) : 1,\n };\n return rgbToHsb(hslToRgb(hsl));\n }\n\n // RGB string\n const rgbMatch = s.match(/rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (rgbMatch) {\n const rgb: BColorRgb = {\n r: parseInt(rgbMatch[1]),\n g: parseInt(rgbMatch[2]),\n b: parseInt(rgbMatch[3]),\n a: rgbMatch[4] !== undefined ? parseFloat(rgbMatch[4]) : 1,\n };\n return rgbToHsb(rgb);\n }\n\n // HSB string\n const hsbMatch = s.match(/hsb\\(\\s*(\\d+)\\s*,\\s*(\\d+)%?\\s*,\\s*(\\d+)%?\\s*(?:,\\s*([\\d.]+))?\\s*\\)/);\n if (hsbMatch) {\n return {\n h: parseInt(hsbMatch[1]),\n s: parseInt(hsbMatch[2]),\n b: parseInt(hsbMatch[3]),\n a: hsbMatch[4] !== undefined ? parseFloat(hsbMatch[4]) : 1,\n };\n }\n\n // Hex (default)\n return rgbToHsb(hexToRgb(s));\n}\n\nfunction hsbToString(hsb: BColorHsb, fmt: `${BColorPickerFormat}`): string {\n const rgb = hsbToRgb(hsb);\n switch (fmt) {\n case BColorPickerFormat.Hex:\n return rgbToHex(rgb);\n case BColorPickerFormat.Rgb:\n return rgb.a < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${roundTo(rgb.a, 2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n case BColorPickerFormat.Hsl: {\n const hsl = rgbToHsl(rgb);\n return hsl.a < 1\n ? `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${roundTo(hsl.a, 2)})`\n : `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;\n }\n case BColorPickerFormat.Hsb:\n return hsb.a < 1\n ? `hsb(${Math.round(hsb.h)}, ${Math.round(hsb.s)}%, ${Math.round(hsb.b)}%, ${roundTo(hsb.a, 2)})`\n : `hsb(${Math.round(hsb.h)}, ${Math.round(hsb.s)}%, ${Math.round(hsb.b)}%)`;\n default:\n return rgbToHex(rgb);\n }\n}\n\nfunction roundTo(n: number, decimals: number): number {\n const factor = 10 ** decimals;\n return Math.round(n * factor) / factor;\n}\n\nfunction hsbToCssColor(hsb: BColorHsb): string {\n const rgb = hsbToRgb(hsb);\n return rgb.a < 1\n ? `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${roundTo(rgb.a, 2)})`\n : `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;\n}\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst panelId = useId();\n\nconst initialColor = parseColor(modelValue ?? defaultValue);\nconst internalHsb = ref<BColorHsb>({ ...initialColor });\nconst internalFormat = ref<`${BColorPickerFormat}`>(format ?? defaultFormat);\nconst internalOpen = ref(false);\nconst cleared = ref(false);\nconst hasBeenOpened = ref(false);\n\nconst isOpen = computed(() => (open !== undefined ? open : internalOpen.value));\nconst shouldRender = computed(() => {\n if (destroyOnHidden) return isOpen.value;\n return hasBeenOpened.value || isOpen.value;\n});\n\nconst activeFormat = computed(() => format ?? internalFormat.value);\n\nconst colorString = computed(() => hsbToString(internalHsb.value, activeFormat.value));\nconst cssColor = computed(() => hsbToCssColor(internalHsb.value));\n\nconst displayText = computed(() => {\n if (!showText) return '';\n if (typeof showText === 'function') return showText(colorString.value);\n return colorString.value;\n});\n\nwatch(isOpen, (val) => {\n if (val) hasBeenOpened.value = true;\n});\n\nwatch(\n () => modelValue,\n (val) => {\n if (val !== undefined) {\n const parsed = parseColor(val);\n internalHsb.value = parsed;\n cleared.value = false;\n }\n },\n);\n\nwatch(\n () => format,\n (val) => {\n if (val) internalFormat.value = val;\n },\n);\n\n// ─────────────────────────────────────────────\n// Visibility control\n// ─────────────────────────────────────────────\nconst triggerRef = ref<HTMLDivElement | null>(null);\nconst panelRef = ref<HTMLDivElement | null>(null);\n\nlet hoverTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction setOpen(val: boolean) {\n if (disabled) return;\n if (open !== undefined) {\n emit('update:open', val);\n } else {\n internalOpen.value = val;\n }\n emit('openChange', val);\n}\n\nfunction toggleOpen() {\n setOpen(!isOpen.value);\n}\n\nfunction onTriggerClick() {\n if (trigger === BColorPickerTrigger.Click) toggleOpen();\n}\n\nfunction onTriggerMouseEnter() {\n if (trigger === BColorPickerTrigger.Hover) {\n if (hoverTimer) clearTimeout(hoverTimer);\n setOpen(true);\n }\n}\n\nfunction onTriggerMouseLeave() {\n if (trigger === BColorPickerTrigger.Hover) {\n hoverTimer = setTimeout(() => setOpen(false), 150);\n }\n}\n\nfunction onPanelMouseEnter() {\n if (trigger === BColorPickerTrigger.Hover && hoverTimer) {\n clearTimeout(hoverTimer);\n }\n}\n\nfunction onPanelMouseLeave() {\n if (trigger === BColorPickerTrigger.Hover) {\n hoverTimer = setTimeout(() => setOpen(false), 150);\n }\n}\n\nfunction onKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape' && isOpen.value) {\n event.preventDefault();\n setOpen(false);\n triggerRef.value?.focus();\n }\n if ((event.key === 'Enter' || event.key === ' ') && !isOpen.value) {\n event.preventDefault();\n setOpen(true);\n }\n}\n\n// Close on outside click\nfunction onDocumentClick(event: MouseEvent) {\n if (!isOpen.value) return;\n const target = event.target as Node;\n if (triggerRef.value?.contains(target) || panelRef.value?.contains(target)) {\n return;\n }\n setOpen(false);\n}\n\nonMounted(() => {\n document.addEventListener('mousedown', onDocumentClick);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', onDocumentClick);\n if (hoverTimer) clearTimeout(hoverTimer);\n});\n\n// Sync controlled open → popover\nwatch(\n () => open,\n (val) => {\n if (val === undefined) return;\n internalOpen.value = val;\n },\n);\n\n// Focus management\nlet previouslyFocusedElement: HTMLElement | null = null;\n\nwatch(isOpen, (val) => {\n if (val) {\n previouslyFocusedElement = document.activeElement as HTMLElement | null;\n nextTick(() => {\n panelRef.value?.focus();\n });\n } else {\n nextTick(() => previouslyFocusedElement?.focus());\n }\n});\n\n// ─────────────────────────────────────────────\n// Saturation panel interaction\n// ─────────────────────────────────────────────\nconst saturationRef = ref<HTMLDivElement | null>(null);\nlet isDraggingSat = false;\n\nfunction updateSaturationFromEvent(event: MouseEvent | TouchEvent) {\n if (!saturationRef.value) return;\n const rect = saturationRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const clientY = 'touches' in event ? event.touches[0].clientY : event.clientY;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const y = Math.max(0, Math.min(1, (clientY - rect.top) / rect.height));\n internalHsb.value = {\n ...internalHsb.value,\n s: x * 100,\n b: (1 - y) * 100,\n };\n emitChange();\n}\n\nfunction onSaturationMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingSat = true;\n updateSaturationFromEvent(event);\n document.addEventListener('mousemove', onSaturationMouseMove);\n document.addEventListener('mouseup', onSaturationMouseUp);\n}\n\nfunction onSaturationMouseMove(event: MouseEvent) {\n if (!isDraggingSat) return;\n updateSaturationFromEvent(event);\n}\n\nfunction onSaturationMouseUp() {\n isDraggingSat = false;\n document.removeEventListener('mousemove', onSaturationMouseMove);\n document.removeEventListener('mouseup', onSaturationMouseUp);\n emitChangeComplete();\n}\n\nfunction onSaturationTouchStart(event: TouchEvent) {\n event.preventDefault();\n isDraggingSat = true;\n updateSaturationFromEvent(event);\n document.addEventListener('touchmove', onSaturationTouchMove);\n document.addEventListener('touchend', onSaturationTouchEnd);\n}\n\nfunction onSaturationTouchMove(event: TouchEvent) {\n if (!isDraggingSat) return;\n updateSaturationFromEvent(event);\n}\n\nfunction onSaturationTouchEnd() {\n isDraggingSat = false;\n document.removeEventListener('touchmove', onSaturationTouchMove);\n document.removeEventListener('touchend', onSaturationTouchEnd);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Hue slider interaction\n// ─────────────────────────────────────────────\nconst hueRef = ref<HTMLDivElement | null>(null);\nlet isDraggingHue = false;\n\nfunction updateHueFromEvent(event: MouseEvent | TouchEvent) {\n if (!hueRef.value) return;\n const rect = hueRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n internalHsb.value = { ...internalHsb.value, h: x * 360 };\n emitChange();\n}\n\nfunction onHueMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingHue = true;\n updateHueFromEvent(event);\n document.addEventListener('mousemove', onHueMouseMove);\n document.addEventListener('mouseup', onHueMouseUp);\n}\n\nfunction onHueMouseMove(event: MouseEvent) {\n if (!isDraggingHue) return;\n updateHueFromEvent(event);\n}\n\nfunction onHueMouseUp() {\n isDraggingHue = false;\n document.removeEventListener('mousemove', onHueMouseMove);\n document.removeEventListener('mouseup', onHueMouseUp);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Alpha slider interaction\n// ─────────────────────────────────────────────\nconst alphaRef = ref<HTMLDivElement | null>(null);\nlet isDraggingAlpha = false;\n\nfunction updateAlphaFromEvent(event: MouseEvent | TouchEvent) {\n if (!alphaRef.value) return;\n const rect = alphaRef.value.getBoundingClientRect();\n const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;\n const x = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n internalHsb.value = { ...internalHsb.value, a: roundTo(x, 2) };\n emitChange();\n}\n\nfunction onAlphaMouseDown(event: MouseEvent) {\n event.preventDefault();\n isDraggingAlpha = true;\n updateAlphaFromEvent(event);\n document.addEventListener('mousemove', onAlphaMouseMove);\n document.addEventListener('mouseup', onAlphaMouseUp);\n}\n\nfunction onAlphaMouseMove(event: MouseEvent) {\n if (!isDraggingAlpha) return;\n updateAlphaFromEvent(event);\n}\n\nfunction onAlphaMouseUp() {\n isDraggingAlpha = false;\n document.removeEventListener('mousemove', onAlphaMouseMove);\n document.removeEventListener('mouseup', onAlphaMouseUp);\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Format switching\n// ─────────────────────────────────────────────\nconst formatOrder: `${BColorPickerFormat}`[] = [\n BColorPickerFormat.Hex,\n BColorPickerFormat.Hsb,\n BColorPickerFormat.Rgb,\n BColorPickerFormat.Hsl,\n];\n\nfunction cycleFormat() {\n if (disabledFormat) return;\n const idx = formatOrder.indexOf(activeFormat.value);\n const next = formatOrder[(idx + 1) % formatOrder.length];\n if (format === undefined) {\n internalFormat.value = next;\n }\n emit('formatChange', next);\n}\n\n// ─────────────────────────────────────────────\n// Input handling\n// ─────────────────────────────────────────────\nconst inputValue = computed(() => {\n switch (activeFormat.value) {\n case BColorPickerFormat.Hex:\n return rgbToHex(hsbToRgb(internalHsb.value)).replace('#', '');\n case BColorPickerFormat.Rgb: {\n const rgb = hsbToRgb(internalHsb.value);\n return `${rgb.r}, ${rgb.g}, ${rgb.b}`;\n }\n case BColorPickerFormat.Hsl: {\n const hsl = rgbToHsl(hsbToRgb(internalHsb.value));\n return `${hsl.h}, ${hsl.s}%, ${hsl.l}%`;\n }\n case BColorPickerFormat.Hsb:\n return `${Math.round(internalHsb.value.h)}, ${Math.round(internalHsb.value.s)}%, ${Math.round(internalHsb.value.b)}%`;\n default:\n return '';\n }\n});\n\nconst alphaPercent = computed(() => Math.round(internalHsb.value.a * 100));\n\nfunction onInputChange(event: Event) {\n const val = (event.target as HTMLInputElement).value.trim();\n try {\n let parsed: BColorHsb;\n switch (activeFormat.value) {\n case BColorPickerFormat.Hex:\n parsed = parseColor('#' + val);\n break;\n case BColorPickerFormat.Rgb: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = rgbToHsb({ r: parts[0], g: parts[1], b: parts[2], a: internalHsb.value.a });\n } else return;\n break;\n }\n case BColorPickerFormat.Hsl: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = rgbToHsb(\n hslToRgb({ h: parts[0], s: parts[1], l: parts[2], a: internalHsb.value.a }),\n );\n } else return;\n break;\n }\n case BColorPickerFormat.Hsb: {\n const parts = val.split(',').map((s) => parseInt(s.trim()));\n if (parts.length >= 3) {\n parsed = { h: parts[0], s: parts[1], b: parts[2], a: internalHsb.value.a };\n } else return;\n break;\n }\n default:\n return;\n }\n internalHsb.value = parsed;\n emitChange();\n emitChangeComplete();\n } catch {\n // Invalid input, ignore\n }\n}\n\nfunction onAlphaInputChange(event: Event) {\n const val = parseInt((event.target as HTMLInputElement).value);\n if (!isNaN(val)) {\n internalHsb.value = { ...internalHsb.value, a: Math.max(0, Math.min(100, val)) / 100 };\n emitChange();\n emitChangeComplete();\n }\n}\n\n// ─────────────────────────────────────────────\n// Preset selection\n// ─────────────────────────────────────────────\nfunction selectPreset(color: string) {\n internalHsb.value = parseColor(color);\n cleared.value = false;\n emitChange();\n emitChangeComplete();\n}\n\n// ─────────────────────────────────────────────\n// Clear\n// ─────────────────────────────────────────────\nfunction onClear() {\n cleared.value = true;\n emit('clear');\n}\n\n// ─────────────────────────────────────────────\n// Emit helpers\n// ─────────────────────────────────────────────\nfunction emitChange() {\n cleared.value = false;\n const str = hsbToString(internalHsb.value, activeFormat.value);\n const css = hsbToCssColor(internalHsb.value);\n emit('update:modelValue', str);\n emit('change', str, css);\n}\n\nfunction emitChangeComplete() {\n const str = hsbToString(internalHsb.value, activeFormat.value);\n emit('changeComplete', str);\n}\n\n// ─────────────────────────────────────────────\n// Computed styles\n// ─────────────────────────────────────────────\nconst anchorName = computed(() => `--b-color-picker-anchor-${componentUID.value}`);\n\nconst saturationStyle = computed(() => ({\n backgroundColor: `hsl(${internalHsb.value.h}, 100%, 50%)`,\n}));\n\nconst saturationHandleStyle = computed(() => ({\n left: `${internalHsb.value.s}%`,\n top: `${100 - internalHsb.value.b}%`,\n}));\n\nconst hueHandleStyle = computed(() => ({\n left: `${(internalHsb.value.h / 360) * 100}%`,\n}));\n\nconst alphaHandleStyle = computed(() => ({\n left: `${internalHsb.value.a * 100}%`,\n}));\n\nconst alphaGradient = computed(() => {\n const rgb = hsbToRgb({ ...internalHsb.value, a: 1 });\n return `linear-gradient(to right, rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0), rgb(${rgb.r}, ${rgb.g}, ${rgb.b}))`;\n});\n\nconst sizeClass = computed(() => {\n switch (size) {\n case BColorPickerSize.Small:\n return 'b-color-picker--sm';\n case BColorPickerSize.Large:\n return 'b-color-picker--lg';\n default:\n return 'b-color-picker--md';\n }\n});\n\n// ─────────────────────────────────────────────\n// Panel keyboard nav\n// ─────────────────────────────────────────────\nfunction onPanelKeydown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.value?.focus();\n }\n}\n\n// ─────────────────────────────────────────────\n// Public API\n// ─────────────────────────────────────────────\ndefineExpose({ open: () => setOpen(true), close: () => setOpen(false) });\n</script>\n\n<template>\n <div class=\"b-color-picker\" :class=\"[sizeClass, { 'b-color-picker--disabled': disabled }]\">\n <!-- Trigger -->\n <div\n ref=\"triggerRef\"\n class=\"b-color-picker__trigger\"\n :style=\"{ anchorName }\"\n role=\"button\"\n :tabindex=\"disabled ? -1 : 0\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? panelId : undefined\"\n :aria-disabled=\"disabled\"\n :aria-label=\"`Color picker: ${colorString}`\"\n aria-haspopup=\"dialog\"\n @click=\"onTriggerClick\"\n @mouseenter=\"onTriggerMouseEnter\"\n @mouseleave=\"onTriggerMouseLeave\"\n @keydown=\"onKeydown\"\n >\n <slot>\n <div class=\"b-color-picker__swatch-wrapper\">\n <div\n class=\"b-color-picker__swatch\"\n :class=\"{ 'b-color-picker__swatch--cleared': cleared && allowClear }\"\n :style=\"{ backgroundColor: cleared ? 'transparent' : cssColor }\"\n />\n </div>\n <span v-if=\"showText\" class=\"b-color-picker__text\">\n {{ displayText }}\n </span>\n </slot>\n </div>\n\n <!-- Panel (popup) -->\n <div\n v-if=\"shouldRender\"\n ref=\"panelRef\"\n :id=\"panelId\"\n class=\"b-color-picker__panel\"\n :class=\"[\n `b-color-picker__panel--${placement}`,\n { 'b-color-picker__panel--open': isOpen, 'b-color-picker__panel--no-arrow': !arrow },\n ]\"\n :style=\"{ positionAnchor: anchorName }\"\n role=\"dialog\"\n :aria-label=\"'Color picker'\"\n tabindex=\"-1\"\n @mouseenter=\"onPanelMouseEnter\"\n @mouseleave=\"onPanelMouseLeave\"\n @keydown=\"onPanelKeydown\"\n >\n <!-- Arrow -->\n <div v-if=\"arrow\" class=\"b-color-picker__arrow\" aria-hidden=\"true\" />\n\n <!-- Saturation panel -->\n <div\n ref=\"saturationRef\"\n class=\"b-color-picker__saturation\"\n :style=\"saturationStyle\"\n role=\"slider\"\n aria-label=\"Color saturation and brightness\"\n :aria-valuetext=\"`Saturation ${Math.round(internalHsb.s)}%, Brightness ${Math.round(internalHsb.b)}%`\"\n tabindex=\"0\"\n @mousedown=\"onSaturationMouseDown\"\n @touchstart.passive=\"onSaturationTouchStart\"\n >\n <div class=\"b-color-picker__saturation-white\" />\n <div class=\"b-color-picker__saturation-black\" />\n <div class=\"b-color-picker__saturation-handle\" :style=\"saturationHandleStyle\" />\n </div>\n\n <!-- Sliders + preview row -->\n <div class=\"b-color-picker__controls\">\n <div class=\"b-color-picker__preview\">\n <div class=\"b-color-picker__preview-color\" :style=\"{ backgroundColor: cssColor }\" />\n </div>\n\n <div class=\"b-color-picker__sliders\">\n <!-- Hue slider -->\n <div\n ref=\"hueRef\"\n class=\"b-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Hue\"\n :aria-valuenow=\"Math.round(internalHsb.h)\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n tabindex=\"0\"\n @mousedown=\"onHueMouseDown\"\n >\n <div class=\"b-color-picker__hue-handle\" :style=\"hueHandleStyle\" />\n </div>\n\n <!-- Alpha slider -->\n <div\n v-if=\"!disabledAlpha\"\n ref=\"alphaRef\"\n class=\"b-color-picker__alpha\"\n :style=\"{ '--b-color-picker-alpha-gradient': alphaGradient }\"\n role=\"slider\"\n aria-label=\"Opacity\"\n :aria-valuenow=\"alphaPercent\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n tabindex=\"0\"\n @mousedown=\"onAlphaMouseDown\"\n >\n <div class=\"b-color-picker__alpha-handle\" :style=\"alphaHandleStyle\" />\n </div>\n </div>\n </div>\n\n <!-- Input row -->\n <div class=\"b-color-picker__input-row\">\n <button\n v-if=\"!disabledFormat\"\n class=\"b-color-picker__format-btn\"\n type=\"button\"\n aria-label=\"Switch color format\"\n @click=\"cycleFormat\"\n >\n {{ activeFormat.toUpperCase() }}\n </button>\n <span v-else class=\"b-color-picker__format-label\">\n {{ activeFormat.toUpperCase() }}\n </span>\n\n <input\n class=\"b-color-picker__input\"\n type=\"text\"\n :value=\"inputValue\"\n aria-label=\"Color value\"\n @change=\"onInputChange\"\n />\n\n <input\n v-if=\"!disabledAlpha\"\n class=\"b-color-picker__alpha-input\"\n type=\"text\"\n :value=\"`${alphaPercent}%`\"\n aria-label=\"Alpha percentage\"\n @change=\"onAlphaInputChange\"\n />\n </div>\n\n <!-- Presets -->\n <div v-if=\"presets && presets.length\" class=\"b-color-picker__presets\">\n <div v-for=\"preset in presets\" :key=\"preset.label\" class=\"b-color-picker__preset-group\">\n <div class=\"b-color-picker__preset-label\">{{ preset.label }}</div>\n <div class=\"b-color-picker__preset-colors\">\n <button\n v-for=\"color in preset.colors\"\n :key=\"color\"\n type=\"button\"\n class=\"b-color-picker__preset-color\"\n :style=\"{ backgroundColor: color }\"\n :aria-label=\"`Select color ${color}`\"\n @click=\"selectPreset(color)\"\n />\n </div>\n </div>\n </div>\n\n <!-- Clear button -->\n <div v-if=\"allowClear\" class=\"b-color-picker__clear-row\">\n <button\n type=\"button\"\n class=\"b-color-picker__clear-btn\"\n aria-label=\"Clear color\"\n @click=\"onClear\"\n >\n Clear\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n/* ────────────────────────────────────────────\n CSS Custom Properties (Design Tokens)\n ──────────────────────────────────────────── */\n.b-color-picker {\n --b-color-picker-width: 234px;\n --b-color-picker-handler-size: 16px;\n --b-color-picker-handler-size-sm: 12px;\n --b-color-picker-slider-height: 8px;\n --b-color-picker-preview-size: 28px;\n --b-color-picker-alpha-input-width: 44px;\n --b-color-picker-border-width: 1px;\n --b-color-picker-border-radius: 6px;\n --b-color-picker-border-radius-sm: 4px;\n --b-color-picker-font-size: 14px;\n --b-color-picker-line-height: 1.5714;\n --b-color-picker-bg: #ffffff;\n --b-color-picker-border-color: #d9d9d9;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-color-picker-trigger-height: 32px;\n --b-color-picker-trigger-height-sm: 24px;\n --b-color-picker-trigger-height-lg: 40px;\n --b-color-picker-swatch-size: 16px;\n --b-color-picker-swatch-size-sm: 12px;\n --b-color-picker-swatch-size-lg: 20px;\n --b-color-picker-panel-padding: 12px;\n --b-color-picker-saturation-height: 160px;\n --b-color-picker-color-block-border-radius: 4px;\n --b-color-picker-input-bg: #ffffff;\n --b-color-picker-input-border: #d9d9d9;\n --b-color-picker-text-color: rgba(0, 0, 0, 0.88);\n --b-color-picker-text-color-secondary: rgba(0, 0, 0, 0.65);\n --b-color-picker-gap: 8px;\n --b-color-picker-transition-duration: 200ms;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-color-picker {\n --b-color-picker-bg: #1f1f1f;\n --b-color-picker-border-color: #424242;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.24), 0 3px 6px -4px rgba(0, 0, 0, 0.36),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-color-picker-input-bg: #141414;\n --b-color-picker-input-border: #424242;\n --b-color-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-color-picker-text-color-secondary: rgba(255, 255, 255, 0.65);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-color-picker {\n --b-color-picker-bg: #1f1f1f;\n --b-color-picker-border-color: #424242;\n --b-color-picker-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.24), 0 3px 6px -4px rgba(0, 0, 0, 0.36),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-color-picker-input-bg: #141414;\n --b-color-picker-input-border: #424242;\n --b-color-picker-text-color: rgba(255, 255, 255, 0.88);\n --b-color-picker-text-color-secondary: rgba(255, 255, 255, 0.65);\n }\n}\n\n/* ────────────────────────────────────────────\n Root\n ──────────────────────────────────────────── */\n.b-color-picker {\n display: inline-flex;\n position: relative;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: var(--b-color-picker-font-size);\n line-height: var(--b-color-picker-line-height);\n}\n\n.b-color-picker--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.b-color-picker--disabled .b-color-picker__trigger {\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Trigger\n ──────────────────────────────────────────── */\n.b-color-picker__trigger {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n height: var(--b-color-picker-trigger-height);\n padding: 3px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-border-color);\n border-radius: var(--b-color-picker-border-radius);\n cursor: pointer;\n background: var(--b-color-picker-bg);\n transition: border-color var(--b-color-picker-transition-duration);\n outline: none;\n}\n\n.b-color-picker__trigger:hover:not([aria-disabled='true']) {\n border-color: #4096ff;\n}\n\n.b-color-picker__trigger:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n.b-color-picker--sm .b-color-picker__trigger {\n height: var(--b-color-picker-trigger-height-sm);\n padding: 2px;\n}\n\n.b-color-picker--lg .b-color-picker__trigger {\n height: var(--b-color-picker-trigger-height-lg);\n padding: 4px;\n}\n\n.b-color-picker__swatch-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: calc(var(--b-color-picker-trigger-height) - 8px);\n height: calc(var(--b-color-picker-trigger-height) - 8px);\n border-radius: var(--b-color-picker-border-radius-sm);\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n}\n\n.b-color-picker--sm .b-color-picker__swatch-wrapper {\n width: calc(var(--b-color-picker-trigger-height-sm) - 6px);\n height: calc(var(--b-color-picker-trigger-height-sm) - 6px);\n}\n\n.b-color-picker--lg .b-color-picker__swatch-wrapper {\n width: calc(var(--b-color-picker-trigger-height-lg) - 10px);\n height: calc(var(--b-color-picker-trigger-height-lg) - 10px);\n}\n\n.b-color-picker__swatch {\n width: 100%;\n height: 100%;\n border-radius: var(--b-color-picker-border-radius-sm);\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.25);\n}\n\n.b-color-picker__swatch--cleared {\n background: linear-gradient(135deg, transparent 45%, #ff4d4f 45%, #ff4d4f 55%, transparent 55%)\n center/100% 100%;\n}\n\n.b-color-picker__text {\n padding-right: 4px;\n color: var(--b-color-picker-text-color);\n font-size: var(--b-color-picker-font-size);\n user-select: none;\n}\n\n/* ────────────────────────────────────────────\n Panel\n ──────────────────────────────────────────── */\n.b-color-picker__panel {\n position: absolute;\n z-index: 1050;\n width: var(--b-color-picker-width);\n padding: var(--b-color-picker-panel-padding);\n background: var(--b-color-picker-bg);\n border-radius: var(--b-color-picker-border-radius);\n box-shadow: var(--b-color-picker-shadow);\n opacity: 0;\n visibility: hidden;\n transition:\n opacity var(--b-color-picker-transition-duration),\n visibility var(--b-color-picker-transition-duration);\n outline: none;\n}\n\n.b-color-picker__panel--open {\n opacity: 1;\n visibility: visible;\n}\n\n/* Placement */\n.b-color-picker__panel--bottom-left {\n top: calc(100% + var(--b-color-picker-gap));\n left: 0;\n}\n\n.b-color-picker__panel--bottom-center {\n top: calc(100% + var(--b-color-picker-gap));\n left: 50%;\n transform: translateX(-50%);\n}\n\n.b-color-picker__panel--bottom-right {\n top: calc(100% + var(--b-color-picker-gap));\n right: 0;\n}\n\n.b-color-picker__panel--top-left {\n bottom: calc(100% + var(--b-color-picker-gap));\n left: 0;\n}\n\n.b-color-picker__panel--top-center {\n bottom: calc(100% + var(--b-color-picker-gap));\n left: 50%;\n transform: translateX(-50%);\n}\n\n.b-color-picker__panel--top-right {\n bottom: calc(100% + var(--b-color-picker-gap));\n right: 0;\n}\n\n/* ── Arrow ── */\n.b-color-picker__arrow {\n position: absolute;\n width: 8px;\n height: 8px;\n background: var(--b-color-picker-bg);\n transform: rotate(45deg);\n pointer-events: none;\n box-shadow: -2px -2px 5px rgba(0, 0, 0, 0.04);\n}\n\n.b-color-picker__panel--bottom-left .b-color-picker__arrow,\n.b-color-picker__panel--bottom-center .b-color-picker__arrow,\n.b-color-picker__panel--bottom-right .b-color-picker__arrow {\n top: -4px;\n left: 16px;\n}\n\n.b-color-picker__panel--top-left .b-color-picker__arrow,\n.b-color-picker__panel--top-center .b-color-picker__arrow,\n.b-color-picker__panel--top-right .b-color-picker__arrow {\n bottom: -4px;\n left: 16px;\n}\n\n.b-color-picker__panel--no-arrow .b-color-picker__arrow {\n display: none;\n}\n\n/* ────────────────────────────────────────────\n Saturation panel\n ──────────────────────────────────────────── */\n.b-color-picker__saturation {\n position: relative;\n width: 100%;\n height: var(--b-color-picker-saturation-height);\n border-radius: var(--b-color-picker-border-radius-sm);\n cursor: crosshair;\n overflow: hidden;\n touch-action: none;\n}\n\n.b-color-picker__saturation-white {\n position: absolute;\n inset: 0;\n background: linear-gradient(to right, #fff, transparent);\n}\n\n.b-color-picker__saturation-black {\n position: absolute;\n inset: 0;\n background: linear-gradient(to bottom, transparent, #000);\n}\n\n.b-color-picker__saturation-handle {\n position: absolute;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow:\n 0 0 0 1px rgba(0, 0, 0, 0.2),\n inset 0 0 1px 1px rgba(0, 0, 0, 0.1);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Controls row (preview + sliders)\n ──────────────────────────────────────────── */\n.b-color-picker__controls {\n display: flex;\n align-items: center;\n gap: var(--b-color-picker-gap);\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preview {\n flex-shrink: 0;\n width: var(--b-color-picker-preview-size);\n height: var(--b-color-picker-preview-size);\n border-radius: 50%;\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n overflow: hidden;\n}\n\n.b-color-picker__preview-color {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.15);\n}\n\n.b-color-picker__sliders {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: var(--b-color-picker-gap);\n}\n\n/* ────────────────────────────────────────────\n Hue slider\n ──────────────────────────────────────────── */\n.b-color-picker__hue {\n position: relative;\n height: var(--b-color-picker-slider-height);\n border-radius: calc(var(--b-color-picker-slider-height) / 2);\n background: linear-gradient(\n to right,\n hsl(0, 100%, 50%),\n hsl(60, 100%, 50%),\n hsl(120, 100%, 50%),\n hsl(180, 100%, 50%),\n hsl(240, 100%, 50%),\n hsl(300, 100%, 50%),\n hsl(360, 100%, 50%)\n );\n cursor: pointer;\n touch-action: none;\n outline: none;\n}\n\n.b-color-picker__hue:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 2px;\n}\n\n.b-color-picker__hue-handle {\n position: absolute;\n top: 50%;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Alpha slider\n ──────────────────────────────────────────── */\n.b-color-picker__alpha {\n position: relative;\n height: var(--b-color-picker-slider-height);\n border-radius: calc(var(--b-color-picker-slider-height) / 2);\n background-image: conic-gradient(\n rgba(0, 0, 0, 0.06) 0 25%,\n transparent 0 50%,\n rgba(0, 0, 0, 0.06) 0 75%,\n transparent 0\n );\n background-size: 8px 8px;\n cursor: pointer;\n touch-action: none;\n outline: none;\n}\n\n.b-color-picker__alpha::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: var(--b-color-picker-alpha-gradient);\n}\n\n.b-color-picker__alpha:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 2px;\n}\n\n.b-color-picker__alpha-handle {\n position: absolute;\n top: 50%;\n z-index: 1;\n width: var(--b-color-picker-handler-size);\n height: var(--b-color-picker-handler-size);\n border: 2px solid #fff;\n border-radius: 50%;\n box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n/* ────────────────────────────────────────────\n Input row\n ──────────────────────────────────────────── */\n.b-color-picker__input-row {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__format-btn {\n flex-shrink: 0;\n padding: 2px 4px;\n border: none;\n background: transparent;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--b-color-picker-border-radius-sm);\n line-height: 1.5;\n}\n\n.b-color-picker__format-btn:hover {\n background: rgba(0, 0, 0, 0.06);\n}\n\n.b-color-picker__format-btn:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n.b-color-picker__format-label {\n flex-shrink: 0;\n padding: 2px 4px;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n font-weight: 500;\n line-height: 1.5;\n}\n\n.b-color-picker__input {\n flex: 1;\n min-width: 0;\n height: 24px;\n padding: 0 4px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-input-border);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: var(--b-color-picker-input-bg);\n color: var(--b-color-picker-text-color);\n font-size: 12px;\n text-align: center;\n outline: none;\n}\n\n.b-color-picker__input:focus {\n border-color: #4096ff;\n}\n\n.b-color-picker__alpha-input {\n width: var(--b-color-picker-alpha-input-width);\n height: 24px;\n padding: 0 4px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-input-border);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: var(--b-color-picker-input-bg);\n color: var(--b-color-picker-text-color);\n font-size: 12px;\n text-align: center;\n outline: none;\n}\n\n.b-color-picker__alpha-input:focus {\n border-color: #4096ff;\n}\n\n/* ────────────────────────────────────────────\n Presets\n ──────────────────────────────────────────── */\n.b-color-picker__presets {\n margin-top: var(--b-color-picker-gap);\n border-top: 1px solid var(--b-color-picker-border-color);\n padding-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preset-group + .b-color-picker__preset-group {\n margin-top: var(--b-color-picker-gap);\n}\n\n.b-color-picker__preset-label {\n font-size: 12px;\n color: var(--b-color-picker-text-color-secondary);\n margin-bottom: 4px;\n}\n\n.b-color-picker__preset-colors {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.b-color-picker__preset-color {\n width: 20px;\n height: 20px;\n border: none;\n border-radius: var(--b-color-picker-color-block-border-radius);\n cursor: pointer;\n box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.2);\n padding: 0;\n transition: transform var(--b-color-picker-transition-duration);\n}\n\n.b-color-picker__preset-color:hover {\n transform: scale(1.2);\n}\n\n.b-color-picker__preset-color:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n/* ────────────────────────────────────────────\n Clear row\n ──────────────────────────────────────────── */\n.b-color-picker__clear-row {\n margin-top: var(--b-color-picker-gap);\n border-top: 1px solid var(--b-color-picker-border-color);\n padding-top: var(--b-color-picker-gap);\n display: flex;\n justify-content: flex-end;\n}\n\n.b-color-picker__clear-btn {\n padding: 2px 8px;\n border: var(--b-color-picker-border-width) solid var(--b-color-picker-border-color);\n border-radius: var(--b-color-picker-border-radius-sm);\n background: transparent;\n color: var(--b-color-picker-text-color-secondary);\n font-size: 12px;\n cursor: pointer;\n line-height: 1.5;\n}\n\n.b-color-picker__clear-btn:hover {\n border-color: #4096ff;\n color: #4096ff;\n}\n\n.b-color-picker__clear-btn:focus-visible {\n outline: 2px solid #4096ff;\n outline-offset: 1px;\n}\n\n/* ────────────────────────────────────────────\n Reduced motion\n ──────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n .b-color-picker__panel {\n transition-duration: 0ms;\n }\n\n .b-color-picker__trigger {\n transition-duration: 0ms;\n }\n\n .b-color-picker__preset-color {\n transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":""}
@@ -1,52 +1,16 @@
1
- import { computed as e, createElementBlock as t, createElementVNode as n, defineComponent as r, normalizeClass as i, openBlock as a, renderSlot as o, useSlots as s } from "vue";
2
- //#region src/components/BDivider/BDivider.vue?vue&type=script&setup=true&lang.ts
3
- var c = { class: "b-divider__content" }, l = /* @__PURE__ */ r({
4
- __name: "BDivider",
5
- props: {
6
- orientation: { default: "horizontal" },
7
- variant: { default: "solid" },
8
- dashed: {
9
- type: Boolean,
10
- default: !1
11
- },
12
- plain: {
13
- type: Boolean,
14
- default: !0
15
- },
16
- size: { default: "large" },
17
- titlePlacement: { default: "center" }
18
- },
19
- setup(r) {
20
- let l = s(), u = e(() => r.orientation === "vertical"), d = e(() => r.orientation === "horizontal"), f = e(() => !!l.default), p = e(() => r.dashed && r.variant === "solid" ? "dashed" : r.variant), m = e(() => [
21
- "b-divider",
22
- `b-divider--${r.orientation}`,
23
- `b-divider--${p.value}`,
24
- `b-divider--size-${r.size}`,
25
- {
26
- "b-divider--with-text": f.value && d.value,
27
- [`b-divider--text-${r.titlePlacement}`]: f.value && d.value,
28
- "b-divider--plain": r.plain
29
- }
30
- ]);
31
- return (e, r) => u.value ? (a(), t("span", {
32
- key: 0,
33
- class: i(m.value),
34
- role: "separator",
35
- "aria-orientation": "vertical"
36
- }, null, 2)) : d.value && !f.value ? (a(), t("div", {
37
- key: 1,
38
- class: i(m.value),
39
- role: "separator",
40
- "aria-orientation": "horizontal"
41
- }, null, 2)) : (a(), t("div", {
42
- key: 2,
43
- class: i(m.value),
44
- role: "separator",
45
- "aria-orientation": "horizontal"
46
- }, [n("span", c, [o(e.$slots, "default")])], 2));
47
- }
48
- });
1
+ //#region src/components/BDatePicker/types.ts
2
+ var e = /* @__PURE__ */ function(e) {
3
+ return e.Date = "date", e.Week = "week", e.Month = "month", e.Quarter = "quarter", e.Year = "year", e;
4
+ }({}), t = /* @__PURE__ */ function(e) {
5
+ return e.Small = "sm", e.Medium = "md", e.Large = "lg", e;
6
+ }({}), n = /* @__PURE__ */ function(e) {
7
+ return e.Outlined = "outlined", e.Filled = "filled", e.Borderless = "borderless", e.Underlined = "underlined", e;
8
+ }({}), r = /* @__PURE__ */ function(e) {
9
+ return e.Error = "error", e.Warning = "warning", e;
10
+ }({}), i = /* @__PURE__ */ function(e) {
11
+ return e.BottomLeft = "bottom-left", e.BottomRight = "bottom-right", e.TopLeft = "top-left", e.TopRight = "top-right", e;
12
+ }({});
49
13
  //#endregion
50
- export { l as default };
14
+ export { i as BDatePickerPlacement, t as BDatePickerSize, r as BDatePickerStatus, e as BDatePickerType, n as BDatePickerVariant };
51
15
 
52
16
  //# sourceMappingURL=design-system69.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"design-system69.js","names":[],"sources":["../src/components/BDivider/BDivider.vue?vue&type=script&setup=true&lang.ts"],"sourcesContent":["import { useSlots as _useSlots, defineComponent as _defineComponent } from 'vue'\nimport { normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, renderSlot as _renderSlot, createElementVNode as _createElementVNode } from \"vue\"\n\nconst _hoisted_1 = { class: \"b-divider__content\" }\n\nimport { computed } from 'vue';\nimport type {\n BDividerOrientation,\n BDividerSize,\n BDividerTitlePlacement,\n BDividerVariant,\n} from './types.ts';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\n\nexport default /*@__PURE__*/_defineComponent({\n __name: 'BDivider',\n props: {\n orientation: { default: 'horizontal' },\n variant: { default: 'solid' },\n dashed: { type: Boolean, default: false },\n plain: { type: Boolean, default: true },\n size: { default: 'large' },\n titlePlacement: { default: 'center' }\n },\n setup(__props: any) {\n\n\n\nconst slots = _useSlots();\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst isVertical = computed(() => __props.orientation === 'vertical');\nconst isHorizontal = computed(() => __props.orientation === 'horizontal');\n\n/** Whether there is slot content to render. */\nconst hasContent = computed(() => Boolean(slots.default));\n\n/**\n * Resolve the effective line style.\n * `dashed` prop is a legacy alias for `variant=\"dashed\"`.\n */\nconst effectiveVariant = computed<BDividerVariant>(() => {\n if (__props.dashed && __props.variant === 'solid') return 'dashed';\n return __props.variant;\n});\n\nconst rootClass = computed(() => [\n 'b-divider',\n `b-divider--${__props.orientation}`,\n `b-divider--${effectiveVariant.value}`,\n `b-divider--size-${__props.size}`,\n {\n 'b-divider--with-text': hasContent.value && isHorizontal.value,\n [`b-divider--text-${__props.titlePlacement}`]: hasContent.value && isHorizontal.value,\n 'b-divider--plain': __props.plain,\n },\n]);\n\nreturn (_ctx: any,_cache: any) => {\n return (isVertical.value)\n ? (_openBlock(), _createElementBlock(\"span\", {\n key: 0,\n class: _normalizeClass(rootClass.value),\n role: \"separator\",\n \"aria-orientation\": \"vertical\"\n }, null, 2))\n : (isHorizontal.value && !hasContent.value)\n ? (_openBlock(), _createElementBlock(\"div\", {\n key: 1,\n class: _normalizeClass(rootClass.value),\n role: \"separator\",\n \"aria-orientation\": \"horizontal\"\n }, null, 2))\n : (_openBlock(), _createElementBlock(\"div\", {\n key: 2,\n class: _normalizeClass(rootClass.value),\n role: \"separator\",\n \"aria-orientation\": \"horizontal\"\n }, [\n _createElementVNode(\"span\", _hoisted_1, [\n _renderSlot(_ctx.$slots, \"default\")\n ])\n ], 2))\n}\n}\n\n})"],"mappings":";;AAGA,IAAM,IAAa,EAAE,OAAO,sBAAsB,EAclD,IAA4B,kBAAiB;CAC3C,QAAQ;CACR,OAAO;EACL,aAAa,EAAE,SAAS,cAAc;EACtC,SAAS,EAAE,SAAS,SAAS;EAC7B,QAAQ;GAAE,MAAM;GAAS,SAAS;GAAO;EACzC,OAAO;GAAE,MAAM;GAAS,SAAS;GAAM;EACvC,MAAM,EAAE,SAAS,SAAS;EAC1B,gBAAgB,EAAE,SAAS,UAAU;EACtC;CACD,MAAM,GAAc;EAItB,IAAM,IAAQ,GAAW,EAKnB,IAAa,QAAe,EAAQ,gBAAgB,WAAW,EAC/D,IAAe,QAAe,EAAQ,gBAAgB,aAAa,EAGnE,IAAa,QAAe,EAAQ,EAAM,QAAS,EAMnD,IAAmB,QACnB,EAAQ,UAAU,EAAQ,YAAY,UAAgB,WACnD,EAAQ,QACf,EAEI,IAAY,QAAe;GAC/B;GACA,cAAc,EAAQ;GACtB,cAAc,EAAiB;GAC/B,mBAAmB,EAAQ;GAC3B;IACE,wBAAwB,EAAW,SAAS,EAAa;KACxD,mBAAmB,EAAQ,mBAAmB,EAAW,SAAS,EAAa;IAChF,oBAAoB,EAAQ;IAC7B;GACF,CAAC;AAEF,UAAQ,GAAU,MACR,EAAW,SACd,GAAY,EAAE,EAAoB,QAAQ;GACzC,KAAK;GACL,OAAO,EAAgB,EAAU,MAAM;GACvC,MAAM;GACN,oBAAoB;GACrB,EAAE,MAAM,EAAE,IACV,EAAa,SAAS,CAAC,EAAW,SAChC,GAAY,EAAE,EAAoB,OAAO;GACxC,KAAK;GACL,OAAO,EAAgB,EAAU,MAAM;GACvC,MAAM;GACN,oBAAoB;GACrB,EAAE,MAAM,EAAE,KACV,GAAY,EAAE,EAAoB,OAAO;GACxC,KAAK;GACL,OAAO,EAAgB,EAAU,MAAM;GACvC,MAAM;GACN,oBAAoB;GACrB,EAAE,CACD,EAAoB,QAAQ,GAAY,CACtC,EAAY,EAAK,QAAQ,UAAU,CACpC,CAAC,CACH,EAAE,EAAE;;CAIZ,CAAA"}
1
+ {"version":3,"file":"design-system69.js","names":[],"sources":["../src/components/BDatePicker/types.ts"],"sourcesContent":["export enum BDatePickerType {\n Date = 'date',\n Week = 'week',\n Month = 'month',\n Quarter = 'quarter',\n Year = 'year',\n}\n\nexport enum BDatePickerSize {\n Small = 'sm',\n Medium = 'md',\n Large = 'lg',\n}\n\nexport enum BDatePickerVariant {\n Outlined = 'outlined',\n Filled = 'filled',\n Borderless = 'borderless',\n Underlined = 'underlined',\n}\n\nexport enum BDatePickerStatus {\n Error = 'error',\n Warning = 'warning',\n}\n\nexport enum BDatePickerPlacement {\n BottomLeft = 'bottom-left',\n BottomRight = 'bottom-right',\n TopLeft = 'top-left',\n TopRight = 'top-right',\n}\n\nexport interface BDatePickerPreset {\n label: string;\n value: Date | (() => Date);\n}\n\nexport interface BDatePickerDisabledDateInfo {\n type: `${BDatePickerType}`;\n}\n"],"mappings":";AAAA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,OAAA,QACA,EAAA,OAAA,QACA,EAAA,QAAA,SACA,EAAA,UAAA,WACA,EAAA,OAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,MACA,EAAA,SAAA,MACA,EAAA,QAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,WAAA,YACA,EAAA,SAAA,UACA,EAAA,aAAA,cACA,EAAA,aAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,SACA,EAAA,UAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,aAAA,eACA,EAAA,cAAA,gBACA,EAAA,UAAA,YACA,EAAA,WAAA;KACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"design-system7.js","names":[],"sources":["../src/components/BAnchor/BAnchor.vue?vue&type=script&setup=true&lang.ts"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { createElementVNode as _createElementVNode, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, renderSlot as _renderSlot, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass, createCommentVNode as _createCommentVNode, normalizeStyle as _normalizeStyle } from \"vue\"\n\nconst _hoisted_1 = [\"aria-label\"]\nconst _hoisted_2 = {\n class: \"b-anchor__list\",\n role: \"list\"\n}\nconst _hoisted_3 = [\"href\", \"target\", \"aria-current\", \"title\", \"onClick\"]\nconst _hoisted_4 = {\n key: 0,\n class: \"b-anchor__nested\",\n role: \"list\"\n}\nconst _hoisted_5 = [\"href\", \"target\", \"aria-current\", \"title\", \"onClick\"]\n\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\n\nimport type { BAnchorDirection, BAnchorItem } from './types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\n\nexport default /*@__PURE__*/_defineComponent({\n __name: 'BAnchor',\n props: {\n affix: { type: Boolean, default: true },\n bounds: { default: 5 },\n direction: { default: 'vertical' },\n getContainer: { type: Function },\n offsetTop: { default: 0 },\n targetOffset: {},\n replace: { type: Boolean, default: false },\n items: { default: () => ([]) },\n getCurrentAnchor: { type: Function },\n modelValue: {},\n ariaLabel: { default: 'Anchor navigation' }\n },\n emits: [\"change\", \"click\", \"update:modelValue\"],\n setup(__props: any, { emit: __emit }) {\n\n\n\n// ─────────────────────────────────────────────\n// Emits\n// ─────────────────────────────────────────────\nconst emit = __emit;\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\n\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst activeLink = ref(__props.modelValue ?? '');\nconst anchorRef = ref<HTMLElement | null>(null);\nconst indicatorRef = ref<HTMLElement | null>(null);\nconst isAffixed = ref(false);\nconst scrolling = ref(false);\n\nconst isControlled = computed(() => __props.modelValue !== undefined);\n\n// Sync with controlled mode\nwatch(\n () => __props.modelValue,\n (val) => {\n if (val !== undefined) activeLink.value = val;\n },\n);\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst rootClasses = computed(() => [\n 'b-anchor',\n `b-anchor--${__props.direction}`,\n { 'b-anchor--affix': __props.affix && isAffixed.value },\n]);\n\nconst container = computed<HTMLElement | Window | null>(() => {\n if (__props.getContainer) {\n const c = __props.getContainer();\n return c || null;\n }\n return window;\n});\n\nconst scrollOffset = computed(() => __props.targetOffset ?? __props.offsetTop);\n\n// ─────────────────────────────────────────────\n// Flatten items for scroll detection\n// ─────────────────────────────────────────────\nfunction flattenItems(list: BAnchorItem[]): BAnchorItem[] {\n const flat: BAnchorItem[] = [];\n for (const item of list) {\n flat.push(item);\n if (item.children) {\n flat.push(...flattenItems(item.children));\n }\n }\n return flat;\n}\n\nconst flatItems = computed(() => flattenItems(__props.items));\n\n// ─────────────────────────────────────────────\n// Scroll tracking\n// ─────────────────────────────────────────────\nfunction getScrollTop(): number {\n const c = container.value;\n if (!c || c === window) return window.scrollY || document.documentElement.scrollTop;\n return (c as HTMLElement).scrollTop;\n}\n\nfunction getOffsetTop(element: HTMLElement): number {\n const c = container.value;\n if (!c || c === window) {\n return element.getBoundingClientRect().top + window.scrollY;\n }\n const containerRect = (c as HTMLElement).getBoundingClientRect();\n const elemRect = element.getBoundingClientRect();\n return elemRect.top - containerRect.top + (c as HTMLElement).scrollTop;\n}\n\nfunction findActiveLink(): string {\n const scrollTop = getScrollTop();\n const offset = scrollOffset.value;\n\n let active = '';\n for (const item of flatItems.value) {\n const target = document.querySelector(item.href);\n if (!target) continue;\n\n const top = getOffsetTop(target as HTMLElement) - offset - __props.bounds;\n if (top <= scrollTop) {\n active = item.href;\n }\n }\n\n if (__props.getCurrentAnchor) {\n return __props.getCurrentAnchor(active);\n }\n return active;\n}\n\nfunction handleScroll() {\n if (scrolling.value) return;\n\n const newActive = findActiveLink();\n if (newActive !== activeLink.value) {\n if (!isControlled.value) {\n activeLink.value = newActive;\n }\n emit('change', newActive);\n emit('update:modelValue', newActive);\n }\n\n updateIndicatorPosition();\n}\n\n// ─────────────────────────────────────────────\n// Indicator position\n// ─────────────────────────────────────────────\nfunction updateIndicatorPosition() {\n if (!anchorRef.value || !indicatorRef.value) return;\n\n const activeEl = anchorRef.value.querySelector<HTMLElement>(\n '.b-anchor-link--active > .b-anchor-link__title',\n );\n\n if (!activeEl) {\n indicatorRef.value.style.opacity = '0';\n return;\n }\n\n indicatorRef.value.style.opacity = '1';\n\n if (__props.direction === 'vertical') {\n const top = activeEl.offsetTop;\n const height = activeEl.offsetHeight;\n indicatorRef.value.style.top = `${top}px`;\n indicatorRef.value.style.height = `${height}px`;\n } else {\n const left = activeEl.offsetLeft;\n const width = activeEl.offsetWidth;\n indicatorRef.value.style.left = `${left}px`;\n indicatorRef.value.style.width = `${width}px`;\n }\n}\n\n// ─────────────────────────────────────────────\n// Click handling\n// ─────────────────────────────────────────────\nfunction handleLinkClick(e: MouseEvent, item: BAnchorItem) {\n emit('click', e, { href: item.href, title: item.title });\n\n if (e.defaultPrevented) return;\n\n e.preventDefault();\n\n activeLink.value = item.href;\n emit('change', item.href);\n emit('update:modelValue', item.href);\n\n const target = document.querySelector(item.href);\n if (!target) return;\n\n scrolling.value = true;\n\n const top = getOffsetTop(target as HTMLElement) - scrollOffset.value;\n const c = container.value;\n\n if (!c || c === window) {\n window.scrollTo({ top, behavior: 'smooth' });\n } else {\n (c as HTMLElement).scrollTo({ top, behavior: 'smooth' });\n }\n\n if (__props.replace) {\n window.history.replaceState(null, '', item.href);\n } else {\n window.history.pushState(null, '', item.href);\n }\n\n setTimeout(() => {\n scrolling.value = false;\n updateIndicatorPosition();\n }, 500);\n}\n\n// ─────────────────────────────────────────────\n// Affix handling\n// ─────────────────────────────────────────────\nfunction handleAffixScroll() {\n if (!__props.affix || !anchorRef.value) return;\n const rect = anchorRef.value.getBoundingClientRect();\n isAffixed.value = rect.top <= __props.offsetTop;\n}\n\n// ─────────────────────────────────────────────\n// Lifecycle - attach scroll listener reactively\n// ─────────────────────────────────────────────\nlet scrollHandler: (() => void) | null = null;\nlet currentContainer: HTMLElement | Window | null = null;\n\nfunction attachScrollListener(c: HTMLElement | Window | null) {\n if (!c) return;\n scrollHandler = () => {\n handleScroll();\n handleAffixScroll();\n };\n c.addEventListener('scroll', scrollHandler, { passive: true });\n currentContainer = c;\n\n // Initial detection\n nextTick(() => {\n handleScroll();\n updateIndicatorPosition();\n });\n}\n\nfunction detachScrollListener() {\n if (scrollHandler && currentContainer) {\n currentContainer.removeEventListener('scroll', scrollHandler);\n }\n scrollHandler = null;\n currentContainer = null;\n}\n\nwatch(\n container,\n (newC, oldC) => {\n if (oldC && oldC !== newC) detachScrollListener();\n if (newC) attachScrollListener(newC);\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n detachScrollListener();\n});\n\n// Update indicator when active link changes\nwatch(activeLink, () => {\n requestAnimationFrame(updateIndicatorPosition);\n});\n\nreturn (_ctx: any,_cache: any) => {\n return (_openBlock(), _createElementBlock(\"nav\", {\n ref_key: \"anchorRef\",\n ref: anchorRef,\n class: _normalizeClass(rootClasses.value),\n role: \"navigation\",\n \"aria-label\": __props.ariaLabel,\n style: _normalizeStyle(__props.affix && isAffixed.value ? { position: 'fixed', top: `${__props.offsetTop}px` } : undefined)\n }, [\n _createElementVNode(\"div\", {\n ref_key: \"indicatorRef\",\n ref: indicatorRef,\n class: \"b-anchor__indicator\",\n \"aria-hidden\": \"true\"\n }, null, 512),\n _createElementVNode(\"div\", _hoisted_2, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(__props.items, (item) => {\n return (_openBlock(), _createElementBlock(\"div\", {\n key: item.key,\n class: _normalizeClass([\"b-anchor-link\", [{ 'b-anchor-link--active': activeLink.value === item.href }, item.className]]),\n role: \"listitem\"\n }, [\n _createElementVNode(\"a\", {\n class: \"b-anchor-link__title\",\n href: item.href,\n target: item.target,\n \"aria-current\": activeLink.value === item.href ? 'location' : undefined,\n title: item.title,\n onClick: ($event: any) => (handleLinkClick($event, item))\n }, [\n _renderSlot(_ctx.$slots, \"itemTitle\", {\n item: item,\n active: activeLink.value === item.href\n }, () => [\n _createTextVNode(_toDisplayString(item.title), 1)\n ])\n ], 8, _hoisted_3),\n (__props.direction === 'vertical' && item.children?.length)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_4, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(item.children, (child) => {\n return (_openBlock(), _createElementBlock(\"div\", {\n key: child.key,\n class: _normalizeClass([\"b-anchor-link b-anchor-link--child\", [{ 'b-anchor-link--active': activeLink.value === child.href }, child.className]]),\n role: \"listitem\"\n }, [\n _createElementVNode(\"a\", {\n class: \"b-anchor-link__title\",\n href: child.href,\n target: child.target,\n \"aria-current\": activeLink.value === child.href ? 'location' : undefined,\n title: child.title,\n onClick: ($event: any) => (handleLinkClick($event, child))\n }, [\n _renderSlot(_ctx.$slots, \"itemTitle\", {\n item: child,\n active: activeLink.value === child.href\n }, () => [\n _createTextVNode(_toDisplayString(child.title), 1)\n ])\n ], 8, _hoisted_5)\n ], 2))\n }), 128))\n ]))\n : _createCommentVNode(\"\", true)\n ], 2))\n }), 128))\n ])\n ], 14, _hoisted_1))\n}\n}\n\n})"],"mappings":"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"}
1
+ {"version":3,"file":"design-system7.js","names":[],"sources":["../src/components/BAnchor/BAnchor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';\n\nimport type { BAnchorDirection, BAnchorItem } from './types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n affix = true,\n bounds = 5,\n direction = 'vertical',\n getContainer,\n offsetTop = 0,\n targetOffset,\n replace = false,\n items = [],\n getCurrentAnchor,\n modelValue,\n ariaLabel = 'Anchor navigation',\n} = defineProps<{\n /** Whether to show affix (fixed positioning) */\n affix?: boolean;\n /** Bounding distance of anchor area in pixels */\n bounds?: number;\n /** Layout direction */\n direction?: BAnchorDirection;\n /** Scrolling container reference */\n getContainer?: () => HTMLElement | Window;\n /** Pixels to offset from top when calculating scroll position */\n offsetTop?: number;\n /** Anchor scroll offset for target elements */\n targetOffset?: number;\n /** Whether to replace browser history instead of push */\n replace?: boolean;\n /** Data-driven link items */\n items?: BAnchorItem[];\n /** Custom logic to determine the current active link */\n getCurrentAnchor?: (activeLink: string) => string;\n /** Currently active link (controlled mode via v-model) */\n modelValue?: string;\n /** Accessible label for the navigation landmark */\n ariaLabel?: string;\n}>();\n\n// ─────────────────────────────────────────────\n// Emits\n// ─────────────────────────────────────────────\nconst emit = defineEmits<{\n /** Fires when active anchor changes */\n change: [currentActiveLink: string];\n /** Custom click handler for anchor links */\n click: [e: MouseEvent, link: { href: string; title: string }];\n /** v-model update */\n 'update:modelValue': [value: string];\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Custom rendering of anchor item title */\n itemTitle?(props: { item: BAnchorItem; active: boolean }): unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst activeLink = ref(modelValue ?? '');\nconst anchorRef = ref<HTMLElement | null>(null);\nconst indicatorRef = ref<HTMLElement | null>(null);\nconst isAffixed = ref(false);\nconst scrolling = ref(false);\n\nconst isControlled = computed(() => modelValue !== undefined);\n\n// Sync with controlled mode\nwatch(\n () => modelValue,\n (val) => {\n if (val !== undefined) activeLink.value = val;\n },\n);\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst rootClasses = computed(() => [\n 'b-anchor',\n `b-anchor--${direction}`,\n { 'b-anchor--affix': affix && isAffixed.value },\n]);\n\nconst container = computed<HTMLElement | Window | null>(() => {\n if (getContainer) {\n const c = getContainer();\n return c || null;\n }\n return window;\n});\n\nconst scrollOffset = computed(() => targetOffset ?? offsetTop);\n\n// ─────────────────────────────────────────────\n// Flatten items for scroll detection\n// ─────────────────────────────────────────────\nfunction flattenItems(list: BAnchorItem[]): BAnchorItem[] {\n const flat: BAnchorItem[] = [];\n for (const item of list) {\n flat.push(item);\n if (item.children) {\n flat.push(...flattenItems(item.children));\n }\n }\n return flat;\n}\n\nconst flatItems = computed(() => flattenItems(items));\n\n// ─────────────────────────────────────────────\n// Scroll tracking\n// ─────────────────────────────────────────────\nfunction getScrollTop(): number {\n const c = container.value;\n if (!c || c === window) return window.scrollY || document.documentElement.scrollTop;\n return (c as HTMLElement).scrollTop;\n}\n\nfunction getOffsetTop(element: HTMLElement): number {\n const c = container.value;\n if (!c || c === window) {\n return element.getBoundingClientRect().top + window.scrollY;\n }\n const containerRect = (c as HTMLElement).getBoundingClientRect();\n const elemRect = element.getBoundingClientRect();\n return elemRect.top - containerRect.top + (c as HTMLElement).scrollTop;\n}\n\nfunction findActiveLink(): string {\n const scrollTop = getScrollTop();\n const offset = scrollOffset.value;\n\n let active = '';\n for (const item of flatItems.value) {\n const target = document.querySelector(item.href);\n if (!target) continue;\n\n const top = getOffsetTop(target as HTMLElement) - offset - bounds;\n if (top <= scrollTop) {\n active = item.href;\n }\n }\n\n if (getCurrentAnchor) {\n return getCurrentAnchor(active);\n }\n return active;\n}\n\nfunction handleScroll() {\n if (scrolling.value) return;\n\n const newActive = findActiveLink();\n if (newActive !== activeLink.value) {\n if (!isControlled.value) {\n activeLink.value = newActive;\n }\n emit('change', newActive);\n emit('update:modelValue', newActive);\n }\n\n updateIndicatorPosition();\n}\n\n// ─────────────────────────────────────────────\n// Indicator position\n// ─────────────────────────────────────────────\nfunction updateIndicatorPosition() {\n if (!anchorRef.value || !indicatorRef.value) return;\n\n const activeEl = anchorRef.value.querySelector<HTMLElement>(\n '.b-anchor-link--active > .b-anchor-link__title',\n );\n\n if (!activeEl) {\n indicatorRef.value.style.opacity = '0';\n return;\n }\n\n indicatorRef.value.style.opacity = '1';\n\n if (direction === 'vertical') {\n const top = activeEl.offsetTop;\n const height = activeEl.offsetHeight;\n indicatorRef.value.style.top = `${top}px`;\n indicatorRef.value.style.height = `${height}px`;\n } else {\n const left = activeEl.offsetLeft;\n const width = activeEl.offsetWidth;\n indicatorRef.value.style.left = `${left}px`;\n indicatorRef.value.style.width = `${width}px`;\n }\n}\n\n// ─────────────────────────────────────────────\n// Click handling\n// ─────────────────────────────────────────────\nfunction handleLinkClick(e: MouseEvent, item: BAnchorItem) {\n emit('click', e, { href: item.href, title: item.title });\n\n if (e.defaultPrevented) return;\n\n e.preventDefault();\n\n activeLink.value = item.href;\n emit('change', item.href);\n emit('update:modelValue', item.href);\n\n const target = document.querySelector(item.href);\n if (!target) return;\n\n scrolling.value = true;\n\n const top = getOffsetTop(target as HTMLElement) - scrollOffset.value;\n const c = container.value;\n\n if (!c || c === window) {\n window.scrollTo({ top, behavior: 'smooth' });\n } else {\n (c as HTMLElement).scrollTo({ top, behavior: 'smooth' });\n }\n\n if (replace) {\n window.history.replaceState(null, '', item.href);\n } else {\n window.history.pushState(null, '', item.href);\n }\n\n setTimeout(() => {\n scrolling.value = false;\n updateIndicatorPosition();\n }, 500);\n}\n\n// ─────────────────────────────────────────────\n// Affix handling\n// ─────────────────────────────────────────────\nfunction handleAffixScroll() {\n if (!affix || !anchorRef.value) return;\n const rect = anchorRef.value.getBoundingClientRect();\n isAffixed.value = rect.top <= offsetTop;\n}\n\n// ─────────────────────────────────────────────\n// Lifecycle - attach scroll listener reactively\n// ─────────────────────────────────────────────\nlet scrollHandler: (() => void) | null = null;\nlet currentContainer: HTMLElement | Window | null = null;\n\nfunction attachScrollListener(c: HTMLElement | Window | null) {\n if (!c) return;\n scrollHandler = () => {\n handleScroll();\n handleAffixScroll();\n };\n c.addEventListener('scroll', scrollHandler, { passive: true });\n currentContainer = c;\n\n // Initial detection\n nextTick(() => {\n handleScroll();\n updateIndicatorPosition();\n });\n}\n\nfunction detachScrollListener() {\n if (scrollHandler && currentContainer) {\n currentContainer.removeEventListener('scroll', scrollHandler);\n }\n scrollHandler = null;\n currentContainer = null;\n}\n\nwatch(\n container,\n (newC, oldC) => {\n if (oldC && oldC !== newC) detachScrollListener();\n if (newC) attachScrollListener(newC);\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n detachScrollListener();\n});\n\n// Update indicator when active link changes\nwatch(activeLink, () => {\n requestAnimationFrame(updateIndicatorPosition);\n});\n</script>\n\n<template>\n <nav\n ref=\"anchorRef\"\n :class=\"rootClasses\"\n role=\"navigation\"\n :aria-label=\"ariaLabel\"\n :style=\"affix && isAffixed ? { position: 'fixed', top: `${offsetTop}px` } : undefined\"\n >\n <div ref=\"indicatorRef\" class=\"b-anchor__indicator\" aria-hidden=\"true\" />\n\n <div class=\"b-anchor__list\" role=\"list\">\n <template v-for=\"item in items\" :key=\"item.key\">\n <div\n class=\"b-anchor-link\"\n :class=\"[{ 'b-anchor-link--active': activeLink === item.href }, item.className]\"\n role=\"listitem\"\n >\n <a\n class=\"b-anchor-link__title\"\n :href=\"item.href\"\n :target=\"item.target\"\n :aria-current=\"activeLink === item.href ? 'location' : undefined\"\n :title=\"item.title\"\n @click=\"handleLinkClick($event, item)\"\n >\n <slot name=\"itemTitle\" :item=\"item\" :active=\"activeLink === item.href\">\n {{ item.title }}\n </slot>\n </a>\n\n <!-- Nested children (vertical only) -->\n <div\n v-if=\"direction === 'vertical' && item.children?.length\"\n class=\"b-anchor__nested\"\n role=\"list\"\n >\n <div\n v-for=\"child in item.children\"\n :key=\"child.key\"\n class=\"b-anchor-link b-anchor-link--child\"\n :class=\"[{ 'b-anchor-link--active': activeLink === child.href }, child.className]\"\n role=\"listitem\"\n >\n <a\n class=\"b-anchor-link__title\"\n :href=\"child.href\"\n :target=\"child.target\"\n :aria-current=\"activeLink === child.href ? 'location' : undefined\"\n :title=\"child.title\"\n @click=\"handleLinkClick($event, child)\"\n >\n <slot name=\"itemTitle\" :item=\"child\" :active=\"activeLink === child.href\">\n {{ child.title }}\n </slot>\n </a>\n </div>\n </div>\n </div>\n </template>\n </div>\n </nav>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BAnchor - CSS custom properties (scoped to root)\n ───────────────────────────────────────────── */\n.b-anchor {\n --b-anchor-link-padding-block: 4px;\n --b-anchor-link-padding-inline-start: 16px;\n --b-anchor-indicator-color: oklch(54.6% 0.245 262.881);\n --b-anchor-indicator-width: 2px;\n --b-anchor-link-color: oklch(40% 0.01 260);\n --b-anchor-link-color-active: oklch(54.6% 0.245 262.881);\n --b-anchor-link-color-hover: oklch(54.6% 0.245 262.881);\n --b-anchor-background: transparent;\n --b-anchor-font-size: 14px;\n --b-anchor-line-height: 1.5;\n --b-anchor-transition-duration: 200ms;\n --b-anchor-border-color: oklch(90% 0.005 260);\n --b-anchor-child-indent: 16px;\n\n position: relative;\n font-size: var(--b-anchor-font-size);\n line-height: var(--b-anchor-line-height);\n background: var(--b-anchor-background);\n box-sizing: border-box;\n}\n\n/* ─────────────────────────────────────────────\n Vertical layout\n ───────────────────────────────────────────── */\n.b-anchor--vertical .b-anchor__list {\n border-left: var(--b-anchor-indicator-width) solid var(--b-anchor-border-color);\n padding-left: 0;\n}\n\n.b-anchor--vertical .b-anchor__indicator {\n position: absolute;\n left: 0;\n width: var(--b-anchor-indicator-width);\n background: var(--b-anchor-indicator-color);\n border-radius: 1px;\n opacity: 0;\n transition:\n top var(--b-anchor-transition-duration) ease,\n height var(--b-anchor-transition-duration) ease,\n opacity var(--b-anchor-transition-duration) ease;\n}\n\n.b-anchor--vertical .b-anchor-link__title {\n display: block;\n padding: var(--b-anchor-link-padding-block) var(--b-anchor-link-padding-block)\n var(--b-anchor-link-padding-block) var(--b-anchor-link-padding-inline-start);\n}\n\n.b-anchor--vertical .b-anchor-link--child .b-anchor-link__title {\n padding-left: calc(var(--b-anchor-link-padding-inline-start) + var(--b-anchor-child-indent));\n}\n\n/* ─────────────────────────────────────────────\n Horizontal layout\n ───────────────────────────────────────────── */\n.b-anchor--horizontal .b-anchor__list {\n display: flex;\n flex-direction: row;\n border-bottom: var(--b-anchor-indicator-width) solid var(--b-anchor-border-color);\n}\n\n.b-anchor--horizontal .b-anchor__indicator {\n position: absolute;\n bottom: 0;\n height: var(--b-anchor-indicator-width);\n background: var(--b-anchor-indicator-color);\n border-radius: 1px;\n opacity: 0;\n transition:\n left var(--b-anchor-transition-duration) ease,\n width var(--b-anchor-transition-duration) ease,\n opacity var(--b-anchor-transition-duration) ease;\n}\n\n.b-anchor--horizontal .b-anchor-link__title {\n display: block;\n padding: var(--b-anchor-link-padding-block) var(--b-anchor-link-padding-inline-start);\n white-space: nowrap;\n}\n\n/* ─────────────────────────────────────────────\n Anchor link\n ───────────────────────────────────────────── */\n.b-anchor-link {\n box-sizing: border-box;\n}\n\n.b-anchor-link__title {\n color: var(--b-anchor-link-color);\n text-decoration: none;\n font-size: inherit;\n line-height: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: color var(--b-anchor-transition-duration) ease;\n outline: none;\n border-radius: 2px;\n}\n\n.b-anchor-link__title:hover {\n color: var(--b-anchor-link-color-hover);\n}\n\n.b-anchor-link__title:focus-visible {\n outline: 2px solid var(--b-anchor-indicator-color);\n outline-offset: 2px;\n}\n\n.b-anchor-link--active > .b-anchor-link__title {\n color: var(--b-anchor-link-color-active);\n}\n\n/* ─────────────────────────────────────────────\n Affix\n ───────────────────────────────────────────── */\n.b-anchor--affix {\n z-index: 10;\n}\n\n/* ─────────────────────────────────────────────\n Dark mode\n ───────────────────────────────────────────── */\n[data-prefers-color='dark'] .b-anchor {\n --b-anchor-link-color: oklch(72% 0.01 260);\n --b-anchor-link-color-active: oklch(70% 0.18 262);\n --b-anchor-link-color-hover: oklch(70% 0.18 262);\n --b-anchor-indicator-color: oklch(70% 0.18 262);\n --b-anchor-border-color: oklch(35% 0.01 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-anchor {\n --b-anchor-link-color: oklch(72% 0.01 260);\n --b-anchor-link-color-active: oklch(70% 0.18 262);\n --b-anchor-link-color-hover: oklch(70% 0.18 262);\n --b-anchor-indicator-color: oklch(70% 0.18 262);\n --b-anchor-border-color: oklch(35% 0.01 260);\n }\n}\n\n/* ─────────────────────────────────────────────\n Reduced motion\n ───────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n .b-anchor {\n --b-anchor-transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":"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"}