@7pmlabs/design-system 2.0.9 → 2.1.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 (377) hide show
  1. package/README.md +4 -4
  2. package/dist/design-system.css +1 -1
  3. package/dist/design-system.js +65 -59
  4. package/dist/design-system100.js +1 -1
  5. package/dist/design-system100.js.map +1 -1
  6. package/dist/design-system101.js +87 -53
  7. package/dist/design-system101.js.map +1 -1
  8. package/dist/design-system103.js +5 -13
  9. package/dist/design-system103.js.map +1 -1
  10. package/dist/design-system104.js +53 -108
  11. package/dist/design-system104.js.map +1 -1
  12. package/dist/{design-system102.js → design-system105.js} +1 -1
  13. package/dist/{design-system102.js.map → design-system105.js.map} +1 -1
  14. package/dist/design-system106.js +13 -6
  15. package/dist/design-system106.js.map +1 -1
  16. package/dist/design-system107.js +93 -190
  17. package/dist/design-system107.js.map +1 -1
  18. package/dist/design-system109.js +2 -2
  19. package/dist/design-system109.js.map +1 -1
  20. package/dist/design-system110.js +183 -484
  21. package/dist/design-system110.js.map +1 -1
  22. package/dist/design-system112.js +5 -4
  23. package/dist/design-system112.js.map +1 -1
  24. package/dist/design-system113.js +507 -7
  25. package/dist/design-system113.js.map +1 -1
  26. package/dist/design-system115.js +8 -0
  27. package/dist/design-system115.js.map +1 -0
  28. package/dist/design-system116.js +7 -6
  29. package/dist/design-system116.js.map +1 -1
  30. package/dist/design-system117.js +154 -169
  31. package/dist/design-system117.js.map +1 -1
  32. package/dist/design-system119.js +2 -2
  33. package/dist/design-system119.js.map +1 -1
  34. package/dist/design-system120.js +210 -149
  35. package/dist/design-system120.js.map +1 -1
  36. package/dist/design-system122.js +5 -4
  37. package/dist/design-system122.js.map +1 -1
  38. package/dist/design-system123.js +160 -9
  39. package/dist/design-system123.js.map +1 -1
  40. package/dist/design-system125.js +8 -0
  41. package/dist/design-system125.js.map +1 -0
  42. package/dist/design-system126.js +176 -6
  43. package/dist/design-system126.js.map +1 -1
  44. package/dist/design-system128.js +8 -0
  45. package/dist/design-system128.js.map +1 -0
  46. package/dist/design-system129.js +213 -5
  47. package/dist/design-system129.js.map +1 -1
  48. package/dist/design-system131.js +5 -90
  49. package/dist/design-system131.js.map +1 -1
  50. package/dist/design-system132.js +166 -0
  51. package/dist/design-system132.js.map +1 -0
  52. package/dist/design-system134.js +5 -42
  53. package/dist/design-system134.js.map +1 -1
  54. package/dist/design-system135.js +12 -0
  55. package/dist/design-system135.js.map +1 -0
  56. package/dist/design-system136.js +274 -5
  57. package/dist/design-system136.js.map +1 -1
  58. package/dist/design-system138.js +9 -0
  59. package/dist/{design-system124.js.map → design-system138.js.map} +1 -1
  60. package/dist/design-system139.js +16 -5
  61. package/dist/design-system139.js.map +1 -1
  62. package/dist/design-system141.js +8 -0
  63. package/dist/{design-system127.js.map → design-system141.js.map} +1 -1
  64. package/dist/design-system142.js +12 -5
  65. package/dist/design-system142.js.map +1 -1
  66. package/dist/design-system143.js +78 -83
  67. package/dist/design-system143.js.map +1 -1
  68. package/dist/design-system145.js +1 -1
  69. package/dist/design-system145.js.map +1 -1
  70. package/dist/design-system146.js +42 -9
  71. package/dist/design-system146.js.map +1 -1
  72. package/dist/design-system148.js +3 -2
  73. package/dist/design-system148.js.map +1 -1
  74. package/dist/design-system149.js +230 -18
  75. package/dist/design-system149.js.map +1 -1
  76. package/dist/design-system151.js +5 -158
  77. package/dist/design-system151.js.map +1 -1
  78. package/dist/{design-system140.js → design-system152.js} +6 -6
  79. package/dist/{design-system140.js.map → design-system152.js.map} +1 -1
  80. package/dist/design-system154.js +5 -307
  81. package/dist/design-system154.js.map +1 -1
  82. package/dist/design-system155.js +98 -0
  83. package/dist/design-system155.js.map +1 -0
  84. package/dist/design-system157.js +5 -240
  85. package/dist/design-system157.js.map +1 -1
  86. package/dist/design-system158.js +12 -0
  87. package/dist/design-system158.js.map +1 -0
  88. package/dist/design-system159.js +37 -5
  89. package/dist/design-system159.js.map +1 -1
  90. package/dist/design-system160.js +4 -189
  91. package/dist/design-system160.js.map +1 -1
  92. package/dist/design-system161.js +24 -0
  93. package/dist/{design-system150.js.map → design-system161.js.map} +1 -1
  94. package/dist/design-system162.js +2 -3
  95. package/dist/design-system162.js.map +1 -1
  96. package/dist/design-system163.js +158 -3
  97. package/dist/design-system163.js.map +1 -1
  98. package/dist/{design-system153.js → design-system165.js} +2 -2
  99. package/dist/{design-system153.js.map → design-system165.js.map} +1 -1
  100. package/dist/design-system166.js +307 -6
  101. package/dist/design-system166.js.map +1 -1
  102. package/dist/{design-system156.js → design-system168.js} +2 -2
  103. package/dist/{design-system156.js.map → design-system168.js.map} +1 -1
  104. package/dist/design-system169.js +167 -6
  105. package/dist/design-system169.js.map +1 -1
  106. package/dist/design-system171.js +8 -0
  107. package/dist/design-system171.js.map +1 -0
  108. package/dist/design-system172.js +240 -6
  109. package/dist/design-system172.js.map +1 -1
  110. package/dist/design-system174.js +8 -0
  111. package/dist/design-system174.js.map +1 -0
  112. package/dist/design-system175.js +189 -6
  113. package/dist/design-system175.js.map +1 -1
  114. package/dist/design-system177.js +8 -0
  115. package/dist/design-system177.js.map +1 -0
  116. package/dist/design-system178.js +3 -5
  117. package/dist/design-system178.js.map +1 -1
  118. package/dist/design-system179.js +58 -11
  119. package/dist/design-system179.js.map +1 -1
  120. package/dist/design-system181.js +9 -0
  121. package/dist/design-system181.js.map +1 -0
  122. package/dist/design-system182.js +56 -6
  123. package/dist/design-system182.js.map +1 -1
  124. package/dist/design-system184.js +9 -0
  125. package/dist/{design-system167.js.map → design-system184.js.map} +1 -1
  126. package/dist/design-system185.js +69 -5
  127. package/dist/design-system185.js.map +1 -1
  128. package/dist/design-system187.js +9 -0
  129. package/dist/{design-system170.js.map → design-system187.js.map} +1 -1
  130. package/dist/design-system188.js +182 -5
  131. package/dist/design-system188.js.map +1 -1
  132. package/dist/design-system190.js +9 -0
  133. package/dist/design-system190.js.map +1 -0
  134. package/dist/design-system191.js +115 -5
  135. package/dist/design-system191.js.map +1 -1
  136. package/dist/design-system193.js +8 -0
  137. package/dist/{design-system176.js.map → design-system193.js.map} +1 -1
  138. package/dist/design-system194.js +11 -5
  139. package/dist/design-system194.js.map +1 -1
  140. package/dist/design-system195.js +453 -24
  141. package/dist/design-system195.js.map +1 -1
  142. package/dist/design-system197.js +5 -4
  143. package/dist/design-system197.js.map +1 -1
  144. package/dist/design-system198.js +20 -16
  145. package/dist/design-system198.js.map +1 -1
  146. package/dist/design-system200.js +1 -1
  147. package/dist/design-system200.js.map +1 -1
  148. package/dist/design-system201.js +70 -314
  149. package/dist/design-system201.js.map +1 -1
  150. package/dist/design-system203.js +1 -1
  151. package/dist/design-system203.js.map +1 -1
  152. package/dist/design-system204.js +24 -89
  153. package/dist/design-system204.js.map +1 -1
  154. package/dist/design-system206.js +1 -1
  155. package/dist/design-system206.js.map +1 -1
  156. package/dist/design-system207.js +26 -17
  157. package/dist/design-system207.js.map +1 -1
  158. package/dist/design-system209.js +5 -3
  159. package/dist/design-system209.js.map +1 -1
  160. package/dist/design-system210.js +22 -408
  161. package/dist/design-system210.js.map +1 -1
  162. package/dist/design-system212.js +1 -1
  163. package/dist/design-system212.js.map +1 -1
  164. package/dist/design-system213.js +24 -52
  165. package/dist/design-system213.js.map +1 -1
  166. package/dist/design-system215.js +1 -1
  167. package/dist/design-system215.js.map +1 -1
  168. package/dist/design-system216.js +329 -85
  169. package/dist/design-system216.js.map +1 -1
  170. package/dist/design-system218.js +5 -108
  171. package/dist/design-system218.js.map +1 -1
  172. package/dist/design-system219.js +103 -0
  173. package/dist/design-system219.js.map +1 -0
  174. package/dist/design-system221.js +5 -106
  175. package/dist/design-system221.js.map +1 -1
  176. package/dist/design-system222.js +22 -0
  177. package/dist/{design-system208.js.map → design-system222.js.map} +1 -1
  178. package/dist/design-system223.js +4 -6
  179. package/dist/design-system223.js.map +1 -1
  180. package/dist/design-system224.js +3 -737
  181. package/dist/design-system224.js.map +1 -1
  182. package/dist/design-system225.js +422 -0
  183. package/dist/design-system225.js.map +1 -0
  184. package/dist/design-system227.js +5 -11
  185. package/dist/design-system227.js.map +1 -1
  186. package/dist/design-system228.js +51 -517
  187. package/dist/design-system228.js.map +1 -1
  188. package/dist/design-system230.js +1 -1
  189. package/dist/design-system230.js.map +1 -1
  190. package/dist/design-system231.js +88 -3
  191. package/dist/design-system231.js.map +1 -1
  192. package/dist/design-system232.js +4 -46
  193. package/dist/design-system232.js.map +1 -1
  194. package/dist/design-system233.js +108 -4
  195. package/dist/design-system233.js.map +1 -1
  196. package/dist/{design-system220.js → design-system235.js} +2 -2
  197. package/dist/{design-system220.js.map → design-system235.js.map} +1 -1
  198. package/dist/design-system236.js +106 -5
  199. package/dist/design-system236.js.map +1 -1
  200. package/dist/design-system238.js +9 -0
  201. package/dist/design-system238.js.map +1 -0
  202. package/dist/design-system239.js +737 -5
  203. package/dist/design-system239.js.map +1 -1
  204. package/dist/{design-system226.js → design-system241.js} +2 -2
  205. package/dist/{design-system226.js.map → design-system241.js.map} +1 -1
  206. package/dist/design-system242.js +3 -5
  207. package/dist/design-system242.js.map +1 -1
  208. package/dist/design-system243.js +42 -50
  209. package/dist/design-system243.js.map +1 -1
  210. package/dist/design-system244.js +1 -1
  211. package/dist/design-system244.js.map +1 -1
  212. package/dist/design-system245.js +254 -141
  213. package/dist/design-system245.js.map +1 -1
  214. package/dist/design-system247.js +1 -1
  215. package/dist/design-system247.js.map +1 -1
  216. package/dist/design-system248.js +119 -7
  217. package/dist/design-system248.js.map +1 -1
  218. package/dist/design-system250.js +8 -0
  219. package/dist/design-system250.js.map +1 -0
  220. package/dist/design-system251.js +172 -5
  221. package/dist/design-system251.js.map +1 -1
  222. package/dist/design-system253.js +8 -0
  223. package/dist/design-system253.js.map +1 -0
  224. package/dist/design-system254.js +11 -6
  225. package/dist/design-system254.js.map +1 -1
  226. package/dist/design-system255.js +525 -9
  227. package/dist/design-system255.js.map +1 -1
  228. package/dist/design-system257.js +8 -0
  229. package/dist/design-system257.js.map +1 -0
  230. package/dist/design-system258.js +112 -6
  231. package/dist/design-system258.js.map +1 -1
  232. package/dist/design-system260.js +5 -374
  233. package/dist/design-system260.js.map +1 -1
  234. package/dist/design-system261.js +57 -0
  235. package/dist/design-system261.js.map +1 -0
  236. package/dist/design-system262.js +4 -6
  237. package/dist/design-system262.js.map +1 -1
  238. package/dist/design-system263.js +173 -0
  239. package/dist/design-system263.js.map +1 -0
  240. package/dist/design-system265.js +8 -0
  241. package/dist/design-system265.js.map +1 -0
  242. package/dist/design-system266.js +10 -0
  243. package/dist/design-system266.js.map +1 -0
  244. package/dist/{design-system249.js → design-system267.js} +2 -2
  245. package/dist/{design-system249.js.map → design-system267.js.map} +1 -1
  246. package/dist/design-system269.js +8 -0
  247. package/dist/design-system269.js.map +1 -0
  248. package/dist/{design-system252.js → design-system270.js} +1 -1
  249. package/dist/{design-system252.js.map → design-system270.js.map} +1 -1
  250. package/dist/design-system272.js +9 -0
  251. package/dist/design-system272.js.map +1 -0
  252. package/dist/design-system273.js +12 -0
  253. package/dist/design-system273.js.map +1 -0
  254. package/dist/{design-system256.js → design-system274.js} +2 -2
  255. package/dist/{design-system256.js.map → design-system274.js.map} +1 -1
  256. package/dist/design-system276.js +9 -0
  257. package/dist/design-system276.js.map +1 -0
  258. package/dist/{design-system259.js → design-system277.js} +1 -1
  259. package/dist/{design-system259.js.map → design-system277.js.map} +1 -1
  260. package/dist/design-system278.js +377 -0
  261. package/dist/design-system278.js.map +1 -0
  262. package/dist/design-system280.js +9 -0
  263. package/dist/design-system280.js.map +1 -0
  264. package/dist/design-system69.js +182 -13
  265. package/dist/design-system69.js.map +1 -1
  266. package/dist/design-system71.js +8 -0
  267. package/dist/design-system71.js.map +1 -0
  268. package/dist/design-system72.js +13 -5
  269. package/dist/design-system72.js.map +1 -1
  270. package/dist/design-system73.js +677 -139
  271. package/dist/design-system73.js.map +1 -1
  272. package/dist/design-system75.js +1 -1
  273. package/dist/design-system75.js.map +1 -1
  274. package/dist/design-system76.js +152 -23
  275. package/dist/design-system76.js.map +1 -1
  276. package/dist/design-system78.js +5 -49
  277. package/dist/design-system78.js.map +1 -1
  278. package/dist/design-system79.js +32 -0
  279. package/dist/design-system79.js.map +1 -0
  280. package/dist/design-system80.js +2 -3
  281. package/dist/design-system80.js.map +1 -1
  282. package/dist/design-system81.js +38 -188
  283. package/dist/design-system81.js.map +1 -1
  284. package/dist/design-system83.js +1 -1
  285. package/dist/design-system83.js.map +1 -1
  286. package/dist/design-system84.js +199 -7
  287. package/dist/design-system84.js.map +1 -1
  288. package/dist/design-system86.js +8 -0
  289. package/dist/design-system86.js.map +1 -0
  290. package/dist/design-system87.js +7 -5
  291. package/dist/design-system87.js.map +1 -1
  292. package/dist/design-system88.js +264 -48
  293. package/dist/design-system88.js.map +1 -1
  294. package/dist/design-system90.js +1 -1
  295. package/dist/design-system90.js.map +1 -1
  296. package/dist/design-system91.js +57 -11
  297. package/dist/design-system91.js.map +1 -1
  298. package/dist/design-system93.js +8 -0
  299. package/dist/design-system93.js.map +1 -0
  300. package/dist/design-system94.js +11 -5
  301. package/dist/design-system94.js.map +1 -1
  302. package/dist/design-system95.js +92 -59
  303. package/dist/design-system95.js.map +1 -1
  304. package/dist/design-system97.js +1 -1
  305. package/dist/design-system97.js.map +1 -1
  306. package/dist/design-system98.js +56 -78
  307. package/dist/design-system98.js.map +1 -1
  308. package/dist/types/components/BContextMenu/BContextMenu.spec.d.ts +1 -0
  309. package/dist/types/components/BContextMenu/BContextMenu.vue.d.ts +42 -0
  310. package/dist/types/components/BContextMenu/index.d.ts +2 -0
  311. package/dist/types/components/BContextMenu/types.d.ts +23 -0
  312. package/dist/types/components/BInputTags/BInputTags.spec.d.ts +1 -0
  313. package/dist/types/components/BInputTags/BInputTags.vue.d.ts +54 -0
  314. package/dist/types/components/BInputTags/index.d.ts +1 -0
  315. package/dist/types/components/BLink/BLink.spec.d.ts +1 -0
  316. package/dist/types/components/BLink/BLink.vue.d.ts +100 -0
  317. package/dist/types/components/BLink/index.d.ts +1 -0
  318. package/dist/types/components/BListbox/BListbox.spec.d.ts +1 -0
  319. package/dist/types/components/BListbox/BListbox.vue.d.ts +52 -0
  320. package/dist/types/components/BListbox/index.d.ts +1 -0
  321. package/dist/types/components/BModal/BModal.spec.d.ts +1 -0
  322. package/dist/types/components/BPinInput/BPinInput.spec.d.ts +1 -0
  323. package/dist/types/components/BPinInput/BPinInput.vue.d.ts +43 -0
  324. package/dist/types/components/BPinInput/index.d.ts +1 -0
  325. package/dist/types/components/BProgress/BProgress.vue.d.ts +47 -2
  326. package/dist/types/components/BTextarea/BTextarea.spec.d.ts +1 -0
  327. package/dist/types/components/BTextarea/BTextarea.vue.d.ts +77 -0
  328. package/dist/types/components/BTextarea/index.d.ts +1 -0
  329. package/dist/types/components/index.d.ts +7 -1
  330. package/package.json +1 -1
  331. package/dist/design-system114.js +0 -212
  332. package/dist/design-system114.js.map +0 -1
  333. package/dist/design-system124.js +0 -277
  334. package/dist/design-system127.js +0 -19
  335. package/dist/design-system130.js +0 -15
  336. package/dist/design-system130.js.map +0 -1
  337. package/dist/design-system133.js +0 -8
  338. package/dist/design-system133.js.map +0 -1
  339. package/dist/design-system137.js +0 -236
  340. package/dist/design-system137.js.map +0 -1
  341. package/dist/design-system147.js +0 -40
  342. package/dist/design-system147.js.map +0 -1
  343. package/dist/design-system150.js +0 -7
  344. package/dist/design-system164.js +0 -61
  345. package/dist/design-system164.js.map +0 -1
  346. package/dist/design-system167.js +0 -59
  347. package/dist/design-system170.js +0 -72
  348. package/dist/design-system173.js +0 -185
  349. package/dist/design-system173.js.map +0 -1
  350. package/dist/design-system176.js +0 -118
  351. package/dist/design-system180.js +0 -465
  352. package/dist/design-system180.js.map +0 -1
  353. package/dist/design-system183.js +0 -38
  354. package/dist/design-system183.js.map +0 -1
  355. package/dist/design-system186.js +0 -91
  356. package/dist/design-system186.js.map +0 -1
  357. package/dist/design-system189.js +0 -38
  358. package/dist/design-system189.js.map +0 -1
  359. package/dist/design-system192.js +0 -31
  360. package/dist/design-system192.js.map +0 -1
  361. package/dist/design-system208.js +0 -7
  362. package/dist/design-system217.js +0 -7
  363. package/dist/design-system217.js.map +0 -1
  364. package/dist/design-system234.js +0 -286
  365. package/dist/design-system234.js.map +0 -1
  366. package/dist/design-system237.js +0 -122
  367. package/dist/design-system237.js.map +0 -1
  368. package/dist/design-system240.js +0 -115
  369. package/dist/design-system240.js.map +0 -1
  370. package/dist/design-system70.js +0 -699
  371. package/dist/design-system70.js.map +0 -1
  372. package/dist/design-system77.js +0 -7
  373. package/dist/design-system77.js.map +0 -1
  374. package/dist/design-system85.js +0 -276
  375. package/dist/design-system85.js.map +0 -1
  376. package/dist/design-system92.js +0 -102
  377. package/dist/design-system92.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"design-system255.js","names":[],"sources":["../src/components/BTreeSelect/types.ts"],"sourcesContent":["export enum BTreeSelectVariant {\n Outlined = 'outlined',\n Filled = 'filled',\n Borderless = 'borderless',\n Underlined = 'underlined',\n}\n\nexport enum BTreeSelectStatus {\n Error = 'error',\n Warning = 'warning',\n}\n\nexport enum BTreeSelectPlacement {\n BottomLeft = 'bottomLeft',\n BottomRight = 'bottomRight',\n TopLeft = 'topLeft',\n TopRight = 'topRight',\n}\n\nexport type BTreeSelectExpandAction = 'click' | 'doubleClick' | false;\n\nexport type BTreeSelectValue = string | number;\n\nexport interface BTreeSelectLabeledValue {\n value: BTreeSelectValue;\n label: string;\n}\n\nexport type BTreeSelectModelValue =\n | BTreeSelectValue\n | BTreeSelectLabeledValue\n | BTreeSelectValue[]\n | BTreeSelectLabeledValue[]\n | null\n | undefined;\n\nexport interface BTreeSelectNode {\n /** The node's display title. */\n title?: string;\n /** Unique identification value. */\n value: BTreeSelectValue;\n /** Optional unique key. Falls back to `value` when omitted. */\n key?: BTreeSelectValue;\n /** Children nodes. */\n children?: BTreeSelectNode[];\n /** Whether this node is disabled. */\n disabled?: boolean;\n /** Whether to disable just the checkbox (treeCheckable mode). */\n disableCheckbox?: boolean;\n /** Whether the node can be selected (single mode). */\n selectable?: boolean;\n /** Whether the node is a leaf (used with loadData). */\n isLeaf?: boolean;\n /** Whether to show a checkbox for this node (treeCheckable mode). */\n checkable?: boolean;\n /** Arbitrary extra data passed through. */\n [key: string]: unknown;\n}\n\nexport interface BTreeSelectFieldNames {\n /** Custom field for label/title. Default: 'title' */\n label?: string;\n /** Custom field for value. Default: 'value' */\n value?: string;\n /** Custom field for children. Default: 'children' */\n children?: string;\n}\n\nexport interface BTreeSelectShowSearchConfig {\n /** Custom filter function. Returns true if a node matches. */\n filter?: (input: string, node: BTreeSelectNode) => boolean;\n}\n\nexport interface BTreeSelectChangeExtra {\n /** Whether selection was triggered by a check/uncheck or a single select. */\n triggerValue?: BTreeSelectValue;\n /** The node that triggered the change. */\n triggerNode?: BTreeSelectNode;\n /** Whether the change came from a \"select\" or \"deselect\". */\n preValue?: BTreeSelectValue[];\n /** Whether currently checked (treeCheckable mode). */\n checked?: boolean;\n /** Whether currently selected. */\n selected?: boolean;\n}\n\nexport interface BTreeSelectFlatNode {\n key: BTreeSelectValue;\n value: BTreeSelectValue;\n data: BTreeSelectNode;\n depth: number;\n visible: boolean;\n parents: BTreeSelectValue[];\n}\n"],"mappings":";AAAA,IAAY,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,cACA,EAAA,cAAA,eACA,EAAA,UAAA,WACA,EAAA,WAAA;KACD"}
1
+ {"version":3,"file":"design-system255.js","names":[],"sources":["../src/components/BTimePicker/BTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\n\nimport {\n BTimePickerPlacement,\n BTimePickerSize,\n BTimePickerStatus,\n BTimePickerVariant,\n type BTimePickerDisabledTime,\n} from './types';\n\nconst {\n size = BTimePickerSize.Medium,\n variant = BTimePickerVariant.Outlined,\n placeholder = 'Select time',\n disabled = false,\n inputReadOnly = false,\n allowClear = true,\n showNow = true,\n use12Hours = false,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n format,\n placement: _placement = BTimePickerPlacement.BottomLeft,\n status,\n hideDisabledOptions = false,\n needConfirm = true,\n changeOnScroll = false,\n showHour = true,\n showMinute = true,\n showSecond = true,\n defaultOpen = false,\n defaultValue,\n open,\n disabledTime,\n} = defineProps<{\n /** Size of the input */\n size?: `${BTimePickerSize}`;\n /** Visual variant */\n variant?: `${BTimePickerVariant}`;\n /** Placeholder text */\n placeholder?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Make input read-only (useful for touch devices) */\n inputReadOnly?: boolean;\n /** Show clear button */\n allowClear?: boolean;\n /** Show \"Now\" button in footer */\n showNow?: boolean;\n /** Use 12-hour format with AM/PM */\n use12Hours?: boolean;\n /** Hour selection step */\n hourStep?: number;\n /** Minute selection step */\n minuteStep?: number;\n /** Second selection step */\n secondStep?: number;\n /** Time format string (e.g. 'HH:mm:ss', 'hh:mm a') */\n format?: string;\n /** Popup placement */\n placement?: `${BTimePickerPlacement}`;\n /** Validation status */\n status?: `${BTimePickerStatus}`;\n /** Hide disabled time options from columns */\n hideDisabledOptions?: boolean;\n /** Require OK button confirmation before applying value */\n needConfirm?: boolean;\n /** Update value on scroll instead of click */\n changeOnScroll?: boolean;\n /** Show hour column */\n showHour?: boolean;\n /** Show minute column */\n showMinute?: boolean;\n /** Show second column */\n showSecond?: boolean;\n /** Default open state */\n defaultOpen?: boolean;\n /** Default value (uncontrolled) */\n defaultValue?: Date;\n /** Controlled open state */\n open?: boolean;\n /** Function returning disabled hours/minutes/seconds */\n disabledTime?: () => BTimePickerDisabledTime;\n}>();\n\nconst model = defineModel<Date | null>({ default: undefined });\n\nconst emit = defineEmits<{\n change: [time: Date | null, timeString: string];\n openChange: [open: boolean];\n}>();\n\nconst inputEl = ref<HTMLInputElement | null>(null);\nconst panelEl = ref<HTMLElement | null>(null);\nconst hourColEl = ref<HTMLElement | null>(null);\nconst minuteColEl = ref<HTMLElement | null>(null);\nconst secondColEl = ref<HTMLElement | null>(null);\nconst ampmColEl = ref<HTMLElement | null>(null);\n\ndefineExpose({\n focus: () => inputEl.value?.focus(),\n blur: () => inputEl.value?.blur(),\n});\n\nconst { componentUID } = useComponentId();\nconst anchorName = computed(() => `--b-time-picker-${componentUID.value}`);\n\n// ─────────────────────────────────────────────\n// State\n// ─────────────────────────────────────────────\nconst isOpen = ref(defaultOpen);\nconst isPanelOpen = ref(open !== undefined ? !!open : defaultOpen);\nconst internalValue = ref<Date | null>(defaultValue ?? null);\nconst pendingHour = ref<number | null>(null);\nconst pendingMinute = ref<number | null>(null);\nconst pendingSecond = ref<number | null>(null);\nconst pendingAmpm = ref<'AM' | 'PM' | null>(null);\nconst inputText = ref('');\nconst focusedColumn = ref<'hour' | 'minute' | 'second' | 'ampm'>('hour');\n\nconst selectedTime = computed({\n get: () => model.value ?? internalValue.value,\n set: (val) => {\n internalValue.value = val;\n model.value = val;\n },\n});\n\n// ─────────────────────────────────────────────\n// Format\n// ─────────────────────────────────────────────\nconst activeFormat = computed(() => {\n if (format) return format;\n const parts: string[] = [];\n if (showHour) parts.push(use12Hours ? 'hh' : 'HH');\n if (showMinute) parts.push('mm');\n if (showSecond) parts.push('ss');\n const base = parts.join(':');\n return use12Hours ? `${base} A` : base;\n});\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nfunction formatTime(d: Date | null): string {\n if (!d) return '';\n const h = d.getHours();\n const m = d.getMinutes();\n const s = d.getSeconds();\n const ampm = h >= 12 ? 'PM' : 'AM';\n\n let result = activeFormat.value;\n if (use12Hours) {\n const h12 = h % 12 || 12;\n result = result.replace('hh', pad(h12));\n result = result.replace('h', String(h12));\n result = result.replace('A', ampm);\n result = result.replace('a', ampm.toLowerCase());\n } else {\n result = result.replace('HH', pad(h));\n result = result.replace('H', String(h));\n }\n result = result.replace('mm', pad(m));\n result = result.replace('ss', pad(s));\n return result;\n}\n\nfunction parseTimeString(str: string): Date | null {\n if (!str.trim()) return null;\n const timeRegex12 = /(\\d{1,2}):(\\d{2})(?::(\\d{2}))?\\s*(AM|PM|am|pm)?/;\n const match = str.match(timeRegex12);\n if (!match) return null;\n\n let h = parseInt(match[1], 10);\n const m = parseInt(match[2], 10);\n const s = match[3] ? parseInt(match[3], 10) : 0;\n const period = match[4]?.toUpperCase();\n\n if (use12Hours && period) {\n if (period === 'PM' && h < 12) h += 12;\n if (period === 'AM' && h === 12) h = 0;\n }\n\n if (h < 0 || h > 23 || m < 0 || m > 59 || s < 0 || s > 59) return null;\n\n const d = new Date();\n d.setHours(h, m, s, 0);\n return d;\n}\n\n// ─────────────────────────────────────────────\n// Disabled time logic\n// ─────────────────────────────────────────────\nconst disabledHours = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n return dt.disabledHours?.() ?? [];\n});\n\nconst disabledMinutes = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n const h = pendingHour.value ?? selectedTime.value?.getHours() ?? 0;\n return dt.disabledMinutes?.(h) ?? [];\n});\n\nconst disabledSeconds = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n const h = pendingHour.value ?? selectedTime.value?.getHours() ?? 0;\n const m = pendingMinute.value ?? selectedTime.value?.getMinutes() ?? 0;\n return dt.disabledSeconds?.(h, m) ?? [];\n});\n\n// ─────────────────────────────────────────────\n// Column data\n// ─────────────────────────────────────────────\nconst hours = computed(() => {\n const list: number[] = [];\n if (use12Hours) {\n for (let i = 1; i <= 12; i += hourStep) list.push(i);\n } else {\n for (let i = 0; i < 24; i += hourStep) list.push(i);\n }\n if (hideDisabledOptions) {\n return list.filter((h) => !disabledHours.value.includes(use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h));\n }\n return list;\n});\n\nconst minutes = computed(() => {\n const list: number[] = [];\n for (let i = 0; i < 60; i += minuteStep) list.push(i);\n if (hideDisabledOptions) {\n return list.filter((m) => !disabledMinutes.value.includes(m));\n }\n return list;\n});\n\nconst seconds = computed(() => {\n const list: number[] = [];\n for (let i = 0; i < 60; i += secondStep) list.push(i);\n if (hideDisabledOptions) {\n return list.filter((s) => !disabledSeconds.value.includes(s));\n }\n return list;\n});\n\nfunction to24Hour(h12: number, period: 'AM' | 'PM'): number {\n if (period === 'AM') return h12 === 12 ? 0 : h12;\n return h12 === 12 ? 12 : h12 + 12;\n}\n\nfunction to12Hour(h24: number): { hour: number; period: 'AM' | 'PM' } {\n const period: 'AM' | 'PM' = h24 >= 12 ? 'PM' : 'AM';\n const hour = h24 % 12 || 12;\n return { hour, period };\n}\n\n// ─────────────────────────────────────────────\n// Panel open/close\n// ─────────────────────────────────────────────\nfunction openPanel() {\n if (disabled) return;\n isOpen.value = true;\n isPanelOpen.value = true;\n emit('openChange', true);\n panelEl.value?.showPopover?.();\n syncPendingFromValue();\n nextTick(() => scrollToSelected());\n}\n\nfunction closePanel() {\n isOpen.value = false;\n isPanelOpen.value = false;\n emit('openChange', false);\n panelEl.value?.hidePopover?.();\n inputEl.value?.focus();\n}\n\nfunction togglePanel() {\n if (isPanelOpen.value) closePanel();\n else openPanel();\n}\n\nfunction handlePopoverToggle(e: Event) {\n const toggleEvent = e as ToggleEvent;\n const nowOpen = toggleEvent.newState === 'open';\n isOpen.value = nowOpen;\n isPanelOpen.value = nowOpen;\n if (!nowOpen) emit('openChange', false);\n}\n\n// ─────────────────────────────────────────────\n// Sync pending state\n// ─────────────────────────────────────────────\nfunction syncPendingFromValue() {\n const t = selectedTime.value;\n if (t) {\n if (use12Hours) {\n const { hour, period } = to12Hour(t.getHours());\n pendingHour.value = hour;\n pendingAmpm.value = period;\n } else {\n pendingHour.value = t.getHours();\n }\n pendingMinute.value = t.getMinutes();\n pendingSecond.value = t.getSeconds();\n } else {\n pendingHour.value = null;\n pendingMinute.value = null;\n pendingSecond.value = null;\n pendingAmpm.value = null;\n }\n}\n\n// ─────────────────────────────────────────────\n// Selection\n// ─────────────────────────────────────────────\nfunction selectHour(h: number) {\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n if (disabledHours.value.includes(h24)) return;\n pendingHour.value = h;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectMinute(m: number) {\n if (disabledMinutes.value.includes(m)) return;\n pendingMinute.value = m;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectSecond(s: number) {\n if (disabledSeconds.value.includes(s)) return;\n pendingSecond.value = s;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectAmpm(val: 'AM' | 'PM') {\n pendingAmpm.value = val;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction applyPendingIfComplete() {\n if (pendingHour.value !== null && pendingMinute.value !== null) {\n if (showSecond && pendingSecond.value === null) return;\n if (use12Hours && pendingAmpm.value === null) return;\n applyPending();\n closePanel();\n }\n}\n\nfunction applyPending() {\n const h = pendingHour.value ?? 0;\n const m = pendingMinute.value ?? 0;\n const s = pendingSecond.value ?? 0;\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n\n const d = new Date();\n d.setHours(h24, m, s, 0);\n selectedTime.value = d;\n inputText.value = formatTime(d);\n emit('change', d, formatTime(d));\n}\n\nfunction handleOk() {\n applyPending();\n closePanel();\n}\n\nfunction handleNow() {\n const now = new Date();\n if (use12Hours) {\n const { hour, period } = to12Hour(now.getHours());\n pendingHour.value = hour;\n pendingAmpm.value = period;\n } else {\n pendingHour.value = now.getHours();\n }\n pendingMinute.value = now.getMinutes();\n pendingSecond.value = now.getSeconds();\n nextTick(() => scrollToSelected());\n if (!needConfirm) {\n applyPending();\n closePanel();\n }\n}\n\nfunction handleClear(e: Event) {\n e.stopPropagation();\n selectedTime.value = null;\n inputText.value = '';\n pendingHour.value = null;\n pendingMinute.value = null;\n pendingSecond.value = null;\n pendingAmpm.value = null;\n emit('change', null, '');\n}\n\n// ─────────────────────────────────────────────\n// Input handling\n// ─────────────────────────────────────────────\nfunction handleInputChange(e: Event) {\n const val = (e.target as HTMLInputElement).value;\n inputText.value = val;\n}\n\nfunction handleInputBlur() {\n if (!isPanelOpen.value) {\n const parsed = parseTimeString(inputText.value);\n if (parsed) {\n selectedTime.value = parsed;\n inputText.value = formatTime(parsed);\n emit('change', parsed, formatTime(parsed));\n } else if (inputText.value === '') {\n selectedTime.value = null;\n emit('change', null, '');\n } else {\n inputText.value = formatTime(selectedTime.value);\n }\n }\n}\n\nfunction handleInputKeydown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n if (!isPanelOpen.value) {\n e.preventDefault();\n openPanel();\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const parsed = parseTimeString(inputText.value);\n if (parsed) {\n selectedTime.value = parsed;\n inputText.value = formatTime(parsed);\n emit('change', parsed, formatTime(parsed));\n }\n closePanel();\n }\n } else if (e.key === 'Escape') {\n if (isPanelOpen.value) {\n e.preventDefault();\n closePanel();\n }\n }\n}\n\n// ─────────────────────────────────────────────\n// Panel keyboard navigation\n// ─────────────────────────────────────────────\nfunction handlePanelKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePanel();\n return;\n }\n\n if (e.key === 'Tab') {\n const columns: ('hour' | 'minute' | 'second' | 'ampm')[] = [];\n if (showHour) columns.push('hour');\n if (showMinute) columns.push('minute');\n if (showSecond) columns.push('second');\n if (use12Hours) columns.push('ampm');\n\n const idx = columns.indexOf(focusedColumn.value);\n if (e.shiftKey) {\n if (idx > 0) {\n e.preventDefault();\n focusedColumn.value = columns[idx - 1];\n }\n } else {\n if (idx < columns.length - 1) {\n e.preventDefault();\n focusedColumn.value = columns[idx + 1];\n }\n }\n return;\n }\n\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n const delta = e.key === 'ArrowUp' ? -1 : 1;\n adjustFocusedColumn(delta);\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n handleOk();\n }\n}\n\nfunction adjustFocusedColumn(delta: number) {\n if (focusedColumn.value === 'hour') {\n const list = hours.value;\n const current = pendingHour.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectHour(next);\n scrollColumnTo(hourColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'minute') {\n const list = minutes.value;\n const current = pendingMinute.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectMinute(next);\n scrollColumnTo(minuteColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'second') {\n const list = seconds.value;\n const current = pendingSecond.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectSecond(next);\n scrollColumnTo(secondColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'ampm') {\n const val = pendingAmpm.value === 'AM' ? 'PM' : 'AM';\n selectAmpm(val);\n }\n}\n\n// ─────────────────────────────────────────────\n// Scroll helpers\n// ─────────────────────────────────────────────\nfunction scrollColumnTo(col: HTMLElement | null, idx: number) {\n if (!col || !col.scrollTo) return;\n const cellHeight = 28;\n col.scrollTo({ top: idx * cellHeight, behavior: 'smooth' });\n}\n\nfunction scrollToSelected() {\n if (pendingHour.value !== null) {\n const idx = hours.value.indexOf(pendingHour.value);\n if (idx >= 0) scrollColumnTo(hourColEl.value, idx);\n }\n if (pendingMinute.value !== null) {\n const idx = minutes.value.indexOf(pendingMinute.value);\n if (idx >= 0) scrollColumnTo(minuteColEl.value, idx);\n }\n if (pendingSecond.value !== null && showSecond) {\n const idx = seconds.value.indexOf(pendingSecond.value);\n if (idx >= 0) scrollColumnTo(secondColEl.value, idx);\n }\n if (pendingAmpm.value && use12Hours) {\n const idx = pendingAmpm.value === 'AM' ? 0 : 1;\n scrollColumnTo(ampmColEl.value, idx);\n }\n}\n\n// ─────────────────────────────────────────────\n// Click outside\n// ─────────────────────────────────────────────\nfunction handleClickOutside(e: MouseEvent) {\n if (!isPanelOpen.value) return;\n const target = e.target as Node;\n if (panelEl.value?.contains(target)) return;\n if (inputEl.value?.parentElement?.contains(target)) return;\n closePanel();\n}\n\nonMounted(() => {\n document.addEventListener('mousedown', handleClickOutside);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', handleClickOutside);\n});\n\n// ─────────────────────────────────────────────\n// Watchers\n// ─────────────────────────────────────────────\nwatch(\n () => open,\n (val) => {\n if (val !== undefined) {\n if (val) openPanel();\n else closePanel();\n }\n },\n);\n\nwatch(selectedTime, (val) => {\n inputText.value = formatTime(val);\n});\n\n// Init display\ninputText.value = formatTime(selectedTime.value);\n\n// ─────────────────────────────────────────────\n// Computed classes\n// ─────────────────────────────────────────────\nconst rootClasses = computed(() => [\n 'b-time-picker',\n `b-time-picker--${size}`,\n `b-time-picker--${variant}`,\n {\n 'b-time-picker--disabled': disabled,\n 'b-time-picker--open': isPanelOpen.value,\n [`b-time-picker--${status}`]: !!status,\n },\n]);\n\nconst isHourDisabled = (h: number) => {\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n return disabledHours.value.includes(h24);\n};\nconst isMinuteDisabled = (m: number) => disabledMinutes.value.includes(m);\nconst isSecondDisabled = (s: number) => disabledSeconds.value.includes(s);\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <div\n class=\"b-time-picker__input-wrap\"\n :style=\"{ anchorName }\"\n @click=\"togglePanel\"\n >\n <input\n :id=\"`b-time-picker-input-${componentUID}`\"\n ref=\"inputEl\"\n class=\"b-time-picker__input\"\n type=\"text\"\n role=\"combobox\"\n :aria-expanded=\"isPanelOpen\"\n aria-haspopup=\"dialog\"\n :aria-controls=\"isPanelOpen ? `b-time-picker-panel-${componentUID}` : undefined\"\n :aria-describedby=\"status ? `b-time-picker-status-${componentUID}` : undefined\"\n :aria-label=\"placeholder\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"inputReadOnly\"\n :value=\"inputText\"\n autocomplete=\"off\"\n @input=\"handleInputChange\"\n @blur=\"handleInputBlur\"\n @keydown=\"handleInputKeydown\"\n />\n <span class=\"b-time-picker__suffix\">\n <svg\n v-if=\"!allowClear || !selectedTime\"\n class=\"b-time-picker__icon\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n <button\n v-else\n class=\"b-time-picker__clear\"\n type=\"button\"\n aria-label=\"Clear time\"\n tabindex=\"-1\"\n @click=\"handleClear\"\n >\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n </button>\n </span>\n <span\n v-if=\"status\"\n :id=\"`b-time-picker-status-${componentUID}`\"\n class=\"b-time-picker__status-text\"\n aria-live=\"polite\"\n >\n {{ status }}\n </span>\n </div>\n\n <div\n :id=\"`b-time-picker-panel-${componentUID}`\"\n ref=\"panelEl\"\n class=\"b-time-picker__panel\"\n popover\n role=\"dialog\"\n :aria-label=\"'Time picker'\"\n :aria-modal=\"true\"\n :style=\"{ positionAnchor: anchorName }\"\n @toggle=\"handlePopoverToggle\"\n @keydown=\"handlePanelKeydown\"\n >\n <div class=\"b-time-picker__columns\" role=\"group\" aria-label=\"Time selection columns\">\n <!-- Hour Column -->\n <div\n v-if=\"showHour\"\n ref=\"hourColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Hours'\"\n :aria-activedescendant=\"pendingHour !== null ? `b-time-picker-hour-${pendingHour}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"h in hours\"\n :id=\"`b-time-picker-hour-${h}-${componentUID}`\"\n :key=\"h\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingHour === h,\n 'b-time-picker__cell--disabled': isHourDisabled(h),\n 'b-time-picker__cell--focused': focusedColumn === 'hour' && pendingHour === h,\n }\"\n role=\"option\"\n :aria-selected=\"pendingHour === h\"\n :aria-disabled=\"isHourDisabled(h)\"\n @click=\"selectHour(h)\"\n >\n {{ pad(h) }}\n </div>\n </div>\n\n <!-- Minute Column -->\n <div\n v-if=\"showMinute\"\n ref=\"minuteColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Minutes'\"\n :aria-activedescendant=\"pendingMinute !== null ? `b-time-picker-minute-${pendingMinute}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"m in minutes\"\n :id=\"`b-time-picker-minute-${m}-${componentUID}`\"\n :key=\"m\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingMinute === m,\n 'b-time-picker__cell--disabled': isMinuteDisabled(m),\n 'b-time-picker__cell--focused': focusedColumn === 'minute' && pendingMinute === m,\n }\"\n role=\"option\"\n :aria-selected=\"pendingMinute === m\"\n :aria-disabled=\"isMinuteDisabled(m)\"\n @click=\"selectMinute(m)\"\n >\n {{ pad(m) }}\n </div>\n </div>\n\n <!-- Second Column -->\n <div\n v-if=\"showSecond\"\n ref=\"secondColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Seconds'\"\n :aria-activedescendant=\"pendingSecond !== null ? `b-time-picker-second-${pendingSecond}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"s in seconds\"\n :id=\"`b-time-picker-second-${s}-${componentUID}`\"\n :key=\"s\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingSecond === s,\n 'b-time-picker__cell--disabled': isSecondDisabled(s),\n 'b-time-picker__cell--focused': focusedColumn === 'second' && pendingSecond === s,\n }\"\n role=\"option\"\n :aria-selected=\"pendingSecond === s\"\n :aria-disabled=\"isSecondDisabled(s)\"\n @click=\"selectSecond(s)\"\n >\n {{ pad(s) }}\n </div>\n </div>\n\n <!-- AM/PM Column -->\n <div\n v-if=\"use12Hours\"\n ref=\"ampmColEl\"\n class=\"b-time-picker__column b-time-picker__column--ampm\"\n role=\"listbox\"\n aria-label=\"AM/PM\"\n >\n <div\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingAmpm === 'AM',\n 'b-time-picker__cell--focused': focusedColumn === 'ampm' && pendingAmpm === 'AM',\n }\"\n role=\"option\"\n :aria-selected=\"pendingAmpm === 'AM'\"\n @click=\"selectAmpm('AM')\"\n >\n AM\n </div>\n <div\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingAmpm === 'PM',\n 'b-time-picker__cell--focused': focusedColumn === 'ampm' && pendingAmpm === 'PM',\n }\"\n role=\"option\"\n :aria-selected=\"pendingAmpm === 'PM'\"\n @click=\"selectAmpm('PM')\"\n >\n PM\n </div>\n </div>\n </div>\n\n <div v-if=\"needConfirm || showNow\" class=\"b-time-picker__footer\">\n <button\n v-if=\"showNow\"\n class=\"b-time-picker__now-btn\"\n type=\"button\"\n @click=\"handleNow\"\n >\n Now\n </button>\n <button\n v-if=\"needConfirm\"\n class=\"b-time-picker__ok-btn\"\n type=\"button\"\n @click=\"handleOk\"\n >\n OK\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n.b-time-picker {\n --b-time-picker-input-font-size: 14px;\n --b-time-picker-input-font-size-lg: 16px;\n --b-time-picker-input-font-size-sm: 14px;\n --b-time-picker-padding-block: 4px;\n --b-time-picker-padding-block-lg: 7px;\n --b-time-picker-padding-block-sm: 0px;\n --b-time-picker-padding-inline: 11px;\n --b-time-picker-padding-inline-lg: 11px;\n --b-time-picker-padding-inline-sm: 7px;\n --b-time-picker-border-color: #d9d9d9;\n --b-time-picker-hover-border-color: #4096ff;\n --b-time-picker-active-border-color: #1677ff;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(255, 38, 5, 0.06);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(255, 215, 5, 0.1);\n --b-time-picker-bg: #ffffff;\n --b-time-picker-hover-bg: #ffffff;\n --b-time-picker-active-bg: #ffffff;\n --b-time-picker-text-color: rgba(0, 0, 0, 0.88);\n --b-time-picker-placeholder-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-icon-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-clear-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-clear-hover-color: rgba(0, 0, 0, 0.45);\n --b-time-picker-disabled-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-disabled-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-panel-bg: #ffffff;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-time-picker-cell-height: 28px;\n --b-time-picker-cell-width: 56px;\n --b-time-picker-cell-hover-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-cell-selected-bg: #e6f4ff;\n --b-time-picker-cell-disabled-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-cell-disabled-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-column-height: 224px;\n --b-time-picker-column-width: 56px;\n --b-time-picker-footer-bg: #ffffff;\n --b-time-picker-border-radius: 6px;\n --b-time-picker-panel-border-radius: 8px;\n --b-time-picker-transition-duration: 0.2s;\n --b-time-picker-z-index-popup: 1050;\n\n position: relative;\n display: inline-flex;\n width: 100%;\n max-width: 200px;\n}\n\n/* ──── Input Wrap ──── */\n.b-time-picker__input-wrap {\n display: flex;\n align-items: center;\n width: 100%;\n background: var(--b-time-picker-bg);\n border: 1px solid var(--b-time-picker-border-color);\n border-radius: var(--b-time-picker-border-radius);\n padding: var(--b-time-picker-padding-block) var(--b-time-picker-padding-inline);\n cursor: pointer;\n transition:\n border-color var(--b-time-picker-transition-duration),\n box-shadow var(--b-time-picker-transition-duration),\n background var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__input-wrap:hover {\n border-color: var(--b-time-picker-hover-border-color);\n background: var(--b-time-picker-hover-bg);\n}\n\n.b-time-picker--open .b-time-picker__input-wrap {\n border-color: var(--b-time-picker-active-border-color);\n box-shadow: var(--b-time-picker-active-shadow);\n background: var(--b-time-picker-active-bg);\n}\n\n/* ──── Size Variants ──── */\n.b-time-picker--sm .b-time-picker__input-wrap {\n padding: var(--b-time-picker-padding-block-sm) var(--b-time-picker-padding-inline-sm);\n}\n\n.b-time-picker--sm .b-time-picker__input {\n font-size: var(--b-time-picker-input-font-size-sm);\n}\n\n.b-time-picker--lg .b-time-picker__input-wrap {\n padding: var(--b-time-picker-padding-block-lg) var(--b-time-picker-padding-inline-lg);\n}\n\n.b-time-picker--lg .b-time-picker__input {\n font-size: var(--b-time-picker-input-font-size-lg);\n}\n\n/* ──── Variant Styles ──── */\n.b-time-picker--filled .b-time-picker__input-wrap {\n background: rgba(0, 0, 0, 0.04);\n border-color: transparent;\n}\n\n.b-time-picker--filled .b-time-picker__input-wrap:hover {\n background: rgba(0, 0, 0, 0.06);\n}\n\n.b-time-picker--borderless .b-time-picker__input-wrap {\n border-color: transparent;\n background: transparent;\n box-shadow: none;\n}\n\n.b-time-picker--underlined .b-time-picker__input-wrap {\n border-radius: 0;\n border: none;\n border-bottom: 1px solid var(--b-time-picker-border-color);\n}\n\n.b-time-picker--underlined .b-time-picker__input-wrap:hover {\n border-bottom-color: var(--b-time-picker-hover-border-color);\n}\n\n.b-time-picker--underlined.b-time-picker--open .b-time-picker__input-wrap {\n border-bottom-color: var(--b-time-picker-active-border-color);\n box-shadow: none;\n}\n\n/* ──── Status ──── */\n.b-time-picker--error .b-time-picker__input-wrap {\n border-color: #ff4d4f;\n}\n\n.b-time-picker--error.b-time-picker--open .b-time-picker__input-wrap {\n box-shadow: var(--b-time-picker-error-active-shadow);\n}\n\n.b-time-picker--warning .b-time-picker__input-wrap {\n border-color: #faad14;\n}\n\n.b-time-picker--warning.b-time-picker--open .b-time-picker__input-wrap {\n box-shadow: var(--b-time-picker-warning-active-shadow);\n}\n\n/* ──── Disabled ──── */\n.b-time-picker--disabled .b-time-picker__input-wrap {\n background: var(--b-time-picker-disabled-bg);\n border-color: var(--b-time-picker-border-color);\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.b-time-picker--disabled .b-time-picker__input {\n color: var(--b-time-picker-disabled-color);\n cursor: not-allowed;\n}\n\n/* ──── Input ──── */\n.b-time-picker__input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-size: var(--b-time-picker-input-font-size);\n color: var(--b-time-picker-text-color);\n line-height: 1.5;\n padding: 0;\n min-width: 0;\n}\n\n.b-time-picker__input::placeholder {\n color: var(--b-time-picker-placeholder-color);\n}\n\n/* ──── Suffix / Icons ──── */\n.b-time-picker__suffix {\n display: flex;\n align-items: center;\n margin-left: 4px;\n flex-shrink: 0;\n}\n\n.b-time-picker__icon {\n width: 14px;\n height: 14px;\n color: var(--b-time-picker-icon-color);\n}\n\n.b-time-picker__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n padding: 0;\n cursor: pointer;\n color: var(--b-time-picker-clear-color);\n transition: color var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__clear:hover {\n color: var(--b-time-picker-clear-hover-color);\n}\n\n.b-time-picker__clear svg {\n width: 14px;\n height: 14px;\n}\n\n.b-time-picker__status-text {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n}\n\n/* ──── Panel ──── */\n.b-time-picker__panel {\n position: absolute;\n position-anchor: var(--b-time-picker-anchor);\n inset: unset;\n top: anchor(bottom);\n left: anchor(left);\n margin: 0;\n margin-top: 4px;\n padding: 0;\n border: none;\n border-radius: var(--b-time-picker-panel-border-radius);\n background: var(--b-time-picker-panel-bg);\n box-shadow: var(--b-time-picker-panel-shadow);\n z-index: var(--b-time-picker-z-index-popup);\n overflow: hidden;\n opacity: 0;\n transform: translateY(-4px);\n transition:\n opacity var(--b-time-picker-transition-duration) ease,\n transform var(--b-time-picker-transition-duration) ease;\n}\n\n.b-time-picker__panel:popover-open {\n opacity: 1;\n transform: translateY(0);\n}\n\n@starting-style {\n .b-time-picker__panel:popover-open {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n/* ──── Columns ──── */\n.b-time-picker__columns {\n display: flex;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.b-time-picker__column {\n width: var(--b-time-picker-column-width);\n height: var(--b-time-picker-column-height);\n overflow-y: auto;\n overflow-x: hidden;\n border-right: 1px solid #f0f0f0;\n scroll-behavior: smooth;\n scrollbar-width: thin;\n}\n\n.b-time-picker__column:last-child {\n border-right: none;\n}\n\n/* ──── Cells ──── */\n.b-time-picker__cell {\n height: var(--b-time-picker-cell-height);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 14px;\n color: var(--b-time-picker-text-color);\n transition: background var(--b-time-picker-transition-duration);\n user-select: none;\n}\n\n.b-time-picker__cell:hover {\n background: var(--b-time-picker-cell-hover-bg);\n}\n\n.b-time-picker__cell--selected {\n background: var(--b-time-picker-cell-selected-bg);\n font-weight: 600;\n}\n\n.b-time-picker__cell--focused {\n outline: 2px solid var(--b-time-picker-active-border-color);\n outline-offset: -2px;\n}\n\n.b-time-picker__cell--disabled {\n color: var(--b-time-picker-cell-disabled-color);\n background: var(--b-time-picker-cell-disabled-bg);\n cursor: not-allowed;\n}\n\n.b-time-picker__cell--disabled:hover {\n background: var(--b-time-picker-cell-disabled-bg);\n}\n\n/* ──── Footer ──── */\n.b-time-picker__footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 8px;\n background: var(--b-time-picker-footer-bg);\n}\n\n.b-time-picker__now-btn {\n border: none;\n background: none;\n color: var(--b-time-picker-active-border-color);\n cursor: pointer;\n font-size: 14px;\n padding: 4px 8px;\n border-radius: 4px;\n transition: background var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__now-btn:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.b-time-picker__ok-btn {\n border: none;\n background: var(--b-time-picker-active-border-color);\n color: #fff;\n cursor: pointer;\n font-size: 14px;\n padding: 2px 12px;\n border-radius: 4px;\n font-weight: 500;\n line-height: 1.5;\n transition:\n background var(--b-time-picker-transition-duration),\n opacity var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__ok-btn:hover {\n opacity: 0.85;\n}\n\n/* ──── Placement ──── */\n.b-time-picker--bottom-right .b-time-picker__panel {\n left: unset;\n right: anchor(right);\n}\n\n.b-time-picker--top-left .b-time-picker__panel {\n top: unset;\n bottom: anchor(top);\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n.b-time-picker--top-right .b-time-picker__panel {\n top: unset;\n bottom: anchor(top);\n left: unset;\n right: anchor(right);\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n/* ──── Dark Mode ──── */\n[data-prefers-color='dark'] .b-time-picker {\n --b-time-picker-bg: #141414;\n --b-time-picker-hover-bg: #141414;\n --b-time-picker-active-bg: #141414;\n --b-time-picker-border-color: #424242;\n --b-time-picker-hover-border-color: #165dff;\n --b-time-picker-active-border-color: #1668dc;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-time-picker-text-color: rgba(255, 255, 255, 0.85);\n --b-time-picker-placeholder-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-icon-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-hover-color: rgba(255, 255, 255, 0.55);\n --b-time-picker-disabled-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-panel-bg: #1f1f1f;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-time-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-cell-selected-bg: #111a2c;\n --b-time-picker-cell-disabled-bg: rgba(255, 255, 255, 0.04);\n --b-time-picker-cell-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-footer-bg: #1f1f1f;\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(220, 56, 72, 0.15);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(217, 146, 0, 0.15);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-time-picker {\n --b-time-picker-bg: #141414;\n --b-time-picker-hover-bg: #141414;\n --b-time-picker-active-bg: #141414;\n --b-time-picker-border-color: #424242;\n --b-time-picker-hover-border-color: #165dff;\n --b-time-picker-active-border-color: #1668dc;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-time-picker-text-color: rgba(255, 255, 255, 0.85);\n --b-time-picker-placeholder-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-icon-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-hover-color: rgba(255, 255, 255, 0.55);\n --b-time-picker-disabled-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-panel-bg: #1f1f1f;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-time-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-cell-selected-bg: #111a2c;\n --b-time-picker-cell-disabled-bg: rgba(255, 255, 255, 0.04);\n --b-time-picker-cell-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-footer-bg: #1f1f1f;\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(220, 56, 72, 0.15);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(217, 146, 0, 0.15);\n }\n}\n\n/* ──── Reduced Motion ──── */\n@media (prefers-reduced-motion: reduce) {\n .b-time-picker,\n .b-time-picker * {\n --b-time-picker-transition-duration: 0ms;\n transition-duration: 0ms !important;\n animation-duration: 0ms !important;\n }\n\n .b-time-picker__column {\n scroll-behavior: auto;\n }\n}\n</style>\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import e from "./design-system255.js";
2
+ /* empty css */
3
+ //#region src/components/BTimePicker/BTimePicker.vue
4
+ var t = e;
5
+ //#endregion
6
+ export { t as default };
7
+
8
+ //# sourceMappingURL=design-system257.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-system257.js","names":[],"sources":["../src/components/BTimePicker/BTimePicker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';\n\nimport {\n BTimePickerPlacement,\n BTimePickerSize,\n BTimePickerStatus,\n BTimePickerVariant,\n type BTimePickerDisabledTime,\n} from './types';\n\nconst {\n size = BTimePickerSize.Medium,\n variant = BTimePickerVariant.Outlined,\n placeholder = 'Select time',\n disabled = false,\n inputReadOnly = false,\n allowClear = true,\n showNow = true,\n use12Hours = false,\n hourStep = 1,\n minuteStep = 1,\n secondStep = 1,\n format,\n placement: _placement = BTimePickerPlacement.BottomLeft,\n status,\n hideDisabledOptions = false,\n needConfirm = true,\n changeOnScroll = false,\n showHour = true,\n showMinute = true,\n showSecond = true,\n defaultOpen = false,\n defaultValue,\n open,\n disabledTime,\n} = defineProps<{\n /** Size of the input */\n size?: `${BTimePickerSize}`;\n /** Visual variant */\n variant?: `${BTimePickerVariant}`;\n /** Placeholder text */\n placeholder?: string;\n /** Disable the picker */\n disabled?: boolean;\n /** Make input read-only (useful for touch devices) */\n inputReadOnly?: boolean;\n /** Show clear button */\n allowClear?: boolean;\n /** Show \"Now\" button in footer */\n showNow?: boolean;\n /** Use 12-hour format with AM/PM */\n use12Hours?: boolean;\n /** Hour selection step */\n hourStep?: number;\n /** Minute selection step */\n minuteStep?: number;\n /** Second selection step */\n secondStep?: number;\n /** Time format string (e.g. 'HH:mm:ss', 'hh:mm a') */\n format?: string;\n /** Popup placement */\n placement?: `${BTimePickerPlacement}`;\n /** Validation status */\n status?: `${BTimePickerStatus}`;\n /** Hide disabled time options from columns */\n hideDisabledOptions?: boolean;\n /** Require OK button confirmation before applying value */\n needConfirm?: boolean;\n /** Update value on scroll instead of click */\n changeOnScroll?: boolean;\n /** Show hour column */\n showHour?: boolean;\n /** Show minute column */\n showMinute?: boolean;\n /** Show second column */\n showSecond?: boolean;\n /** Default open state */\n defaultOpen?: boolean;\n /** Default value (uncontrolled) */\n defaultValue?: Date;\n /** Controlled open state */\n open?: boolean;\n /** Function returning disabled hours/minutes/seconds */\n disabledTime?: () => BTimePickerDisabledTime;\n}>();\n\nconst model = defineModel<Date | null>({ default: undefined });\n\nconst emit = defineEmits<{\n change: [time: Date | null, timeString: string];\n openChange: [open: boolean];\n}>();\n\nconst inputEl = ref<HTMLInputElement | null>(null);\nconst panelEl = ref<HTMLElement | null>(null);\nconst hourColEl = ref<HTMLElement | null>(null);\nconst minuteColEl = ref<HTMLElement | null>(null);\nconst secondColEl = ref<HTMLElement | null>(null);\nconst ampmColEl = ref<HTMLElement | null>(null);\n\ndefineExpose({\n focus: () => inputEl.value?.focus(),\n blur: () => inputEl.value?.blur(),\n});\n\nconst { componentUID } = useComponentId();\nconst anchorName = computed(() => `--b-time-picker-${componentUID.value}`);\n\n// ─────────────────────────────────────────────\n// State\n// ─────────────────────────────────────────────\nconst isOpen = ref(defaultOpen);\nconst isPanelOpen = ref(open !== undefined ? !!open : defaultOpen);\nconst internalValue = ref<Date | null>(defaultValue ?? null);\nconst pendingHour = ref<number | null>(null);\nconst pendingMinute = ref<number | null>(null);\nconst pendingSecond = ref<number | null>(null);\nconst pendingAmpm = ref<'AM' | 'PM' | null>(null);\nconst inputText = ref('');\nconst focusedColumn = ref<'hour' | 'minute' | 'second' | 'ampm'>('hour');\n\nconst selectedTime = computed({\n get: () => model.value ?? internalValue.value,\n set: (val) => {\n internalValue.value = val;\n model.value = val;\n },\n});\n\n// ─────────────────────────────────────────────\n// Format\n// ─────────────────────────────────────────────\nconst activeFormat = computed(() => {\n if (format) return format;\n const parts: string[] = [];\n if (showHour) parts.push(use12Hours ? 'hh' : 'HH');\n if (showMinute) parts.push('mm');\n if (showSecond) parts.push('ss');\n const base = parts.join(':');\n return use12Hours ? `${base} A` : base;\n});\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nfunction formatTime(d: Date | null): string {\n if (!d) return '';\n const h = d.getHours();\n const m = d.getMinutes();\n const s = d.getSeconds();\n const ampm = h >= 12 ? 'PM' : 'AM';\n\n let result = activeFormat.value;\n if (use12Hours) {\n const h12 = h % 12 || 12;\n result = result.replace('hh', pad(h12));\n result = result.replace('h', String(h12));\n result = result.replace('A', ampm);\n result = result.replace('a', ampm.toLowerCase());\n } else {\n result = result.replace('HH', pad(h));\n result = result.replace('H', String(h));\n }\n result = result.replace('mm', pad(m));\n result = result.replace('ss', pad(s));\n return result;\n}\n\nfunction parseTimeString(str: string): Date | null {\n if (!str.trim()) return null;\n const timeRegex12 = /(\\d{1,2}):(\\d{2})(?::(\\d{2}))?\\s*(AM|PM|am|pm)?/;\n const match = str.match(timeRegex12);\n if (!match) return null;\n\n let h = parseInt(match[1], 10);\n const m = parseInt(match[2], 10);\n const s = match[3] ? parseInt(match[3], 10) : 0;\n const period = match[4]?.toUpperCase();\n\n if (use12Hours && period) {\n if (period === 'PM' && h < 12) h += 12;\n if (period === 'AM' && h === 12) h = 0;\n }\n\n if (h < 0 || h > 23 || m < 0 || m > 59 || s < 0 || s > 59) return null;\n\n const d = new Date();\n d.setHours(h, m, s, 0);\n return d;\n}\n\n// ─────────────────────────────────────────────\n// Disabled time logic\n// ─────────────────────────────────────────────\nconst disabledHours = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n return dt.disabledHours?.() ?? [];\n});\n\nconst disabledMinutes = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n const h = pendingHour.value ?? selectedTime.value?.getHours() ?? 0;\n return dt.disabledMinutes?.(h) ?? [];\n});\n\nconst disabledSeconds = computed<number[]>(() => {\n if (!disabledTime) return [];\n const dt = disabledTime();\n const h = pendingHour.value ?? selectedTime.value?.getHours() ?? 0;\n const m = pendingMinute.value ?? selectedTime.value?.getMinutes() ?? 0;\n return dt.disabledSeconds?.(h, m) ?? [];\n});\n\n// ─────────────────────────────────────────────\n// Column data\n// ─────────────────────────────────────────────\nconst hours = computed(() => {\n const list: number[] = [];\n if (use12Hours) {\n for (let i = 1; i <= 12; i += hourStep) list.push(i);\n } else {\n for (let i = 0; i < 24; i += hourStep) list.push(i);\n }\n if (hideDisabledOptions) {\n return list.filter((h) => !disabledHours.value.includes(use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h));\n }\n return list;\n});\n\nconst minutes = computed(() => {\n const list: number[] = [];\n for (let i = 0; i < 60; i += minuteStep) list.push(i);\n if (hideDisabledOptions) {\n return list.filter((m) => !disabledMinutes.value.includes(m));\n }\n return list;\n});\n\nconst seconds = computed(() => {\n const list: number[] = [];\n for (let i = 0; i < 60; i += secondStep) list.push(i);\n if (hideDisabledOptions) {\n return list.filter((s) => !disabledSeconds.value.includes(s));\n }\n return list;\n});\n\nfunction to24Hour(h12: number, period: 'AM' | 'PM'): number {\n if (period === 'AM') return h12 === 12 ? 0 : h12;\n return h12 === 12 ? 12 : h12 + 12;\n}\n\nfunction to12Hour(h24: number): { hour: number; period: 'AM' | 'PM' } {\n const period: 'AM' | 'PM' = h24 >= 12 ? 'PM' : 'AM';\n const hour = h24 % 12 || 12;\n return { hour, period };\n}\n\n// ─────────────────────────────────────────────\n// Panel open/close\n// ─────────────────────────────────────────────\nfunction openPanel() {\n if (disabled) return;\n isOpen.value = true;\n isPanelOpen.value = true;\n emit('openChange', true);\n panelEl.value?.showPopover?.();\n syncPendingFromValue();\n nextTick(() => scrollToSelected());\n}\n\nfunction closePanel() {\n isOpen.value = false;\n isPanelOpen.value = false;\n emit('openChange', false);\n panelEl.value?.hidePopover?.();\n inputEl.value?.focus();\n}\n\nfunction togglePanel() {\n if (isPanelOpen.value) closePanel();\n else openPanel();\n}\n\nfunction handlePopoverToggle(e: Event) {\n const toggleEvent = e as ToggleEvent;\n const nowOpen = toggleEvent.newState === 'open';\n isOpen.value = nowOpen;\n isPanelOpen.value = nowOpen;\n if (!nowOpen) emit('openChange', false);\n}\n\n// ─────────────────────────────────────────────\n// Sync pending state\n// ─────────────────────────────────────────────\nfunction syncPendingFromValue() {\n const t = selectedTime.value;\n if (t) {\n if (use12Hours) {\n const { hour, period } = to12Hour(t.getHours());\n pendingHour.value = hour;\n pendingAmpm.value = period;\n } else {\n pendingHour.value = t.getHours();\n }\n pendingMinute.value = t.getMinutes();\n pendingSecond.value = t.getSeconds();\n } else {\n pendingHour.value = null;\n pendingMinute.value = null;\n pendingSecond.value = null;\n pendingAmpm.value = null;\n }\n}\n\n// ─────────────────────────────────────────────\n// Selection\n// ─────────────────────────────────────────────\nfunction selectHour(h: number) {\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n if (disabledHours.value.includes(h24)) return;\n pendingHour.value = h;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectMinute(m: number) {\n if (disabledMinutes.value.includes(m)) return;\n pendingMinute.value = m;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectSecond(s: number) {\n if (disabledSeconds.value.includes(s)) return;\n pendingSecond.value = s;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction selectAmpm(val: 'AM' | 'PM') {\n pendingAmpm.value = val;\n if (!needConfirm && !changeOnScroll) applyPendingIfComplete();\n else if (changeOnScroll) applyPending();\n}\n\nfunction applyPendingIfComplete() {\n if (pendingHour.value !== null && pendingMinute.value !== null) {\n if (showSecond && pendingSecond.value === null) return;\n if (use12Hours && pendingAmpm.value === null) return;\n applyPending();\n closePanel();\n }\n}\n\nfunction applyPending() {\n const h = pendingHour.value ?? 0;\n const m = pendingMinute.value ?? 0;\n const s = pendingSecond.value ?? 0;\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n\n const d = new Date();\n d.setHours(h24, m, s, 0);\n selectedTime.value = d;\n inputText.value = formatTime(d);\n emit('change', d, formatTime(d));\n}\n\nfunction handleOk() {\n applyPending();\n closePanel();\n}\n\nfunction handleNow() {\n const now = new Date();\n if (use12Hours) {\n const { hour, period } = to12Hour(now.getHours());\n pendingHour.value = hour;\n pendingAmpm.value = period;\n } else {\n pendingHour.value = now.getHours();\n }\n pendingMinute.value = now.getMinutes();\n pendingSecond.value = now.getSeconds();\n nextTick(() => scrollToSelected());\n if (!needConfirm) {\n applyPending();\n closePanel();\n }\n}\n\nfunction handleClear(e: Event) {\n e.stopPropagation();\n selectedTime.value = null;\n inputText.value = '';\n pendingHour.value = null;\n pendingMinute.value = null;\n pendingSecond.value = null;\n pendingAmpm.value = null;\n emit('change', null, '');\n}\n\n// ─────────────────────────────────────────────\n// Input handling\n// ─────────────────────────────────────────────\nfunction handleInputChange(e: Event) {\n const val = (e.target as HTMLInputElement).value;\n inputText.value = val;\n}\n\nfunction handleInputBlur() {\n if (!isPanelOpen.value) {\n const parsed = parseTimeString(inputText.value);\n if (parsed) {\n selectedTime.value = parsed;\n inputText.value = formatTime(parsed);\n emit('change', parsed, formatTime(parsed));\n } else if (inputText.value === '') {\n selectedTime.value = null;\n emit('change', null, '');\n } else {\n inputText.value = formatTime(selectedTime.value);\n }\n }\n}\n\nfunction handleInputKeydown(e: KeyboardEvent) {\n if (e.key === 'Enter' || e.key === ' ') {\n if (!isPanelOpen.value) {\n e.preventDefault();\n openPanel();\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const parsed = parseTimeString(inputText.value);\n if (parsed) {\n selectedTime.value = parsed;\n inputText.value = formatTime(parsed);\n emit('change', parsed, formatTime(parsed));\n }\n closePanel();\n }\n } else if (e.key === 'Escape') {\n if (isPanelOpen.value) {\n e.preventDefault();\n closePanel();\n }\n }\n}\n\n// ─────────────────────────────────────────────\n// Panel keyboard navigation\n// ─────────────────────────────────────────────\nfunction handlePanelKeydown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.preventDefault();\n closePanel();\n return;\n }\n\n if (e.key === 'Tab') {\n const columns: ('hour' | 'minute' | 'second' | 'ampm')[] = [];\n if (showHour) columns.push('hour');\n if (showMinute) columns.push('minute');\n if (showSecond) columns.push('second');\n if (use12Hours) columns.push('ampm');\n\n const idx = columns.indexOf(focusedColumn.value);\n if (e.shiftKey) {\n if (idx > 0) {\n e.preventDefault();\n focusedColumn.value = columns[idx - 1];\n }\n } else {\n if (idx < columns.length - 1) {\n e.preventDefault();\n focusedColumn.value = columns[idx + 1];\n }\n }\n return;\n }\n\n if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {\n e.preventDefault();\n const delta = e.key === 'ArrowUp' ? -1 : 1;\n adjustFocusedColumn(delta);\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n handleOk();\n }\n}\n\nfunction adjustFocusedColumn(delta: number) {\n if (focusedColumn.value === 'hour') {\n const list = hours.value;\n const current = pendingHour.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectHour(next);\n scrollColumnTo(hourColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'minute') {\n const list = minutes.value;\n const current = pendingMinute.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectMinute(next);\n scrollColumnTo(minuteColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'second') {\n const list = seconds.value;\n const current = pendingSecond.value ?? list[0];\n const idx = list.indexOf(current);\n const next = list[Math.max(0, Math.min(list.length - 1, idx + delta))];\n selectSecond(next);\n scrollColumnTo(secondColEl.value, list.indexOf(next));\n } else if (focusedColumn.value === 'ampm') {\n const val = pendingAmpm.value === 'AM' ? 'PM' : 'AM';\n selectAmpm(val);\n }\n}\n\n// ─────────────────────────────────────────────\n// Scroll helpers\n// ─────────────────────────────────────────────\nfunction scrollColumnTo(col: HTMLElement | null, idx: number) {\n if (!col || !col.scrollTo) return;\n const cellHeight = 28;\n col.scrollTo({ top: idx * cellHeight, behavior: 'smooth' });\n}\n\nfunction scrollToSelected() {\n if (pendingHour.value !== null) {\n const idx = hours.value.indexOf(pendingHour.value);\n if (idx >= 0) scrollColumnTo(hourColEl.value, idx);\n }\n if (pendingMinute.value !== null) {\n const idx = minutes.value.indexOf(pendingMinute.value);\n if (idx >= 0) scrollColumnTo(minuteColEl.value, idx);\n }\n if (pendingSecond.value !== null && showSecond) {\n const idx = seconds.value.indexOf(pendingSecond.value);\n if (idx >= 0) scrollColumnTo(secondColEl.value, idx);\n }\n if (pendingAmpm.value && use12Hours) {\n const idx = pendingAmpm.value === 'AM' ? 0 : 1;\n scrollColumnTo(ampmColEl.value, idx);\n }\n}\n\n// ─────────────────────────────────────────────\n// Click outside\n// ─────────────────────────────────────────────\nfunction handleClickOutside(e: MouseEvent) {\n if (!isPanelOpen.value) return;\n const target = e.target as Node;\n if (panelEl.value?.contains(target)) return;\n if (inputEl.value?.parentElement?.contains(target)) return;\n closePanel();\n}\n\nonMounted(() => {\n document.addEventListener('mousedown', handleClickOutside);\n});\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', handleClickOutside);\n});\n\n// ─────────────────────────────────────────────\n// Watchers\n// ─────────────────────────────────────────────\nwatch(\n () => open,\n (val) => {\n if (val !== undefined) {\n if (val) openPanel();\n else closePanel();\n }\n },\n);\n\nwatch(selectedTime, (val) => {\n inputText.value = formatTime(val);\n});\n\n// Init display\ninputText.value = formatTime(selectedTime.value);\n\n// ─────────────────────────────────────────────\n// Computed classes\n// ─────────────────────────────────────────────\nconst rootClasses = computed(() => [\n 'b-time-picker',\n `b-time-picker--${size}`,\n `b-time-picker--${variant}`,\n {\n 'b-time-picker--disabled': disabled,\n 'b-time-picker--open': isPanelOpen.value,\n [`b-time-picker--${status}`]: !!status,\n },\n]);\n\nconst isHourDisabled = (h: number) => {\n const h24 = use12Hours ? to24Hour(h, pendingAmpm.value ?? 'AM') : h;\n return disabledHours.value.includes(h24);\n};\nconst isMinuteDisabled = (m: number) => disabledMinutes.value.includes(m);\nconst isSecondDisabled = (s: number) => disabledSeconds.value.includes(s);\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <div\n class=\"b-time-picker__input-wrap\"\n :style=\"{ anchorName }\"\n @click=\"togglePanel\"\n >\n <input\n :id=\"`b-time-picker-input-${componentUID}`\"\n ref=\"inputEl\"\n class=\"b-time-picker__input\"\n type=\"text\"\n role=\"combobox\"\n :aria-expanded=\"isPanelOpen\"\n aria-haspopup=\"dialog\"\n :aria-controls=\"isPanelOpen ? `b-time-picker-panel-${componentUID}` : undefined\"\n :aria-describedby=\"status ? `b-time-picker-status-${componentUID}` : undefined\"\n :aria-label=\"placeholder\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :readonly=\"inputReadOnly\"\n :value=\"inputText\"\n autocomplete=\"off\"\n @input=\"handleInputChange\"\n @blur=\"handleInputBlur\"\n @keydown=\"handleInputKeydown\"\n />\n <span class=\"b-time-picker__suffix\">\n <svg\n v-if=\"!allowClear || !selectedTime\"\n class=\"b-time-picker__icon\"\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n <button\n v-else\n class=\"b-time-picker__clear\"\n type=\"button\"\n aria-label=\"Clear time\"\n tabindex=\"-1\"\n @click=\"handleClear\"\n >\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\" />\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\" />\n </svg>\n </button>\n </span>\n <span\n v-if=\"status\"\n :id=\"`b-time-picker-status-${componentUID}`\"\n class=\"b-time-picker__status-text\"\n aria-live=\"polite\"\n >\n {{ status }}\n </span>\n </div>\n\n <div\n :id=\"`b-time-picker-panel-${componentUID}`\"\n ref=\"panelEl\"\n class=\"b-time-picker__panel\"\n popover\n role=\"dialog\"\n :aria-label=\"'Time picker'\"\n :aria-modal=\"true\"\n :style=\"{ positionAnchor: anchorName }\"\n @toggle=\"handlePopoverToggle\"\n @keydown=\"handlePanelKeydown\"\n >\n <div class=\"b-time-picker__columns\" role=\"group\" aria-label=\"Time selection columns\">\n <!-- Hour Column -->\n <div\n v-if=\"showHour\"\n ref=\"hourColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Hours'\"\n :aria-activedescendant=\"pendingHour !== null ? `b-time-picker-hour-${pendingHour}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"h in hours\"\n :id=\"`b-time-picker-hour-${h}-${componentUID}`\"\n :key=\"h\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingHour === h,\n 'b-time-picker__cell--disabled': isHourDisabled(h),\n 'b-time-picker__cell--focused': focusedColumn === 'hour' && pendingHour === h,\n }\"\n role=\"option\"\n :aria-selected=\"pendingHour === h\"\n :aria-disabled=\"isHourDisabled(h)\"\n @click=\"selectHour(h)\"\n >\n {{ pad(h) }}\n </div>\n </div>\n\n <!-- Minute Column -->\n <div\n v-if=\"showMinute\"\n ref=\"minuteColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Minutes'\"\n :aria-activedescendant=\"pendingMinute !== null ? `b-time-picker-minute-${pendingMinute}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"m in minutes\"\n :id=\"`b-time-picker-minute-${m}-${componentUID}`\"\n :key=\"m\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingMinute === m,\n 'b-time-picker__cell--disabled': isMinuteDisabled(m),\n 'b-time-picker__cell--focused': focusedColumn === 'minute' && pendingMinute === m,\n }\"\n role=\"option\"\n :aria-selected=\"pendingMinute === m\"\n :aria-disabled=\"isMinuteDisabled(m)\"\n @click=\"selectMinute(m)\"\n >\n {{ pad(m) }}\n </div>\n </div>\n\n <!-- Second Column -->\n <div\n v-if=\"showSecond\"\n ref=\"secondColEl\"\n class=\"b-time-picker__column\"\n role=\"listbox\"\n :aria-label=\"'Seconds'\"\n :aria-activedescendant=\"pendingSecond !== null ? `b-time-picker-second-${pendingSecond}-${componentUID}` : undefined\"\n >\n <div\n v-for=\"s in seconds\"\n :id=\"`b-time-picker-second-${s}-${componentUID}`\"\n :key=\"s\"\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingSecond === s,\n 'b-time-picker__cell--disabled': isSecondDisabled(s),\n 'b-time-picker__cell--focused': focusedColumn === 'second' && pendingSecond === s,\n }\"\n role=\"option\"\n :aria-selected=\"pendingSecond === s\"\n :aria-disabled=\"isSecondDisabled(s)\"\n @click=\"selectSecond(s)\"\n >\n {{ pad(s) }}\n </div>\n </div>\n\n <!-- AM/PM Column -->\n <div\n v-if=\"use12Hours\"\n ref=\"ampmColEl\"\n class=\"b-time-picker__column b-time-picker__column--ampm\"\n role=\"listbox\"\n aria-label=\"AM/PM\"\n >\n <div\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingAmpm === 'AM',\n 'b-time-picker__cell--focused': focusedColumn === 'ampm' && pendingAmpm === 'AM',\n }\"\n role=\"option\"\n :aria-selected=\"pendingAmpm === 'AM'\"\n @click=\"selectAmpm('AM')\"\n >\n AM\n </div>\n <div\n class=\"b-time-picker__cell\"\n :class=\"{\n 'b-time-picker__cell--selected': pendingAmpm === 'PM',\n 'b-time-picker__cell--focused': focusedColumn === 'ampm' && pendingAmpm === 'PM',\n }\"\n role=\"option\"\n :aria-selected=\"pendingAmpm === 'PM'\"\n @click=\"selectAmpm('PM')\"\n >\n PM\n </div>\n </div>\n </div>\n\n <div v-if=\"needConfirm || showNow\" class=\"b-time-picker__footer\">\n <button\n v-if=\"showNow\"\n class=\"b-time-picker__now-btn\"\n type=\"button\"\n @click=\"handleNow\"\n >\n Now\n </button>\n <button\n v-if=\"needConfirm\"\n class=\"b-time-picker__ok-btn\"\n type=\"button\"\n @click=\"handleOk\"\n >\n OK\n </button>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n.b-time-picker {\n --b-time-picker-input-font-size: 14px;\n --b-time-picker-input-font-size-lg: 16px;\n --b-time-picker-input-font-size-sm: 14px;\n --b-time-picker-padding-block: 4px;\n --b-time-picker-padding-block-lg: 7px;\n --b-time-picker-padding-block-sm: 0px;\n --b-time-picker-padding-inline: 11px;\n --b-time-picker-padding-inline-lg: 11px;\n --b-time-picker-padding-inline-sm: 7px;\n --b-time-picker-border-color: #d9d9d9;\n --b-time-picker-hover-border-color: #4096ff;\n --b-time-picker-active-border-color: #1677ff;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(5, 145, 255, 0.1);\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(255, 38, 5, 0.06);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(255, 215, 5, 0.1);\n --b-time-picker-bg: #ffffff;\n --b-time-picker-hover-bg: #ffffff;\n --b-time-picker-active-bg: #ffffff;\n --b-time-picker-text-color: rgba(0, 0, 0, 0.88);\n --b-time-picker-placeholder-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-icon-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-clear-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-clear-hover-color: rgba(0, 0, 0, 0.45);\n --b-time-picker-disabled-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-disabled-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-panel-bg: #ffffff;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-time-picker-cell-height: 28px;\n --b-time-picker-cell-width: 56px;\n --b-time-picker-cell-hover-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-cell-selected-bg: #e6f4ff;\n --b-time-picker-cell-disabled-bg: rgba(0, 0, 0, 0.04);\n --b-time-picker-cell-disabled-color: rgba(0, 0, 0, 0.25);\n --b-time-picker-column-height: 224px;\n --b-time-picker-column-width: 56px;\n --b-time-picker-footer-bg: #ffffff;\n --b-time-picker-border-radius: 6px;\n --b-time-picker-panel-border-radius: 8px;\n --b-time-picker-transition-duration: 0.2s;\n --b-time-picker-z-index-popup: 1050;\n\n position: relative;\n display: inline-flex;\n width: 100%;\n max-width: 200px;\n}\n\n/* ──── Input Wrap ──── */\n.b-time-picker__input-wrap {\n display: flex;\n align-items: center;\n width: 100%;\n background: var(--b-time-picker-bg);\n border: 1px solid var(--b-time-picker-border-color);\n border-radius: var(--b-time-picker-border-radius);\n padding: var(--b-time-picker-padding-block) var(--b-time-picker-padding-inline);\n cursor: pointer;\n transition:\n border-color var(--b-time-picker-transition-duration),\n box-shadow var(--b-time-picker-transition-duration),\n background var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__input-wrap:hover {\n border-color: var(--b-time-picker-hover-border-color);\n background: var(--b-time-picker-hover-bg);\n}\n\n.b-time-picker--open .b-time-picker__input-wrap {\n border-color: var(--b-time-picker-active-border-color);\n box-shadow: var(--b-time-picker-active-shadow);\n background: var(--b-time-picker-active-bg);\n}\n\n/* ──── Size Variants ──── */\n.b-time-picker--sm .b-time-picker__input-wrap {\n padding: var(--b-time-picker-padding-block-sm) var(--b-time-picker-padding-inline-sm);\n}\n\n.b-time-picker--sm .b-time-picker__input {\n font-size: var(--b-time-picker-input-font-size-sm);\n}\n\n.b-time-picker--lg .b-time-picker__input-wrap {\n padding: var(--b-time-picker-padding-block-lg) var(--b-time-picker-padding-inline-lg);\n}\n\n.b-time-picker--lg .b-time-picker__input {\n font-size: var(--b-time-picker-input-font-size-lg);\n}\n\n/* ──── Variant Styles ──── */\n.b-time-picker--filled .b-time-picker__input-wrap {\n background: rgba(0, 0, 0, 0.04);\n border-color: transparent;\n}\n\n.b-time-picker--filled .b-time-picker__input-wrap:hover {\n background: rgba(0, 0, 0, 0.06);\n}\n\n.b-time-picker--borderless .b-time-picker__input-wrap {\n border-color: transparent;\n background: transparent;\n box-shadow: none;\n}\n\n.b-time-picker--underlined .b-time-picker__input-wrap {\n border-radius: 0;\n border: none;\n border-bottom: 1px solid var(--b-time-picker-border-color);\n}\n\n.b-time-picker--underlined .b-time-picker__input-wrap:hover {\n border-bottom-color: var(--b-time-picker-hover-border-color);\n}\n\n.b-time-picker--underlined.b-time-picker--open .b-time-picker__input-wrap {\n border-bottom-color: var(--b-time-picker-active-border-color);\n box-shadow: none;\n}\n\n/* ──── Status ──── */\n.b-time-picker--error .b-time-picker__input-wrap {\n border-color: #ff4d4f;\n}\n\n.b-time-picker--error.b-time-picker--open .b-time-picker__input-wrap {\n box-shadow: var(--b-time-picker-error-active-shadow);\n}\n\n.b-time-picker--warning .b-time-picker__input-wrap {\n border-color: #faad14;\n}\n\n.b-time-picker--warning.b-time-picker--open .b-time-picker__input-wrap {\n box-shadow: var(--b-time-picker-warning-active-shadow);\n}\n\n/* ──── Disabled ──── */\n.b-time-picker--disabled .b-time-picker__input-wrap {\n background: var(--b-time-picker-disabled-bg);\n border-color: var(--b-time-picker-border-color);\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.b-time-picker--disabled .b-time-picker__input {\n color: var(--b-time-picker-disabled-color);\n cursor: not-allowed;\n}\n\n/* ──── Input ──── */\n.b-time-picker__input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-size: var(--b-time-picker-input-font-size);\n color: var(--b-time-picker-text-color);\n line-height: 1.5;\n padding: 0;\n min-width: 0;\n}\n\n.b-time-picker__input::placeholder {\n color: var(--b-time-picker-placeholder-color);\n}\n\n/* ──── Suffix / Icons ──── */\n.b-time-picker__suffix {\n display: flex;\n align-items: center;\n margin-left: 4px;\n flex-shrink: 0;\n}\n\n.b-time-picker__icon {\n width: 14px;\n height: 14px;\n color: var(--b-time-picker-icon-color);\n}\n\n.b-time-picker__clear {\n display: flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: none;\n padding: 0;\n cursor: pointer;\n color: var(--b-time-picker-clear-color);\n transition: color var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__clear:hover {\n color: var(--b-time-picker-clear-hover-color);\n}\n\n.b-time-picker__clear svg {\n width: 14px;\n height: 14px;\n}\n\n.b-time-picker__status-text {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n}\n\n/* ──── Panel ──── */\n.b-time-picker__panel {\n position: absolute;\n position-anchor: var(--b-time-picker-anchor);\n inset: unset;\n top: anchor(bottom);\n left: anchor(left);\n margin: 0;\n margin-top: 4px;\n padding: 0;\n border: none;\n border-radius: var(--b-time-picker-panel-border-radius);\n background: var(--b-time-picker-panel-bg);\n box-shadow: var(--b-time-picker-panel-shadow);\n z-index: var(--b-time-picker-z-index-popup);\n overflow: hidden;\n opacity: 0;\n transform: translateY(-4px);\n transition:\n opacity var(--b-time-picker-transition-duration) ease,\n transform var(--b-time-picker-transition-duration) ease;\n}\n\n.b-time-picker__panel:popover-open {\n opacity: 1;\n transform: translateY(0);\n}\n\n@starting-style {\n .b-time-picker__panel:popover-open {\n opacity: 0;\n transform: translateY(-4px);\n }\n}\n\n/* ──── Columns ──── */\n.b-time-picker__columns {\n display: flex;\n border-bottom: 1px solid #f0f0f0;\n}\n\n.b-time-picker__column {\n width: var(--b-time-picker-column-width);\n height: var(--b-time-picker-column-height);\n overflow-y: auto;\n overflow-x: hidden;\n border-right: 1px solid #f0f0f0;\n scroll-behavior: smooth;\n scrollbar-width: thin;\n}\n\n.b-time-picker__column:last-child {\n border-right: none;\n}\n\n/* ──── Cells ──── */\n.b-time-picker__cell {\n height: var(--b-time-picker-cell-height);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 14px;\n color: var(--b-time-picker-text-color);\n transition: background var(--b-time-picker-transition-duration);\n user-select: none;\n}\n\n.b-time-picker__cell:hover {\n background: var(--b-time-picker-cell-hover-bg);\n}\n\n.b-time-picker__cell--selected {\n background: var(--b-time-picker-cell-selected-bg);\n font-weight: 600;\n}\n\n.b-time-picker__cell--focused {\n outline: 2px solid var(--b-time-picker-active-border-color);\n outline-offset: -2px;\n}\n\n.b-time-picker__cell--disabled {\n color: var(--b-time-picker-cell-disabled-color);\n background: var(--b-time-picker-cell-disabled-bg);\n cursor: not-allowed;\n}\n\n.b-time-picker__cell--disabled:hover {\n background: var(--b-time-picker-cell-disabled-bg);\n}\n\n/* ──── Footer ──── */\n.b-time-picker__footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 8px;\n background: var(--b-time-picker-footer-bg);\n}\n\n.b-time-picker__now-btn {\n border: none;\n background: none;\n color: var(--b-time-picker-active-border-color);\n cursor: pointer;\n font-size: 14px;\n padding: 4px 8px;\n border-radius: 4px;\n transition: background var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__now-btn:hover {\n background: rgba(0, 0, 0, 0.04);\n}\n\n.b-time-picker__ok-btn {\n border: none;\n background: var(--b-time-picker-active-border-color);\n color: #fff;\n cursor: pointer;\n font-size: 14px;\n padding: 2px 12px;\n border-radius: 4px;\n font-weight: 500;\n line-height: 1.5;\n transition:\n background var(--b-time-picker-transition-duration),\n opacity var(--b-time-picker-transition-duration);\n}\n\n.b-time-picker__ok-btn:hover {\n opacity: 0.85;\n}\n\n/* ──── Placement ──── */\n.b-time-picker--bottom-right .b-time-picker__panel {\n left: unset;\n right: anchor(right);\n}\n\n.b-time-picker--top-left .b-time-picker__panel {\n top: unset;\n bottom: anchor(top);\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n.b-time-picker--top-right .b-time-picker__panel {\n top: unset;\n bottom: anchor(top);\n left: unset;\n right: anchor(right);\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n/* ──── Dark Mode ──── */\n[data-prefers-color='dark'] .b-time-picker {\n --b-time-picker-bg: #141414;\n --b-time-picker-hover-bg: #141414;\n --b-time-picker-active-bg: #141414;\n --b-time-picker-border-color: #424242;\n --b-time-picker-hover-border-color: #165dff;\n --b-time-picker-active-border-color: #1668dc;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-time-picker-text-color: rgba(255, 255, 255, 0.85);\n --b-time-picker-placeholder-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-icon-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-hover-color: rgba(255, 255, 255, 0.55);\n --b-time-picker-disabled-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-panel-bg: #1f1f1f;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-time-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-cell-selected-bg: #111a2c;\n --b-time-picker-cell-disabled-bg: rgba(255, 255, 255, 0.04);\n --b-time-picker-cell-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-footer-bg: #1f1f1f;\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(220, 56, 72, 0.15);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(217, 146, 0, 0.15);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-time-picker {\n --b-time-picker-bg: #141414;\n --b-time-picker-hover-bg: #141414;\n --b-time-picker-active-bg: #141414;\n --b-time-picker-border-color: #424242;\n --b-time-picker-hover-border-color: #165dff;\n --b-time-picker-active-border-color: #1668dc;\n --b-time-picker-active-shadow: 0 0 0 2px rgba(22, 104, 220, 0.15);\n --b-time-picker-text-color: rgba(255, 255, 255, 0.85);\n --b-time-picker-placeholder-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-icon-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-color: rgba(255, 255, 255, 0.3);\n --b-time-picker-clear-hover-color: rgba(255, 255, 255, 0.55);\n --b-time-picker-disabled-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-panel-bg: #1f1f1f;\n --b-time-picker-panel-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.32), 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-time-picker-cell-hover-bg: rgba(255, 255, 255, 0.08);\n --b-time-picker-cell-selected-bg: #111a2c;\n --b-time-picker-cell-disabled-bg: rgba(255, 255, 255, 0.04);\n --b-time-picker-cell-disabled-color: rgba(255, 255, 255, 0.25);\n --b-time-picker-footer-bg: #1f1f1f;\n --b-time-picker-error-active-shadow: 0 0 0 2px rgba(220, 56, 72, 0.15);\n --b-time-picker-warning-active-shadow: 0 0 0 2px rgba(217, 146, 0, 0.15);\n }\n}\n\n/* ──── Reduced Motion ──── */\n@media (prefers-reduced-motion: reduce) {\n .b-time-picker,\n .b-time-picker * {\n --b-time-picker-transition-duration: 0ms;\n transition-duration: 0ms !important;\n animation-duration: 0ms !important;\n }\n\n .b-time-picker__column {\n scroll-behavior: auto;\n }\n}\n</style>\n"],"mappings":""}
@@ -1,9 +1,115 @@
1
- import e from "./design-system14.js";
2
- import t from "./design-system256.js";
3
- /* empty css */
4
- //#region src/components/BTreeSelect/BTreeSelect.vue
5
- var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-79b7111a"]]);
1
+ import { Fragment as e, computed as t, createCommentVNode as n, createElementBlock as r, createElementVNode as i, defineComponent as a, normalizeClass as o, normalizeStyle as s, openBlock as c, provide as l, renderList as u, renderSlot as d, toDisplayString as f } from "vue";
2
+ //#region src/components/BTimeline/BTimeline.vue?vue&type=script&setup=true&lang.ts
3
+ var p = { class: "b-timeline-item__label" }, m = {
4
+ class: "b-timeline-item__dot-wrapper",
5
+ "aria-hidden": "true"
6
+ }, h = ["data-icon"], g = {
7
+ key: 1,
8
+ class: "b-timeline-item__dot--pending-spinner"
9
+ }, _ = {
10
+ key: 2,
11
+ class: "b-timeline-item__dot"
12
+ }, v = { class: "b-timeline-item__content" }, y = {
13
+ class: "b-timeline-item__dot-wrapper",
14
+ "aria-hidden": "true"
15
+ }, b = ["data-icon"], x = {
16
+ key: 1,
17
+ class: "b-timeline-item__dot--pending-spinner",
18
+ "aria-hidden": "true"
19
+ }, S = { class: "b-timeline-item__content" }, C = /* @__PURE__ */ a({
20
+ __name: "BTimeline",
21
+ props: {
22
+ mode: { default: "start" },
23
+ variant: { default: "filled" },
24
+ orientation: { default: "vertical" },
25
+ pending: {
26
+ type: [Boolean, String],
27
+ default: !1
28
+ },
29
+ pendingDot: {},
30
+ reverse: {
31
+ type: Boolean,
32
+ default: !1
33
+ },
34
+ items: {}
35
+ },
36
+ setup(a) {
37
+ l("b-timeline-mode", a.mode), l("b-timeline-variant", a.variant);
38
+ let C = t(() => !!a.pending), w = t(() => a.pending !== !0 && a.pending ? a.pending : ""), T = t(() => a.items ? a.reverse ? [...a.items].reverse() : a.items : []), E = [
39
+ "blue",
40
+ "red",
41
+ "green",
42
+ "gray"
43
+ ];
44
+ function D(e) {
45
+ return !e || E.includes(e);
46
+ }
47
+ function O(e) {
48
+ if (!(!e || D(e))) return { "--b-timeline-item-dot-color": e };
49
+ }
50
+ function k(e) {
51
+ let t = e ?? "blue";
52
+ return D(t) ? `b-timeline-item--${t}` : "b-timeline-item--custom";
53
+ }
54
+ let A = t(() => [
55
+ "b-timeline",
56
+ `b-timeline--${a.mode}`,
57
+ `b-timeline--${a.variant}`,
58
+ `b-timeline--${a.orientation}`,
59
+ {
60
+ "b-timeline--pending": C.value,
61
+ "b-timeline--reverse": a.reverse
62
+ }
63
+ ]);
64
+ function j(e, t) {
65
+ return t ? t === "end" ? "b-timeline-item--right" : "b-timeline-item--left" : a.mode === "alternate" ? e % 2 == 0 ? "b-timeline-item--left" : "b-timeline-item--right" : a.mode === "end" ? "b-timeline-item--right" : "b-timeline-item--left";
66
+ }
67
+ return (t, l) => (c(), r("ol", {
68
+ class: o(A.value),
69
+ "aria-label": "Timeline"
70
+ }, [a.items && a.items.length ? (c(!0), r(e, { key: 0 }, u(T.value, (e, t) => (c(), r("li", {
71
+ key: t,
72
+ class: o(["b-timeline-item", [
73
+ k(e.color),
74
+ j(t, e.placement),
75
+ { "b-timeline-item--pending": e.loading },
76
+ e.className
77
+ ]]),
78
+ style: s([O(e.color), (e.style, e.style)])
79
+ }, [
80
+ i("span", p, f(e.title ?? ""), 1),
81
+ l[0] ||= i("div", {
82
+ class: "b-timeline-item__tail",
83
+ "aria-hidden": "true"
84
+ }, null, -1),
85
+ i("div", m, [e.icon ? (c(), r("span", {
86
+ key: 0,
87
+ class: "b-timeline-item__dot--custom",
88
+ "data-icon": e.icon,
89
+ "aria-hidden": "true"
90
+ }, null, 8, h)) : e.loading ? (c(), r("span", g)) : (c(), r("span", _))]),
91
+ i("div", v, f(e.content), 1)
92
+ ], 6))), 128)) : d(t.$slots, "default", { key: 1 }), C.value ? (c(), r("li", {
93
+ key: 2,
94
+ class: o(["b-timeline-item b-timeline-item--pending", [j(a.items ? T.value.length : 0)]]),
95
+ "aria-label": "Pending"
96
+ }, [
97
+ l[1] ||= i("span", { class: "b-timeline-item__label" }, null, -1),
98
+ l[2] ||= i("div", {
99
+ class: "b-timeline-item__tail",
100
+ "aria-hidden": "true"
101
+ }, null, -1),
102
+ i("div", y, [d(t.$slots, "pendingDot", {}, () => [a.pendingDot ? (c(), r("span", {
103
+ key: 0,
104
+ class: "b-timeline-item__dot--custom",
105
+ "data-icon": a.pendingDot,
106
+ "aria-hidden": "true"
107
+ }, null, 8, b)) : (c(), r("span", x))])]),
108
+ i("div", S, f(w.value), 1)
109
+ ], 2)) : n("", !0)], 2));
110
+ }
111
+ });
6
112
  //#endregion
7
- export { n as default };
113
+ export { C as default };
8
114
 
9
115
  //# sourceMappingURL=design-system258.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"design-system258.js","names":[],"sources":["../src/components/BTreeSelect/BTreeSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useComponentId } from '@/composables/useComponentId.ts';\nimport { BCommonSize } from '@/types.ts';\nimport { computed, nextTick, ref, useAttrs, watch } from 'vue';\nimport {\n BTreeSelectPlacement,\n BTreeSelectStatus,\n BTreeSelectVariant,\n type BTreeSelectChangeExtra,\n type BTreeSelectExpandAction,\n type BTreeSelectFieldNames,\n type BTreeSelectFlatNode,\n type BTreeSelectLabeledValue,\n type BTreeSelectModelValue,\n type BTreeSelectNode,\n type BTreeSelectShowSearchConfig,\n type BTreeSelectValue,\n} from './types.ts';\n\ndefineOptions({ inheritAttrs: false });\n\nconst attrs = useAttrs();\n\nconst {\n treeData = [],\n fieldNames,\n multiple = false,\n treeCheckable = false,\n treeCheckStrictly = false,\n labelInValue = false,\n size = BCommonSize.Medium,\n variant = BTreeSelectVariant.Outlined,\n placeholder,\n disabled = false,\n status,\n defaultOpen = false,\n showSearch = false,\n treeDefaultExpandAll = false,\n treeDefaultExpandedKeys = [],\n treeExpandedKeys: treeExpandedKeysProp,\n treeExpandAction = false,\n treeIcon = false,\n treeLine = false,\n loadData,\n placement: _placement = BTreeSelectPlacement.BottomLeft,\n popupMatchSelectWidth = true,\n listHeight = 256,\n maxTagCount,\n maxTagPlaceholder,\n maxCount,\n allowClear = false,\n notFoundContent = 'Not Found',\n filterTreeNode = true,\n treeNodeFilterProp = 'title',\n treeNodeLabelProp,\n} = defineProps<{\n /** Hierarchical data of the tree. */\n treeData?: BTreeSelectNode[];\n /** Replace default field names. */\n fieldNames?: BTreeSelectFieldNames;\n /** Allow multiple selection (without checkboxes). */\n multiple?: boolean;\n /** Show checkboxes — implies multiple. */\n treeCheckable?: boolean;\n /** Whether checkable parent/child are independent. */\n treeCheckStrictly?: boolean;\n /** Embed label in value (returns `{ value, label }`). */\n labelInValue?: boolean;\n /** Selector size. */\n size?: `${BCommonSize}`;\n /** Visual variant. */\n variant?: `${BTreeSelectVariant}`;\n /** Placeholder text when nothing selected. */\n placeholder?: string;\n /** Disable the component. */\n disabled?: boolean;\n /** Validation status. */\n status?: `${BTreeSelectStatus}`;\n /** Default open state (uncontrolled). */\n defaultOpen?: boolean;\n /** Show search input — `true` or a config object. */\n showSearch?: boolean | BTreeSelectShowSearchConfig;\n /** Expand all nodes on mount. */\n treeDefaultExpandAll?: boolean;\n /** Default expanded keys (uncontrolled). */\n treeDefaultExpandedKeys?: BTreeSelectValue[];\n /** Controlled expanded keys. */\n treeExpandedKeys?: BTreeSelectValue[];\n /** When to expand on click — `click | doubleClick | false`. */\n treeExpandAction?: BTreeSelectExpandAction;\n /** Show node icons. */\n treeIcon?: boolean;\n /** Show connector lines between nodes. */\n treeLine?: boolean;\n /** Async-load child nodes. */\n loadData?: (node: BTreeSelectNode) => Promise<void>;\n /** Dropdown placement. */\n placement?: `${BTreeSelectPlacement}`;\n /** Match popup width to selector. */\n popupMatchSelectWidth?: boolean | number;\n /** Max popup list height in px. */\n listHeight?: number;\n /** Max tags to show before collapsing into +N. */\n maxTagCount?: number | 'responsive';\n /** Custom +N tag content (function or string). */\n maxTagPlaceholder?: string | ((omitted: BTreeSelectLabeledValue[]) => string);\n /** Maximum selectable nodes. */\n maxCount?: number;\n /** Show a clear button when there is a value. */\n allowClear?: boolean;\n /** Content when search yields no results. */\n notFoundContent?: string;\n /** Filter behavior — `true` uses default, `false` disables, function for custom. */\n filterTreeNode?: boolean | ((input: string, node: BTreeSelectNode) => boolean);\n /** Property of the node used for default filtering. */\n treeNodeFilterProp?: string;\n /** Property used as the displayed label (defaults to fieldNames.label). */\n treeNodeLabelProp?: string;\n}>();\n\nconst emit = defineEmits<{\n /** Fires when selection value changes. */\n change: [\n value: BTreeSelectValue | BTreeSelectValue[] | BTreeSelectLabeledValue | BTreeSelectLabeledValue[] | undefined,\n label: string | string[],\n extra: BTreeSelectChangeExtra,\n ];\n /** Fires when a node is selected (single/multiple modes). */\n select: [value: BTreeSelectValue, node: BTreeSelectNode];\n /** Fires when a node is deselected (multiple/treeCheckable modes). */\n deselect: [value: BTreeSelectValue, node: BTreeSelectNode];\n /** Fires when a node is checked/unchecked (treeCheckable mode). */\n treeCheck: [keys: BTreeSelectValue[], info: { checked: boolean; node: BTreeSelectNode }];\n /** Fires when popup visibility changes. */\n openChange: [open: boolean];\n /** Fires when the popup scrolls. */\n popupScroll: [event: Event];\n /** Fires when expanded keys change. */\n treeExpand: [expandedKeys: BTreeSelectValue[]];\n /** Fires when search input changes. */\n search: [value: string];\n /** Fires when clear is pressed. */\n clear: [];\n /** Fires on selector focus. */\n focus: [event: FocusEvent];\n /** Fires on selector blur. */\n blur: [event: FocusEvent];\n}>();\n\nconst model = defineModel<BTreeSelectModelValue>();\nconst openModel = defineModel<boolean>('open', { default: false });\nif (defaultOpen && !openModel.value) openModel.value = defaultOpen;\n\ndefineSlots<{\n /** Suffix icon (replaces default arrow). */\n suffixIcon?(): unknown;\n /** Custom switcher icon. */\n switcherIcon?(props: { node: BTreeSelectNode; expanded: boolean }): unknown;\n /** Custom node title renderer. */\n title?(props: { node: BTreeSelectNode }): unknown;\n /** Custom tag renderer (multiple/treeCheckable). */\n tagRender?(props: { value: BTreeSelectValue; label: string; closable: boolean; onClose: () => void }): unknown;\n /** Custom not-found content. */\n notFoundContent?(): unknown;\n /** Custom node icon. */\n treeIcon?(props: { node: BTreeSelectNode }): unknown;\n}>();\n\n// ─── Field name resolution ────────────────────────────────────────────────────\nconst labelField = computed(() => fieldNames?.label ?? 'title');\nconst valueField = computed(() => fieldNames?.value ?? 'value');\nconst childrenField = computed(() => fieldNames?.children ?? 'children');\nconst displayLabelField = computed(() => treeNodeLabelProp ?? labelField.value);\n\nfunction getLabel(n: BTreeSelectNode): string {\n return String((n as Record<string, unknown>)[labelField.value] ?? '');\n}\nfunction getDisplayLabel(n: BTreeSelectNode): string {\n const v = (n as Record<string, unknown>)[displayLabelField.value];\n return v == null ? getLabel(n) : String(v);\n}\nfunction getValue(n: BTreeSelectNode): BTreeSelectValue {\n return (n as Record<string, unknown>)[valueField.value] as BTreeSelectValue;\n}\nfunction getKey(n: BTreeSelectNode): BTreeSelectValue {\n return (n.key as BTreeSelectValue) ?? getValue(n);\n}\nfunction getChildren(n: BTreeSelectNode): BTreeSelectNode[] | undefined {\n return (n as Record<string, unknown>)[childrenField.value] as BTreeSelectNode[] | undefined;\n}\n\n// ─── Identity / IDs ───────────────────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst anchorName = computed(() => `--b-tree-select-anchor-${componentUID.value}`);\nconst treeId = computed(() => `b-tree-select-tree-${componentUID.value}`);\n\n// ─── Refs ─────────────────────────────────────────────────────────────────────\nconst selectorRef = ref<HTMLElement | null>(null);\nconst searchInputRef = ref<HTMLInputElement | null>(null);\nconst popoverRef = ref<HTMLElement | null>(null);\nconst treeRef = ref<HTMLElement | null>(null);\n\n// ─── State ────────────────────────────────────────────────────────────────────\nconst isOpen = computed(() => !!openModel.value);\n\nconst searchValue = ref('');\n\nconst internalExpanded = ref<Set<BTreeSelectValue>>(new Set());\nconst isControlledExpanded = computed(() => treeExpandedKeysProp !== undefined);\nconst activeExpanded = computed<Set<BTreeSelectValue>>(() => {\n if (isControlledExpanded.value) return new Set(treeExpandedKeysProp);\n return internalExpanded.value;\n});\n\nconst focusedKey = ref<BTreeSelectValue | null>(null);\nconst loadingKeys = ref<Set<BTreeSelectValue>>(new Set());\nconst loadedKeys = ref<Set<BTreeSelectValue>>(new Set());\n\n// ─── Mode helpers ────────────────────────────────────────────────────────────\nconst isMultiple = computed(() => multiple || treeCheckable);\n\n// ─── Tree traversal ───────────────────────────────────────────────────────────\nfunction flatten(\n nodes: BTreeSelectNode[],\n depth = 0,\n parents: BTreeSelectValue[] = [],\n parentVisible = true,\n): BTreeSelectFlatNode[] {\n const out: BTreeSelectFlatNode[] = [];\n for (const node of nodes) {\n const value = getValue(node);\n const key = getKey(node);\n const expanded = activeExpanded.value.has(key);\n out.push({ key, value, data: node, depth, visible: parentVisible, parents });\n const children = getChildren(node);\n if (children?.length) {\n out.push(...flatten(children, depth + 1, [...parents, value], parentVisible && expanded));\n }\n }\n return out;\n}\n\nconst flatNodes = computed(() => flatten(treeData));\nconst nodeByValue = computed(() => {\n const map = new Map<BTreeSelectValue, BTreeSelectNode>();\n for (const f of flatNodes.value) map.set(f.value, f.data);\n return map;\n});\n\n// ─── Search filtering ─────────────────────────────────────────────────────────\nconst searchEnabled = computed(() => !!showSearch);\n\nfunction nodeMatches(node: BTreeSelectNode, query: string): boolean {\n if (!query) return true;\n if (typeof filterTreeNode === 'function') return filterTreeNode(query, node);\n if (filterTreeNode === false) return true;\n const cfg = typeof showSearch === 'object' && showSearch !== null ? showSearch : null;\n if (cfg?.filter) return cfg.filter(query, node);\n const prop = treeNodeFilterProp ?? 'title';\n const value = (node as Record<string, unknown>)[prop];\n return String(value ?? '')\n .toLowerCase()\n .includes(query.toLowerCase());\n}\n\nconst visibleFlatNodes = computed(() => {\n const q = searchValue.value.trim();\n if (!q) return flatNodes.value.filter((n) => n.visible);\n\n // Show ancestors of any matching node\n const keepValues = new Set<BTreeSelectValue>();\n for (const f of flatNodes.value) {\n if (nodeMatches(f.data, q)) {\n keepValues.add(f.value);\n f.parents.forEach((p) => keepValues.add(p));\n }\n }\n return flatNodes.value\n .filter((f) => keepValues.has(f.value))\n .map((f) => ({ ...f, visible: true }));\n});\n\n// ─── Value / model helpers ────────────────────────────────────────────────────\nfunction toRawValue(v: BTreeSelectValue | BTreeSelectLabeledValue): BTreeSelectValue {\n if (typeof v === 'object' && v !== null) return v.value;\n return v as BTreeSelectValue;\n}\n\nconst selectedValues = computed<BTreeSelectValue[]>(() => {\n const m = model.value;\n if (m == null) return [];\n if (Array.isArray(m)) return m.map(toRawValue);\n return [toRawValue(m as BTreeSelectValue | BTreeSelectLabeledValue)];\n});\n\nconst selectedSet = computed(() => new Set(selectedValues.value));\n\n// In treeCheckable mode w/o strict, derive half-checked state from selectedValues\nconst halfCheckedSet = computed<Set<BTreeSelectValue>>(() => {\n if (!treeCheckable || treeCheckStrictly) return new Set();\n const half = new Set<BTreeSelectValue>();\n function walk(nodes: BTreeSelectNode[]): { all: boolean; some: boolean } {\n let all = true;\n let some = false;\n for (const n of nodes) {\n const v = getValue(n);\n const children = getChildren(n);\n if (children?.length) {\n const sub = walk(children);\n if (sub.all) {\n some = true;\n } else if (sub.some) {\n half.add(v);\n all = false;\n some = true;\n } else {\n if (!selectedSet.value.has(v)) all = false;\n else some = true;\n }\n } else {\n if (!selectedSet.value.has(v)) all = false;\n else some = true;\n }\n }\n return { all, some };\n }\n walk(treeData);\n return half;\n});\n\n// ─── Display tags / single label ──────────────────────────────────────────────\nconst displayTags = computed<BTreeSelectLabeledValue[]>(() => {\n return selectedValues.value.map((v) => {\n const node = nodeByValue.value.get(v);\n const fromModel = Array.isArray(model.value)\n ? (model.value.find(\n (m) => typeof m === 'object' && m !== null && 'value' in m && (m as BTreeSelectLabeledValue).value === v,\n ) as BTreeSelectLabeledValue | undefined)\n : typeof model.value === 'object' && model.value !== null && 'value' in (model.value as object) &&\n (model.value as BTreeSelectLabeledValue).value === v\n ? (model.value as BTreeSelectLabeledValue)\n : undefined;\n const label = node ? getDisplayLabel(node) : (fromModel?.label ?? String(v));\n return { value: v, label };\n });\n});\n\nconst singleLabel = computed(() => displayTags.value[0]?.label ?? '');\n\nconst visibleTags = computed(() => {\n if (maxTagCount == null || maxTagCount === 'responsive') return displayTags.value;\n return displayTags.value.slice(0, maxTagCount as number);\n});\n\nconst omittedTags = computed(() => {\n if (maxTagCount == null || maxTagCount === 'responsive') return [] as BTreeSelectLabeledValue[];\n return displayTags.value.slice(maxTagCount as number);\n});\n\nconst omittedPlaceholder = computed(() => {\n const omitted = omittedTags.value;\n if (omitted.length === 0) return '';\n if (typeof maxTagPlaceholder === 'function') return maxTagPlaceholder(omitted);\n if (typeof maxTagPlaceholder === 'string') return maxTagPlaceholder;\n return `+ ${omitted.length} ...`;\n});\n\n// ─── Initialise expanded ──────────────────────────────────────────────────────\nfunction collectAllExpandableKeys(nodes: BTreeSelectNode[]): BTreeSelectValue[] {\n const out: BTreeSelectValue[] = [];\n for (const n of nodes) {\n const ch = getChildren(n);\n if (ch?.length) {\n out.push(getKey(n));\n out.push(...collectAllExpandableKeys(ch));\n }\n }\n return out;\n}\n\nif (!isControlledExpanded.value) {\n if (treeDefaultExpandAll) {\n internalExpanded.value = new Set(collectAllExpandableKeys(treeData));\n } else if (treeDefaultExpandedKeys.length) {\n internalExpanded.value = new Set(treeDefaultExpandedKeys);\n }\n}\n\n// ─── Open/close ───────────────────────────────────────────────────────────────\nlet previouslyFocusedElement: HTMLElement | null = null;\n\nfunction setOpen(val: boolean) {\n if (openModel.value !== val) openModel.value = val;\n emit('openChange', val);\n}\n\nfunction openMenu() {\n if (disabled || isOpen.value) return;\n previouslyFocusedElement = document.activeElement as HTMLElement | null;\n setOpen(true);\n}\n\nfunction closeMenu() {\n if (!isOpen.value) return;\n setOpen(false);\n searchValue.value = '';\n // Return focus to selector\n nextTick(() => {\n if (previouslyFocusedElement?.isConnected) {\n previouslyFocusedElement.focus();\n } else {\n selectorRef.value?.focus();\n }\n });\n}\n\nwatch(isOpen, (val) => {\n if (val) {\n nextTick(() => {\n popoverRef.value?.showPopover?.();\n if (searchEnabled.value) searchInputRef.value?.focus();\n // Initial focused node\n if (!focusedKey.value && visibleFlatNodes.value[0]) {\n focusedKey.value = visibleFlatNodes.value[0].key;\n }\n });\n } else {\n popoverRef.value?.hidePopover?.();\n }\n});\n\n// ─── Toggle expand ────────────────────────────────────────────────────────────\nasync function toggleExpand(node: BTreeSelectNode) {\n const k = getKey(node);\n if (node.disabled) return;\n\n const expanding = !activeExpanded.value.has(k);\n\n // Async load\n if (expanding && loadData && !loadedKeys.value.has(k) && !loadingKeys.value.has(k)) {\n loadingKeys.value.add(k);\n try {\n await loadData(node);\n loadedKeys.value.add(k);\n } finally {\n loadingKeys.value.delete(k);\n }\n }\n\n let next: Set<BTreeSelectValue>;\n if (isControlledExpanded.value) {\n next = new Set(treeExpandedKeysProp);\n } else {\n next = new Set(internalExpanded.value);\n }\n if (expanding) next.add(k);\n else next.delete(k);\n\n if (!isControlledExpanded.value) internalExpanded.value = next;\n emit('treeExpand', [...next]);\n}\n\n// ─── Selection / check ────────────────────────────────────────────────────────\nfunction emitChange(\n values: BTreeSelectValue[],\n triggerNode: BTreeSelectNode,\n extra: Partial<BTreeSelectChangeExtra> = {},\n) {\n const labels = values.map((v) => {\n const n = nodeByValue.value.get(v);\n return n ? getDisplayLabel(n) : String(v);\n });\n\n // Build emit value\n let emitValue: BTreeSelectValue | BTreeSelectValue[] | BTreeSelectLabeledValue | BTreeSelectLabeledValue[] | undefined;\n if (isMultiple.value) {\n emitValue = labelInValue\n ? values.map((v, i) => ({ value: v, label: labels[i] }))\n : [...values];\n } else {\n if (values.length === 0) {\n emitValue = labelInValue ? undefined : undefined;\n } else {\n emitValue = labelInValue ? { value: values[0], label: labels[0] } : values[0];\n }\n }\n\n model.value = emitValue;\n emit('change', emitValue, isMultiple.value ? labels : (labels[0] ?? ''), {\n triggerValue: getValue(triggerNode),\n triggerNode,\n ...extra,\n });\n}\n\nfunction selectNode(node: BTreeSelectNode) {\n if (node.disabled || node.selectable === false) return;\n const v = getValue(node);\n\n if (treeCheckable) {\n handleCheck(node);\n return;\n }\n\n if (isMultiple.value) {\n const cur = selectedValues.value.slice();\n const idx = cur.indexOf(v);\n if (idx >= 0) {\n cur.splice(idx, 1);\n emit('deselect', v, node);\n emitChange(cur, node, { selected: false });\n } else {\n if (maxCount != null && cur.length >= maxCount) return;\n cur.push(v);\n emit('select', v, node);\n emitChange(cur, node, { selected: true });\n }\n } else {\n if (selectedValues.value[0] === v) {\n // Already selected: just close\n closeMenu();\n return;\n }\n emit('select', v, node);\n emitChange([v], node, { selected: true });\n closeMenu();\n }\n}\n\nfunction handleCheck(node: BTreeSelectNode) {\n if (node.disabled || node.disableCheckbox) return;\n const v = getValue(node);\n const cur = new Set(selectedValues.value);\n const isCurrentlyChecked = cur.has(v);\n\n if (treeCheckStrictly) {\n if (isCurrentlyChecked) {\n cur.delete(v);\n emit('deselect', v, node);\n } else {\n if (maxCount != null && cur.size >= maxCount) return;\n cur.add(v);\n emit('select', v, node);\n }\n } else {\n // cascade\n if (isCurrentlyChecked) {\n cur.delete(v);\n function uncheck(nodes: BTreeSelectNode[]) {\n for (const n of nodes) {\n cur.delete(getValue(n));\n const ch = getChildren(n);\n if (ch?.length) uncheck(ch);\n }\n }\n const ch = getChildren(node);\n if (ch?.length) uncheck(ch);\n emit('deselect', v, node);\n } else {\n if (maxCount != null && cur.size >= maxCount) return;\n cur.add(v);\n function check(nodes: BTreeSelectNode[]) {\n for (const n of nodes) {\n if (!n.disabled && !n.disableCheckbox) cur.add(getValue(n));\n const ch = getChildren(n);\n if (ch?.length) check(ch);\n }\n }\n const ch = getChildren(node);\n if (ch?.length) check(ch);\n emit('select', v, node);\n }\n // Recompute parent state by removing parents that aren't fully selected\n function syncParents(nodes: BTreeSelectNode[]): { all: boolean; some: boolean } {\n let all = true;\n let some = false;\n for (const n of nodes) {\n const value = getValue(n);\n const children = getChildren(n);\n if (children?.length) {\n const sub = syncParents(children);\n if (sub.all) {\n cur.add(value);\n some = true;\n } else if (sub.some) {\n cur.delete(value);\n all = false;\n some = true;\n } else {\n cur.delete(value);\n if (!cur.has(value)) all = false;\n }\n } else {\n if (!cur.has(value)) all = false;\n else some = true;\n }\n }\n return { all, some };\n }\n syncParents(treeData);\n }\n\n emit('treeCheck', [...cur], { checked: !isCurrentlyChecked, node });\n emitChange([...cur], node, { checked: !isCurrentlyChecked });\n}\n\nfunction removeTag(value: BTreeSelectValue, e?: Event) {\n e?.stopPropagation();\n const node = nodeByValue.value.get(value);\n if (treeCheckable && node) {\n handleCheck(node);\n return;\n }\n const next = selectedValues.value.filter((v) => v !== value);\n if (node) emit('deselect', value, node);\n emitChange(next, node ?? ({ [valueField.value]: value } as BTreeSelectNode), { selected: false });\n}\n\nfunction handleClear(e: Event) {\n e.stopPropagation();\n const dummy = { [valueField.value]: '' } as BTreeSelectNode;\n if (isMultiple.value) {\n model.value = [];\n } else {\n model.value = undefined;\n }\n searchValue.value = '';\n emit('clear');\n emit('change', model.value, isMultiple.value ? [] : '', {\n triggerNode: dummy,\n triggerValue: undefined,\n });\n}\n\n// ─── Click outside ────────────────────────────────────────────────────────────\nfunction onSelectorClick() {\n if (disabled) return;\n if (isOpen.value) closeMenu();\n else openMenu();\n}\n\nfunction onSelectorBlur(e: FocusEvent) {\n const related = e.relatedTarget as HTMLElement | null;\n if (popoverRef.value?.contains(related)) return;\n if (selectorRef.value?.contains(related)) return;\n emit('blur', e);\n}\n\nfunction onSelectorFocus(e: FocusEvent) {\n emit('focus', e);\n}\n\nfunction onSearchInput(e: Event) {\n const t = e.target as HTMLInputElement;\n searchValue.value = t.value;\n emit('search', t.value);\n if (!isOpen.value) openMenu();\n // Focus first visible node when searching\n nextTick(() => {\n focusedKey.value = visibleFlatNodes.value[0]?.key ?? null;\n });\n}\n\nfunction onPopupScroll(e: Event) {\n emit('popupScroll', e);\n}\n\n// ─── Keyboard handling ────────────────────────────────────────────────────────\nfunction focusVisibleNode(key: BTreeSelectValue) {\n focusedKey.value = key;\n nextTick(() => {\n const safe = String(key).replace(/[\"\\\\]/g, '\\\\$&');\n const el = treeRef.value?.querySelector<HTMLElement>(\n `[data-node-key=\"${safe}\"]`,\n );\n el?.focus();\n el?.scrollIntoView?.({ block: 'nearest' });\n });\n}\n\nfunction onSelectorKeyDown(e: KeyboardEvent) {\n if (disabled) return;\n switch (e.key) {\n case 'Enter':\n case ' ':\n if (!searchEnabled.value || !isOpen.value) {\n e.preventDefault();\n if (isOpen.value) closeMenu();\n else openMenu();\n }\n break;\n case 'ArrowDown':\n e.preventDefault();\n if (!isOpen.value) openMenu();\n nextTick(() => {\n const first = visibleFlatNodes.value[0];\n if (first) focusVisibleNode(first.key);\n });\n break;\n case 'Escape':\n if (isOpen.value) {\n e.preventDefault();\n closeMenu();\n }\n break;\n case 'Backspace':\n if (isMultiple.value && !searchValue.value && selectedValues.value.length > 0) {\n const last = selectedValues.value[selectedValues.value.length - 1];\n removeTag(last);\n }\n break;\n case 'Tab':\n if (isOpen.value) closeMenu();\n break;\n }\n}\n\nfunction onTreeKeyDown(e: KeyboardEvent) {\n const visible = visibleFlatNodes.value;\n if (!visible.length) return;\n const idx = visible.findIndex((n) => n.key === focusedKey.value);\n const cur = visible[idx];\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault();\n const next = visible[idx + 1] ?? visible[0];\n focusVisibleNode(next.key);\n break;\n }\n case 'ArrowUp': {\n e.preventDefault();\n const prev = visible[idx - 1] ?? visible[visible.length - 1];\n focusVisibleNode(prev.key);\n break;\n }\n case 'ArrowRight': {\n e.preventDefault();\n if (!cur) break;\n if (hasChildren(cur.data) && !activeExpanded.value.has(cur.key)) toggleExpand(cur.data);\n break;\n }\n case 'ArrowLeft': {\n e.preventDefault();\n if (!cur) break;\n if (activeExpanded.value.has(cur.key)) toggleExpand(cur.data);\n break;\n }\n case 'Enter':\n case ' ': {\n e.preventDefault();\n if (cur) selectNode(cur.data);\n break;\n }\n case 'Escape':\n e.preventDefault();\n closeMenu();\n break;\n case 'Home': {\n e.preventDefault();\n if (visible[0]) focusVisibleNode(visible[0].key);\n break;\n }\n case 'End': {\n e.preventDefault();\n const last = visible[visible.length - 1];\n if (last) focusVisibleNode(last.key);\n break;\n }\n case 'Tab': {\n closeMenu();\n break;\n }\n }\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\nfunction hasChildren(node: BTreeSelectNode): boolean {\n const ch = getChildren(node);\n return !!ch?.length || (!!loadData && !node.isLeaf);\n}\n\nfunction isExpanded(key: BTreeSelectValue) {\n return activeExpanded.value.has(key);\n}\n\nfunction isLoading(key: BTreeSelectValue) {\n return loadingKeys.value.has(key);\n}\n\nfunction nodeIsSelectable(node: BTreeSelectNode) {\n if (treeCheckable) return node.checkable !== false && !node.disabled && !node.disableCheckbox;\n return node.selectable !== false && !node.disabled;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\ndefineExpose({\n focus: () => selectorRef.value?.focus(),\n blur: () => selectorRef.value?.blur(),\n});\n\n// ─── Computed UI helpers ──────────────────────────────────────────────────────\nconst showClear = computed(() => {\n if (!allowClear || disabled) return false;\n return selectedValues.value.length > 0;\n});\n\nconst sizeClass = computed(() => `b-tree-select--${size}`);\nconst variantClass = computed(() => `b-tree-select--${variant}`);\nconst statusClass = computed(() => (status ? `b-tree-select--${status}` : ''));\n\nconst expandTrigger = computed(() => treeExpandAction);\n\nfunction onNodeRowClick(node: BTreeSelectNode, event: MouseEvent) {\n if (expandTrigger.value === 'click' && hasChildren(node) && nodeIsSelectable(node)) {\n toggleExpand(node);\n }\n selectNode(node);\n void event;\n}\n\nfunction onNodeRowDblClick(node: BTreeSelectNode) {\n if (expandTrigger.value === 'doubleClick' && hasChildren(node)) {\n toggleExpand(node);\n }\n}\n</script>\n\n<template>\n <div\n class=\"b-tree-select b:relative b:inline-flex b:w-full\"\n :class=\"[sizeClass, variantClass, statusClass, { 'b-tree-select--disabled': disabled, 'b-tree-select--multiple': isMultiple, 'b-tree-select--open': isOpen }]\"\n >\n <!-- ─── Selector trigger ───────────────────────────────────────── -->\n <div\n ref=\"selectorRef\"\n v-bind=\"attrs\"\n class=\"b-tree-select__selector b:box-border b:flex b:w-full b:cursor-pointer b:items-center b:gap-1 b:transition-all b:outline-none\"\n :class=\"[\n {\n 'b:min-h-6 b:px-2 b:text-sm': size === BCommonSize.Small,\n 'b:min-h-8 b:px-3 b:text-sm': size === BCommonSize.Medium,\n 'b:min-h-10 b:px-3 b:text-base': size === BCommonSize.Large,\n },\n {\n 'b:rounded-lg b:border-1 b:border-[var(--b-tree-select-border-color)] b:bg-[var(--b-tree-select-bg)] b:hover:not-disabled:border-[var(--b-tree-select-hover-border-color)] b:focus:not-disabled:border-[var(--b-tree-select-active-border-color)] b:focus:not-disabled:shadow-[0_0_0_2px_var(--b-tree-select-active-outline-color)]':\n variant === BTreeSelectVariant.Outlined,\n 'b:rounded-lg b:border-1 b:border-transparent b:bg-[var(--b-tree-select-filled-bg)] b:focus:not-disabled:border-[var(--b-tree-select-active-border-color)] b:focus:not-disabled:bg-[var(--b-tree-select-bg)] b:focus:not-disabled:shadow-[0_0_0_2px_var(--b-tree-select-active-outline-color)]':\n variant === BTreeSelectVariant.Filled,\n 'b:rounded-lg b:border-1 b:border-transparent b:bg-transparent':\n variant === BTreeSelectVariant.Borderless,\n 'b:rounded-none b:border-0 b:border-b-1 b:border-[var(--b-tree-select-border-color)] b:bg-transparent':\n variant === BTreeSelectVariant.Underlined,\n },\n {\n 'b:border-red-500! b:hover:not-disabled:border-red-400! b:focus:not-disabled:border-red-500! b:focus:not-disabled:shadow-[0_0_0_2px_rgba(255,38,5,0.06)]!':\n status === BTreeSelectStatus.Error,\n 'b:border-yellow-500! b:hover:not-disabled:border-yellow-400! b:focus:not-disabled:border-yellow-500! b:focus:not-disabled:shadow-[0_0_0_2px_rgba(255,215,5,0.1)]!':\n status === BTreeSelectStatus.Warning,\n },\n {\n 'b:cursor-not-allowed b:opacity-40': disabled,\n },\n ]\"\n :tabindex=\"disabled ? -1 : 0\"\n role=\"combobox\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? treeId : undefined\"\n aria-haspopup=\"tree\"\n :aria-label=\"placeholder ?? 'Tree select'\"\n :aria-disabled=\"disabled || undefined\"\n @click=\"onSelectorClick\"\n @keydown=\"onSelectorKeyDown\"\n @focus=\"onSelectorFocus\"\n @blur=\"onSelectorBlur\"\n >\n <!-- ─── Multiple/checkable mode: tags ─── -->\n <template v-if=\"isMultiple\">\n <span\n v-for=\"tag in visibleTags\"\n :key=\"String(tag.value)\"\n class=\"b-tree-select__tag b:inline-flex b:max-w-full b:items-center b:gap-0.5 b:rounded b:border-1 b:border-[var(--b-tree-select-tag-border-color)] b:bg-[var(--b-tree-select-tag-bg)] b:leading-none\"\n :class=\"[\n {\n 'b:h-4 b:px-1 b:text-xs': size === BCommonSize.Small,\n 'b:h-6 b:px-1.5 b:text-xs': size === BCommonSize.Medium,\n 'b:h-8 b:px-2 b:text-sm': size === BCommonSize.Large,\n },\n ]\"\n >\n <slot\n name=\"tagRender\"\n :value=\"tag.value\"\n :label=\"tag.label\"\n :closable=\"!disabled\"\n :on-close=\"() => removeTag(tag.value)\"\n >\n <span class=\"b:truncate\">{{ tag.label }}</span>\n <button\n v-if=\"!disabled\"\n type=\"button\"\n class=\"b-tree-select__tag-close b:ml-0.5 b:flex b:h-3.5 b:w-3.5 b:cursor-pointer b:items-center b:justify-center b:rounded-full b:border-none b:bg-transparent b:text-[10px] b:text-zinc-400 b:hover:bg-zinc-200 b:hover:text-zinc-600\"\n :aria-label=\"`Remove ${tag.label}`\"\n tabindex=\"-1\"\n @click.stop=\"removeTag(tag.value)\"\n @mousedown.prevent\n >\n <svg aria-hidden=\"true\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\n <path d=\"M1 1l6 6M7 1L1 7\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n </button>\n </slot>\n </span>\n <span\n v-if=\"omittedTags.length > 0\"\n class=\"b-tree-select__tag b-tree-select__tag--count b:relative b:z-1 b:inline-flex b:shrink-0 b:items-center b:rounded b:bg-[var(--b-tree-select-multiple-count-bg)] b:px-1.5 b:text-xs b:leading-none b:text-[var(--b-tree-select-multiple-count-color)]\"\n :class=\"[\n {\n 'b:h-4': size === BCommonSize.Small,\n 'b:h-6': size === BCommonSize.Medium,\n 'b:h-8': size === BCommonSize.Large,\n },\n ]\"\n >\n {{ omittedPlaceholder }}\n </span>\n <input\n v-if=\"searchEnabled\"\n ref=\"searchInputRef\"\n class=\"b-tree-select__search b:min-w-4 b:flex-1 b:border-none b:bg-transparent b:text-sm b:outline-none b:placeholder:text-[var(--b-tree-select-placeholder-color)]\"\n :value=\"searchValue\"\n :placeholder=\"selectedValues.length === 0 ? placeholder : undefined\"\n :disabled=\"disabled\"\n aria-autocomplete=\"list\"\n :aria-label=\"placeholder ?? 'Search'\"\n autocomplete=\"off\"\n @input=\"onSearchInput\"\n />\n <span\n v-else-if=\"selectedValues.length === 0\"\n class=\"b-tree-select__placeholder b:flex-1 b:truncate b:text-[var(--b-tree-select-placeholder-color)]\"\n >\n {{ placeholder }}\n </span>\n </template>\n\n <!-- ─── Single mode ─── -->\n <template v-else>\n <span\n v-if=\"singleLabel && !searchValue\"\n class=\"b-tree-select__value b:flex-1 b:truncate b:text-[color:var(--b-tree-select-color)]\"\n >\n {{ singleLabel }}\n </span>\n <span\n v-else-if=\"!singleLabel && !searchValue\"\n class=\"b-tree-select__placeholder b:flex-1 b:truncate b:text-[var(--b-tree-select-placeholder-color)]\"\n >\n {{ placeholder }}\n </span>\n <input\n v-if=\"searchEnabled\"\n ref=\"searchInputRef\"\n class=\"b-tree-select__search b:absolute b:inset-0 b:w-full b:border-none b:bg-transparent b:px-3 b:text-sm b:outline-none b:placeholder:text-[var(--b-tree-select-placeholder-color)]\"\n :class=\"{ 'b:opacity-0': !isOpen }\"\n :value=\"searchValue\"\n :disabled=\"disabled\"\n autocomplete=\"off\"\n tabindex=\"-1\"\n aria-autocomplete=\"list\"\n :aria-label=\"placeholder ?? 'Search'\"\n @input=\"onSearchInput\"\n />\n </template>\n\n <!-- Clear button -->\n <button\n v-if=\"showClear\"\n type=\"button\"\n class=\"b-tree-select__clear b:z-1 b:flex b:h-4 b:w-4 b:shrink-0 b:cursor-pointer b:items-center b:justify-center b:rounded-full b:border-none b:bg-[var(--b-tree-select-bg)] b:text-xs b:text-zinc-400 b:hover:text-zinc-600\"\n aria-label=\"Clear selection\"\n tabindex=\"-1\"\n @click=\"handleClear\"\n @mousedown.prevent\n >\n <svg aria-hidden=\"true\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\n <path d=\"M1 1l6 6M7 1L1 7\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n </button>\n\n <!-- Suffix arrow -->\n <span\n class=\"b-tree-select__arrow b:ml-auto b:flex b:shrink-0 b:items-center b:text-zinc-400 b:transition-transform b:duration-200\"\n :class=\"{ 'b:rotate-180': isOpen }\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffixIcon\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path\n d=\"M2.5 4.5L6 8L9.5 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </slot>\n </span>\n </div>\n\n <!-- ─── Popup ─── -->\n <div\n :id=\"treeId\"\n ref=\"popoverRef\"\n class=\"b-tree-select__dropdown\"\n :class=\"{ 'b-tree-select__dropdown--match-width': popupMatchSelectWidth === true }\"\n :style=\"[\n typeof popupMatchSelectWidth === 'number'\n ? { width: `${popupMatchSelectWidth}px` }\n : undefined,\n { maxHeight: `${listHeight}px` },\n ]\"\n popover\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-label=\"placeholder ?? 'Tree options'\"\n @scroll=\"onPopupScroll\"\n @keydown=\"onTreeKeyDown\"\n >\n <div\n ref=\"treeRef\"\n class=\"b-tree-select__tree\"\n :class=\"{ 'b-tree-select__tree--show-line': treeLine }\"\n role=\"tree\"\n :aria-multiselectable=\"isMultiple || undefined\"\n >\n <template v-if=\"visibleFlatNodes.length > 0\">\n <div\n v-for=\"flat in visibleFlatNodes\"\n :key=\"String(flat.key)\"\n :data-node-key=\"String(flat.key)\"\n class=\"b-tree-select__node\"\n :class=\"{\n 'b-tree-select__node--selected': !treeCheckable && selectedSet.has(flat.value),\n 'b-tree-select__node--disabled': flat.data.disabled,\n 'b-tree-select__node--focused': focusedKey === flat.key,\n 'b-tree-select__node--expanded': isExpanded(flat.key),\n }\"\n role=\"treeitem\"\n :aria-expanded=\"hasChildren(flat.data) ? isExpanded(flat.key) : undefined\"\n :aria-selected=\"!treeCheckable && selectedSet.has(flat.value)\"\n :aria-checked=\"treeCheckable\n ? halfCheckedSet.has(flat.value)\n ? 'mixed'\n : selectedSet.has(flat.value)\n : undefined\"\n :aria-disabled=\"flat.data.disabled || undefined\"\n :aria-level=\"flat.depth + 1\"\n :tabindex=\"focusedKey === flat.key ? 0 : -1\"\n :style=\"{ '--b-tree-select-node-indent': `${flat.depth * 24}px` }\"\n @click.stop=\"onNodeRowClick(flat.data, $event)\"\n @dblclick.stop=\"onNodeRowDblClick(flat.data)\"\n >\n <!-- Indent -->\n <span class=\"b-tree-select__indent\" aria-hidden=\"true\" />\n\n <!-- Switcher -->\n <span\n v-if=\"hasChildren(flat.data)\"\n class=\"b-tree-select__switcher\"\n :class=\"{\n 'b-tree-select__switcher--expanded': isExpanded(flat.key),\n 'b-tree-select__switcher--loading': isLoading(flat.key),\n }\"\n aria-hidden=\"true\"\n @click.stop=\"toggleExpand(flat.data)\"\n >\n <slot\n v-if=\"!isLoading(flat.key)\"\n name=\"switcherIcon\"\n :node=\"flat.data\"\n :expanded=\"isExpanded(flat.key)\"\n >\n <svg\n class=\"b-tree-select__switcher-icon\"\n viewBox=\"0 0 8 8\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M2 1.5L6 4L2 6.5z\" />\n </svg>\n </slot>\n <svg\n v-if=\"isLoading(flat.key)\"\n class=\"b-tree-select__switcher-icon b-tree-select__switcher-icon--spin\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-dasharray=\"42\"\n stroke-dashoffset=\"14\"\n stroke-linecap=\"round\"\n />\n </svg>\n </span>\n <span v-else class=\"b-tree-select__switcher b-tree-select__switcher--leaf\" aria-hidden=\"true\" />\n\n <!-- Checkbox (treeCheckable mode) -->\n <span\n v-if=\"treeCheckable && flat.data.checkable !== false\"\n class=\"b-tree-select__checkbox\"\n :class=\"{\n 'b-tree-select__checkbox--checked': selectedSet.has(flat.value),\n 'b-tree-select__checkbox--indeterminate': halfCheckedSet.has(flat.value),\n 'b-tree-select__checkbox--disabled': flat.data.disabled || flat.data.disableCheckbox,\n }\"\n role=\"checkbox\"\n :aria-checked=\"halfCheckedSet.has(flat.value) ? 'mixed' : selectedSet.has(flat.value)\"\n :aria-disabled=\"flat.data.disabled || flat.data.disableCheckbox || undefined\"\n tabindex=\"-1\"\n @click.stop=\"handleCheck(flat.data)\"\n >\n <span class=\"b-tree-select__checkbox-inner\" aria-hidden=\"true\" />\n </span>\n\n <!-- Icon -->\n <span v-if=\"treeIcon || $slots.treeIcon\" class=\"b-tree-select__icon\" aria-hidden=\"true\">\n <slot name=\"treeIcon\" :node=\"flat.data\" />\n </span>\n\n <!-- Title -->\n <span class=\"b-tree-select__title\">\n <slot name=\"title\" :node=\"flat.data\">\n {{ getDisplayLabel(flat.data) }}\n </slot>\n </span>\n </div>\n </template>\n\n <!-- Empty -->\n <div v-else class=\"b-tree-select__empty\">\n <slot name=\"notFoundContent\">{{ notFoundContent }}</slot>\n </div>\n </div>\n </div>\n\n <!-- a11y live region: announces selection count -->\n <span class=\"b-tree-select__sr-only\" role=\"status\" aria-live=\"polite\">\n <template v-if=\"isMultiple\">{{ selectedValues.length }} selected</template>\n <template v-else-if=\"singleLabel\">{{ singleLabel }} selected</template>\n </span>\n </div>\n</template>\n\n<style scoped>\n/* ─── Design tokens ─────────────────────────────────────────────────────────── */\n.b-tree-select {\n /* AntD: indentSize */\n --b-tree-select-indent-size: 24px;\n /* AntD: nodeHoverBg */\n --b-tree-select-node-hover-bg: rgba(0, 0, 0, 0.04);\n /* AntD: nodeHoverColor */\n --b-tree-select-node-hover-color: rgba(0, 0, 0, 0.88);\n /* AntD: nodeSelectedBg */\n --b-tree-select-node-selected-bg: #e6f4ff;\n /* AntD: nodeSelectedColor */\n --b-tree-select-node-selected-color: rgba(0, 0, 0, 0.88);\n /* AntD: switcherSize */\n --b-tree-select-switcher-size: 16px;\n /* AntD: titleHeight */\n --b-tree-select-title-height: 24px;\n\n /* Selector tokens */\n --b-tree-select-bg: #ffffff;\n --b-tree-select-color: rgba(0, 0, 0, 0.88);\n --b-tree-select-placeholder-color: #606870;\n --b-tree-select-border-color: #d9d9d9;\n --b-tree-select-hover-border-color: #4096ff;\n --b-tree-select-active-border-color: #1677ff;\n --b-tree-select-active-outline-color: rgba(5, 145, 255, 0.1);\n --b-tree-select-filled-bg: rgba(0, 0, 0, 0.04);\n\n /* Tag tokens */\n --b-tree-select-tag-bg: rgba(0, 0, 0, 0.06);\n --b-tree-select-tag-border-color: transparent;\n --b-tree-select-multiple-count-bg: #f0f0f0;\n --b-tree-select-multiple-count-color: #1f1f1f;\n\n /* Checkbox tokens */\n --b-tree-select-checkbox-size: 16px;\n --b-tree-select-checkbox-border: #d9d9d9;\n --b-tree-select-checkbox-bg: #ffffff;\n --b-tree-select-checkbox-checked-bg: #1677ff;\n\n /* Popup tokens */\n --b-tree-select-popup-bg: #ffffff;\n --b-tree-select-popup-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.08),\n 0 3px 6px -4px rgba(0, 0, 0, 0.12),\n 0 9px 28px 8px rgba(0, 0, 0, 0.05);\n --b-tree-select-popup-border-radius: 8px;\n --b-tree-select-z-index-popup: 1050;\n --b-tree-select-line-color: #d9d9d9;\n\n /* Motion */\n --b-tree-select-transition-duration: 200ms;\n}\n\n/* ─── Dark mode ─────────────────────────────────────────────────────────────── */\n[data-prefers-color='dark'] .b-tree-select {\n --b-tree-select-node-hover-bg: rgba(255, 255, 255, 0.08);\n --b-tree-select-node-hover-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-node-selected-bg: #111a2c;\n --b-tree-select-node-selected-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-bg: #1f1f1f;\n --b-tree-select-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-placeholder-color: #9ca3af;\n --b-tree-select-border-color: #424242;\n --b-tree-select-hover-border-color: #4096ff;\n --b-tree-select-active-border-color: #1668dc;\n --b-tree-select-active-outline-color: rgba(22, 104, 220, 0.15);\n --b-tree-select-filled-bg: rgba(255, 255, 255, 0.08);\n --b-tree-select-tag-bg: rgba(255, 255, 255, 0.1);\n --b-tree-select-multiple-count-bg: #353535;\n --b-tree-select-multiple-count-color: #e0e0e0;\n --b-tree-select-checkbox-border: #424242;\n --b-tree-select-checkbox-bg: #1f1f1f;\n --b-tree-select-popup-bg: #1f1f1f;\n --b-tree-select-popup-shadow:\n 0 6px 16px 0 rgba(0, 0, 0, 0.24),\n 0 3px 6px -4px rgba(0, 0, 0, 0.36),\n 0 9px 28px 8px rgba(0, 0, 0, 0.2);\n --b-tree-select-line-color: #424242;\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-tree-select {\n --b-tree-select-node-hover-bg: rgba(255, 255, 255, 0.08);\n --b-tree-select-node-hover-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-node-selected-bg: #111a2c;\n --b-tree-select-node-selected-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-bg: #1f1f1f;\n --b-tree-select-color: rgba(255, 255, 255, 0.88);\n --b-tree-select-placeholder-color: #9ca3af;\n --b-tree-select-border-color: #424242;\n --b-tree-select-active-border-color: #1668dc;\n --b-tree-select-active-outline-color: rgba(22, 104, 220, 0.15);\n --b-tree-select-filled-bg: rgba(255, 255, 255, 0.08);\n --b-tree-select-tag-bg: rgba(255, 255, 255, 0.1);\n --b-tree-select-multiple-count-bg: #353535;\n --b-tree-select-multiple-count-color: #e0e0e0;\n --b-tree-select-checkbox-border: #424242;\n --b-tree-select-checkbox-bg: #1f1f1f;\n --b-tree-select-popup-bg: #1f1f1f;\n --b-tree-select-line-color: #424242;\n }\n}\n\n/* ─── Selector anchor ───────────────────────────────────────────────────────── */\n.b-tree-select__selector {\n anchor-name: v-bind('anchorName');\n}\n\n/* ─── Dropdown ──────────────────────────────────────────────────────────────── */\n.b-tree-select__dropdown {\n position: absolute;\n margin: 0;\n padding: 4px;\n border: none;\n background: var(--b-tree-select-popup-bg);\n border-radius: var(--b-tree-select-popup-border-radius);\n box-shadow: var(--b-tree-select-popup-shadow);\n overflow: auto;\n z-index: var(--b-tree-select-z-index-popup);\n\n position-anchor: v-bind('anchorName');\n position-try-fallbacks: --b-tree-select-top;\n inset: auto;\n top: anchor(bottom);\n left: anchor(left);\n margin-top: 4px;\n\n transition:\n display 0.2s,\n opacity 0.2s;\n transition-behavior: allow-discrete;\n opacity: 0;\n\n &:popover-open {\n opacity: 1;\n\n @starting-style {\n opacity: 0;\n }\n }\n}\n\n.b-tree-select__tree {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 4px 0;\n outline: none;\n}\n\n.b-tree-select__dropdown--match-width {\n width: anchor-size(width);\n}\n\n@position-try --b-tree-select-top {\n inset: auto;\n bottom: anchor(top);\n left: anchor(left);\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n.b-tree-select__node {\n position: relative;\n display: flex;\n align-items: center;\n gap: 4px;\n height: var(--b-tree-select-title-height);\n padding-inline-start: calc(8px + var(--b-tree-select-node-indent, 0px));\n padding-inline-end: 12px;\n border-radius: 6px;\n cursor: pointer;\n user-select: none;\n outline: none;\n color: inherit;\n transition:\n background-color var(--b-tree-select-transition-duration) ease,\n color var(--b-tree-select-transition-duration) ease;\n}\n\n.b-tree-select__node:hover {\n background-color: var(--b-tree-select-node-hover-bg);\n color: var(--b-tree-select-node-hover-color);\n}\n\n.b-tree-select__node--selected {\n background-color: var(--b-tree-select-node-selected-bg);\n color: var(--b-tree-select-node-selected-color);\n font-weight: 600;\n}\n\n.b-tree-select__node--selected:hover {\n background-color: var(--b-tree-select-node-selected-bg);\n}\n\n.b-tree-select__node--focused,\n.b-tree-select__node:focus-visible {\n background-color: var(--b-tree-select-node-hover-bg);\n outline: none;\n}\n\n.b-tree-select__node--disabled {\n cursor: not-allowed;\n opacity: 0.4;\n}\n\n.b-tree-select__node--disabled:hover {\n background-color: transparent;\n}\n\n/* Indent placeholder */\n.b-tree-select__indent {\n display: inline-block;\n flex-shrink: 0;\n}\n\n/* Switcher */\n.b-tree-select__switcher {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--b-tree-select-switcher-size);\n height: var(--b-tree-select-switcher-size);\n color: rgba(0, 0, 0, 0.45);\n}\n\n.b-tree-select__switcher--leaf {\n pointer-events: none;\n visibility: hidden;\n}\n\n.b-tree-select__switcher-icon {\n width: 10px;\n height: 10px;\n transition: transform var(--b-tree-select-transition-duration) ease;\n}\n\n.b-tree-select__switcher--expanded .b-tree-select__switcher-icon:not(.b-tree-select__switcher-icon--spin) {\n transform: rotate(90deg);\n}\n\n@keyframes b-tree-select-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n.b-tree-select__switcher-icon--spin {\n animation: b-tree-select-spin 700ms linear infinite;\n}\n\n/* Checkbox */\n.b-tree-select__checkbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n cursor: pointer;\n line-height: 1;\n}\n\n.b-tree-select__checkbox-inner {\n display: inline-block;\n width: var(--b-tree-select-checkbox-size);\n height: var(--b-tree-select-checkbox-size);\n border: 1.5px solid var(--b-tree-select-checkbox-border);\n border-radius: 3px;\n background-color: var(--b-tree-select-checkbox-bg);\n position: relative;\n transition:\n border-color var(--b-tree-select-transition-duration) ease,\n background-color var(--b-tree-select-transition-duration) ease;\n}\n\n.b-tree-select__checkbox--checked .b-tree-select__checkbox-inner {\n border-color: var(--b-tree-select-checkbox-checked-bg);\n background-color: var(--b-tree-select-checkbox-checked-bg);\n}\n\n.b-tree-select__checkbox--checked .b-tree-select__checkbox-inner::after {\n content: '';\n position: absolute;\n inset-inline-start: 4px;\n top: 1px;\n width: 5px;\n height: 8px;\n border: 2px solid #fff;\n border-top: none;\n border-inline-start: none;\n transform: rotate(45deg);\n}\n\n.b-tree-select__checkbox--indeterminate .b-tree-select__checkbox-inner {\n border-color: var(--b-tree-select-checkbox-checked-bg);\n background-color: var(--b-tree-select-checkbox-checked-bg);\n}\n\n.b-tree-select__checkbox--indeterminate .b-tree-select__checkbox-inner::after {\n content: '';\n position: absolute;\n inset-inline-start: 2px;\n top: 50%;\n width: calc(100% - 4px);\n height: 2px;\n background-color: #fff;\n transform: translateY(-50%);\n}\n\n.b-tree-select__checkbox--disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n\n/* Icon */\n.b-tree-select__icon {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n}\n\n/* Title */\n.b-tree-select__title {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Show line */\n.b-tree-select__tree--show-line .b-tree-select__node:not(:last-child)::before {\n content: '';\n position: absolute;\n inset-inline-start: calc(var(--b-tree-select-node-indent, 0px) + var(--b-tree-select-switcher-size) / 2);\n top: var(--b-tree-select-title-height);\n width: 1px;\n height: var(--b-tree-select-title-height);\n background-color: var(--b-tree-select-line-color);\n pointer-events: none;\n}\n\n/* Empty content */\n.b-tree-select__empty {\n padding: 16px;\n text-align: center;\n color: var(--b-tree-select-placeholder-color);\n font-size: 14px;\n}\n\n/* SR only */\n.b-tree-select__sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Reduced motion */\n@media (prefers-reduced-motion: reduce) {\n .b-tree-select,\n .b-tree-select__dropdown,\n .b-tree-select__node,\n .b-tree-select__switcher-icon,\n .b-tree-select__arrow {\n transition-duration: 0ms;\n }\n\n .b-tree-select__switcher-icon--spin {\n animation: none;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"design-system258.js","names":[],"sources":["../src/components/BTimeline/BTimeline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide } from 'vue';\n\nimport type {\n BTimelineItem,\n BTimelineItemColor,\n BTimelineItemPlacement,\n BTimelineMode,\n BTimelineOrientation,\n BTimelineVariant,\n} from './types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n mode = 'start',\n variant = 'filled',\n orientation = 'vertical',\n pending = false,\n pendingDot,\n reverse = false,\n items,\n} = defineProps<{\n /**\n * Controls which side labels appear on.\n * - `'start'` - all content on the right of the line (default)\n * - `'end'` - all content on the left of the line\n * - `'alternate'` - content alternates left/right\n * @default 'start'\n */\n mode?: BTimelineMode;\n /**\n * Dot style.\n * - `'filled'` - solid filled circle (default)\n * - `'outlined'` - hollow ring with colored border\n * @default 'filled'\n */\n variant?: BTimelineVariant;\n /**\n * Layout direction.\n * - `'vertical'` - items stacked top-to-bottom (default)\n * - `'horizontal'` - items laid out left-to-right\n * @default 'vertical'\n */\n orientation?: BTimelineOrientation;\n /**\n * Whether to show a pending (ghost) item at the bottom.\n * Pass `true` for the default spinner, or a string for custom content.\n * @default false\n */\n pending?: boolean | string;\n /**\n * Custom dot for the pending item. Overridden by the `#pendingDot` slot.\n */\n pendingDot?: string;\n /**\n * Whether to reverse the order of items (newest first).\n * @default false\n */\n reverse?: boolean;\n /**\n * Data-driven items. When provided, slot-based BTimelineItem children are\n * ignored. Use this for simple, data-only timelines.\n */\n items?: BTimelineItem[];\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /**\n * Default slot: place `<BTimelineItem>` children here.\n * Ignored when `items` prop is provided.\n */\n default?(): unknown;\n /** Custom dot for the pending ghost item. */\n pendingDot?(): unknown;\n}>();\n\n// Provide mode to slot-based BTimelineItem children\nprovide('b-timeline-mode', mode);\nprovide('b-timeline-variant', variant);\n\n// ─────────────────────────────────────────────\n// Pending item helpers\n// ─────────────────────────────────────────────\nconst hasPending = computed(() => !!pending);\nconst pendingContent = computed(() => (pending !== true && pending ? pending : ''));\n\n// ─────────────────────────────────────────────\n// Reversed items (data-driven)\n// ─────────────────────────────────────────────\nconst orderedItems = computed<BTimelineItem[]>(() => {\n if (!items) return [];\n return reverse ? [...items].reverse() : items;\n});\n\n// ─────────────────────────────────────────────\n// CSS-var dot color helper\n// ─────────────────────────────────────────────\nconst PRESET_COLORS: BTimelineItemColor[] = ['blue', 'red', 'green', 'gray'];\n\nfunction isPresetColor(color?: BTimelineItemColor): boolean {\n return !color || PRESET_COLORS.includes(color as string);\n}\n\nfunction dotColorStyle(color?: BTimelineItemColor): Record<string, string> | undefined {\n if (!color || isPresetColor(color)) return undefined;\n return { '--b-timeline-item-dot-color': color };\n}\n\nfunction dotColorClass(color?: BTimelineItemColor): string {\n const c = color ?? 'blue';\n return isPresetColor(c) ? `b-timeline-item--${c}` : 'b-timeline-item--custom';\n}\n\n// ─────────────────────────────────────────────\n// Root classes\n// ─────────────────────────────────────────────\nconst rootClasses = computed(() => [\n 'b-timeline',\n `b-timeline--${mode}`,\n `b-timeline--${variant}`,\n `b-timeline--${orientation}`,\n {\n 'b-timeline--pending': hasPending.value,\n 'b-timeline--reverse': reverse,\n },\n]);\n\n// ─────────────────────────────────────────────\n// Item position helper\n// ─────────────────────────────────────────────\nfunction itemPositionClass(index: number, placement?: BTimelineItemPlacement): string {\n // Per-item placement overrides the global mode\n if (placement) {\n return placement === 'end' ? 'b-timeline-item--right' : 'b-timeline-item--left';\n }\n if (mode === 'alternate') {\n return index % 2 === 0 ? 'b-timeline-item--left' : 'b-timeline-item--right';\n }\n return mode === 'end' ? 'b-timeline-item--right' : 'b-timeline-item--left';\n}\n</script>\n\n<template>\n <ol :class=\"rootClasses\" aria-label=\"Timeline\">\n <!-- ── Data-driven items ── -->\n <template v-if=\"items && items.length\">\n <li\n v-for=\"(item, i) in orderedItems\"\n :key=\"i\"\n class=\"b-timeline-item\"\n :class=\"[\n dotColorClass(item.color),\n itemPositionClass(i, item.placement),\n { 'b-timeline-item--pending': item.loading },\n item.className,\n ]\"\n :style=\"[\n dotColorStyle(item.color),\n typeof item.style === 'string' ? item.style : item.style,\n ]\"\n >\n <!-- Label / title (opposing side) - always rendered as structural spacer; CSS hides in start mode -->\n <span class=\"b-timeline-item__label\">{{ item.title ?? '' }}</span>\n\n <!-- Line + dot -->\n <div class=\"b-timeline-item__tail\" aria-hidden=\"true\" />\n <div class=\"b-timeline-item__dot-wrapper\" aria-hidden=\"true\">\n <template v-if=\"item.icon\">\n <span class=\"b-timeline-item__dot--custom\" :data-icon=\"item.icon\" aria-hidden=\"true\" />\n </template>\n <template v-else-if=\"item.loading\">\n <span class=\"b-timeline-item__dot--pending-spinner\" />\n </template>\n <template v-else>\n <span class=\"b-timeline-item__dot\" />\n </template>\n </div>\n\n <!-- Content -->\n <div class=\"b-timeline-item__content\">{{ item.content }}</div>\n </li>\n </template>\n\n <!-- ── Slot-based items (default slot children) ── -->\n <template v-else>\n <slot />\n </template>\n\n <!-- ── Pending ghost item ── -->\n <li\n v-if=\"hasPending\"\n class=\"b-timeline-item b-timeline-item--pending\"\n :class=\"[itemPositionClass(items ? orderedItems.length : 0)]\"\n aria-label=\"Pending\"\n >\n <!-- Label spacer (structural; hidden in start mode via CSS) -->\n <span class=\"b-timeline-item__label\" />\n <div class=\"b-timeline-item__tail\" aria-hidden=\"true\" />\n <div class=\"b-timeline-item__dot-wrapper\" aria-hidden=\"true\">\n <slot name=\"pendingDot\">\n <span\n v-if=\"pendingDot\"\n class=\"b-timeline-item__dot--custom\"\n :data-icon=\"pendingDot\"\n aria-hidden=\"true\"\n />\n <span v-else class=\"b-timeline-item__dot--pending-spinner\" aria-hidden=\"true\" />\n </slot>\n </div>\n <div class=\"b-timeline-item__content\">{{ pendingContent }}</div>\n </li>\n </ol>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BTimeline - CSS custom properties (scoped to root)\n ───────────────────────────────────────────── */\n.b-timeline {\n /* ── Structural ── */\n --b-timeline-line-width: 2px;\n --b-timeline-line-color: oklch(90% 0.005 260);\n --b-timeline-item-padding-bottom: 20px;\n\n /* ── Dot ── */\n --b-timeline-dot-size: 10px;\n --b-timeline-dot-offset: 0px; /* fine-tune vertical alignment */\n --b-timeline-dot-border-width: 2px;\n --b-timeline-custom-dot-font-size: 20px; /* emoji / text custom dots */\n\n /* ── Blue (default) ── */\n --b-timeline-color-blue: oklch(54.6% 0.245 262.881);\n /* ── Green ── */\n --b-timeline-color-green: oklch(52% 0.17 145);\n /* ── Red ── */\n --b-timeline-color-red: oklch(50% 0.2 20);\n /* ── Gray ── */\n --b-timeline-color-gray: oklch(68% 0.01 260);\n\n /* ── Content text ── */\n --b-timeline-content-color: oklch(32% 0.02 260);\n --b-timeline-content-font-size: 14px;\n\n /* ── Label text ── */\n --b-timeline-label-color: oklch(52% 0.01 260);\n --b-timeline-label-font-size: 14px;\n\n /* ── Pending ── */\n --b-timeline-pending-line-style: dashed;\n --b-timeline-pending-dot-color: oklch(70% 0.01 260);\n\n /* ── Spinner ── */\n --b-timeline-spinner-size: 14px;\n --b-timeline-spinner-border-color: oklch(54.6% 0.245 262.881 / 20%);\n --b-timeline-spinner-accent-color: oklch(54.6% 0.245 262.881);\n --b-timeline-spinner-duration: 700ms;\n\n /* ── Transition ── */\n --b-timeline-transition-duration: 200ms;\n\n /* ── Layout ── */\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n list-style: none;\n font-size: var(--b-timeline-content-font-size);\n line-height: 1.5;\n color: var(--b-timeline-content-color);\n}\n\n/* ─────────────────────────────────────────────\n Item\n ───────────────────────────────────────────── */\n.b-timeline-item {\n position: relative;\n display: flex;\n align-items: flex-start;\n padding-bottom: var(--b-timeline-item-padding-bottom);\n margin: 0;\n list-style: none;\n}\n\n/* last item - hide tail, collapse bottom padding */\n.b-timeline-item:last-child {\n padding-bottom: 0;\n}\n\n.b-timeline-item:last-child .b-timeline-item__tail {\n display: none;\n}\n\n/* ── Tail (vertical line) ── */\n.b-timeline-item__tail {\n position: absolute;\n top: calc(var(--b-timeline-dot-size) + 4px);\n left: calc(\n (var(--b-timeline-dot-size) / 2) - (var(--b-timeline-line-width) / 2)\n ); /* overridden per-mode */\n height: calc(100% - var(--b-timeline-dot-size) - 4px);\n width: var(--b-timeline-line-width);\n background: var(--b-timeline-line-color);\n transition: background var(--b-timeline-transition-duration);\n}\n\n/* ── Dot wrapper ── */\n.b-timeline-item__dot-wrapper {\n position: relative;\n flex-shrink: 0;\n width: var(--b-timeline-dot-size);\n height: var(--b-timeline-dot-size);\n margin-top: var(--b-timeline-dot-offset);\n z-index: 1;\n overflow: visible;\n}\n\n/* ── Standard dot ── */\n.b-timeline-item__dot {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background: var(--b-timeline-item-current-color, var(--b-timeline-color-blue));\n box-sizing: border-box;\n}\n\n/* ── Custom dot (icon / text) ── */\n.b-timeline-item__dot--custom {\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: var(--b-timeline-custom-dot-font-size);\n line-height: 1;\n width: var(--b-timeline-custom-dot-font-size);\n height: var(--b-timeline-custom-dot-font-size);\n /* shift left/up so the icon stays centred over the dot position */\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: var(--b-timeline-item-current-color, var(--b-timeline-color-blue));\n}\n\n/* Symbol rendered via ::before so no text node exists - avoids axe non-text-char rule */\n.b-timeline-item__dot--custom::before {\n content: attr(data-icon);\n}\n\n/* ─────────────────────────────────────────────\n Preset colors - set --b-timeline-item-current-color\n ───────────────────────────────────────────── */\n.b-timeline-item--blue {\n --b-timeline-item-current-color: var(--b-timeline-color-blue);\n}\n\n.b-timeline-item--green {\n --b-timeline-item-current-color: var(--b-timeline-color-green);\n}\n\n.b-timeline-item--red {\n --b-timeline-item-current-color: var(--b-timeline-color-red);\n}\n\n.b-timeline-item--gray {\n --b-timeline-item-current-color: var(--b-timeline-color-gray);\n}\n\n/* Custom (non-preset) color: provided via inline var */\n.b-timeline-item--custom {\n --b-timeline-item-current-color: var(--b-timeline-item-dot-color);\n}\n\n/* ─────────────────────────────────────────────\n Content & Label\n ───────────────────────────────────────────── */\n.b-timeline-item__content {\n flex: 1;\n padding-left: 12px;\n color: var(--b-timeline-content-color);\n font-size: var(--b-timeline-content-font-size);\n word-break: break-word;\n}\n\n.b-timeline-item__label {\n display: none; /* hidden in start mode; shown in alternate/end */\n color: var(--b-timeline-label-color);\n font-size: var(--b-timeline-label-font-size);\n text-align: right;\n flex-shrink: 0;\n}\n\n/* ─────────────────────────────────────────────\n Mode: start (default) - content right of line\n Each item: [dot] [content]\n ───────────────────────────────────────────── */\n.b-timeline--start .b-timeline-item {\n flex-direction: row;\n}\n\n.b-timeline--start .b-timeline-item__tail {\n left: calc((var(--b-timeline-dot-size) / 2) - (var(--b-timeline-line-width) / 2));\n}\n\n.b-timeline--start .b-timeline-item__label {\n display: none;\n}\n\n/* ─────────────────────────────────────────────\n Mode: end - content left of line\n Each item: [content] [dot]\n ───────────────────────────────────────────── */\n.b-timeline--end .b-timeline-item {\n flex-direction: row-reverse;\n}\n\n.b-timeline--end .b-timeline-item__content {\n padding-left: 0;\n padding-right: 12px;\n text-align: right;\n}\n\n.b-timeline--end .b-timeline-item__tail {\n right: calc((var(--b-timeline-dot-size) / 2) - (var(--b-timeline-line-width) / 2));\n left: auto;\n}\n\n.b-timeline--end .b-timeline-item__label {\n display: none;\n}\n\n/* ─────────────────────────────────────────────\n Mode: alternate\n Each row is always: [left-half][dot][right-half]\n Left items (even): left-half = label (right-aligned)\n right-half = content (left-aligned)\n Right items (odd): left-half = content (right-aligned)\n right-half = label (left-aligned)\n We use CSS `order` to swap - never flex-direction:row-reverse,\n which would flip the padding direction and break the gap.\n ───────────────────────────────────────────── */\n\n/* Label: always rendered as a structural spacer; hidden in start mode */\n.b-timeline--alternate .b-timeline-item__label {\n display: block;\n /* Each half = 50% of the row minus half the dot width.\n box-sizing:border-box means padding is included in this width,\n so the dot centre lands exactly at 50% of the row. */\n flex: 0 0 calc(50% - var(--b-timeline-dot-size) / 2);\n box-sizing: border-box;\n font-size: var(--b-timeline-label-font-size);\n color: var(--b-timeline-label-color);\n word-break: break-word;\n}\n\n/* Content: same symmetric half-width */\n.b-timeline--alternate .b-timeline-item__content {\n flex: 0 0 calc(50% - var(--b-timeline-dot-size) / 2);\n box-sizing: border-box;\n}\n\n/* Tail: always at exactly 50% of the row, regardless of which items have labels */\n.b-timeline--alternate .b-timeline-item__tail {\n left: calc(50% - var(--b-timeline-line-width) / 2);\n transform: none;\n}\n\n/* ── Left items (even): label LEFT → dot → content RIGHT ── */\n/* DOM order: label(1) tail(abs) dot(2) content(3) - already correct, no reordering needed */\n.b-timeline--alternate .b-timeline-item--left .b-timeline-item__label {\n order: 1;\n text-align: right;\n padding-right: 12px;\n padding-left: 0;\n}\n\n.b-timeline--alternate .b-timeline-item--left .b-timeline-item__dot-wrapper {\n order: 2;\n}\n\n.b-timeline--alternate .b-timeline-item--left .b-timeline-item__content {\n order: 3;\n text-align: left;\n padding-left: 12px;\n padding-right: 0;\n}\n\n/* ── Right items (odd): content LEFT → dot → label RIGHT ── */\n/* Use `order` to pull content before dot, push label after dot */\n.b-timeline--alternate .b-timeline-item--right .b-timeline-item__content {\n order: 1;\n text-align: right;\n padding-right: 12px;\n padding-left: 0;\n}\n\n.b-timeline--alternate .b-timeline-item--right .b-timeline-item__dot-wrapper {\n order: 2;\n}\n\n.b-timeline--alternate .b-timeline-item--right .b-timeline-item__label {\n order: 3;\n text-align: left;\n padding-left: 12px;\n padding-right: 0;\n}\n\n/* ─────────────────────────────────────────────\n Variant: outlined - hollow ring dot\n ───────────────────────────────────────────── */\n.b-timeline--outlined .b-timeline-item__dot {\n background: transparent;\n border: var(--b-timeline-dot-border-width) solid\n var(--b-timeline-item-current-color, var(--b-timeline-color-blue));\n}\n\n/* ─────────────────────────────────────────────\n Orientation: horizontal\n Items laid out left-to-right; tail becomes a\n horizontal bar running to the right.\n ───────────────────────────────────────────── */\n.b-timeline--horizontal {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n overflow-x: auto;\n}\n\n.b-timeline--horizontal.b-timeline--start .b-timeline-item,\n.b-timeline--horizontal.b-timeline--end .b-timeline-item {\n flex-direction: column;\n align-items: center;\n flex: 1;\n padding-bottom: 0;\n padding-right: 0;\n min-width: 80px;\n}\n\n/* Horizontal tail: runs right from the dot */\n.b-timeline--horizontal .b-timeline-item__tail {\n top: calc(var(--b-timeline-dot-size) / 2 - var(--b-timeline-line-width) / 2);\n left: calc(var(--b-timeline-dot-size) + 4px);\n width: calc(100% - var(--b-timeline-dot-size) - 4px);\n height: var(--b-timeline-line-width);\n right: auto;\n bottom: auto;\n}\n\n/* In horizontal mode the last item still hides its tail */\n.b-timeline--horizontal .b-timeline-item:last-child .b-timeline-item__tail {\n display: none;\n}\n\n/* Dot: centred horizontally above content */\n.b-timeline--horizontal .b-timeline-item__dot-wrapper {\n margin-top: 0;\n flex-shrink: 0;\n}\n\n/* Content sits below the dot row */\n.b-timeline--horizontal .b-timeline-item__content {\n padding-left: 0;\n padding-top: 8px;\n text-align: center;\n width: 100%;\n}\n\n/* Label sits above the dot row (for start mode) */\n.b-timeline--horizontal.b-timeline--start .b-timeline-item__label {\n display: block;\n text-align: center;\n padding-bottom: 8px;\n order: 1;\n}\n\n.b-timeline--horizontal.b-timeline--start .b-timeline-item__dot-wrapper {\n order: 2;\n}\n\n.b-timeline--horizontal.b-timeline--start .b-timeline-item__content {\n order: 3;\n}\n\n/* For end mode, label goes below content */\n.b-timeline--horizontal.b-timeline--end .b-timeline-item__content {\n order: 1;\n padding-top: 8px;\n padding-right: 0;\n text-align: center;\n}\n\n.b-timeline--horizontal.b-timeline--end .b-timeline-item__dot-wrapper {\n order: 2;\n}\n\n.b-timeline--horizontal.b-timeline--end .b-timeline-item__label {\n display: block;\n text-align: center;\n padding-top: 8px;\n order: 3;\n}\n\n/* ─────────────────────────────────────────────\n Pending item\n ───────────────────────────────────────────── */\n.b-timeline-item--pending .b-timeline-item__tail {\n border-left: var(--b-timeline-line-width) var(--b-timeline-pending-line-style)\n var(--b-timeline-line-color);\n background: transparent;\n}\n\n.b-timeline--start .b-timeline-item--pending .b-timeline-item__tail {\n /* override the absolute left, matches .b-timeline--start logic */\n left: calc((var(--b-timeline-dot-size) / 2) - (var(--b-timeline-line-width) / 2));\n}\n\n/* Horizontal pending tail */\n.b-timeline--horizontal .b-timeline-item--pending .b-timeline-item__tail {\n border-left: none;\n border-top: var(--b-timeline-line-width) var(--b-timeline-pending-line-style)\n var(--b-timeline-line-color);\n background: transparent;\n height: 0;\n}\n\n/* ── Default pending spinner ── */\n.b-timeline-item__dot--pending-spinner {\n display: block;\n width: var(--b-timeline-spinner-size);\n height: var(--b-timeline-spinner-size);\n margin-left: calc((var(--b-timeline-dot-size) - var(--b-timeline-spinner-size)) / 2);\n border-radius: 50%;\n border: var(--b-timeline-dot-border-width) solid var(--b-timeline-spinner-border-color);\n border-top-color: var(--b-timeline-spinner-accent-color);\n animation: b-timeline-spin var(--b-timeline-spinner-duration) linear infinite;\n}\n\n@keyframes b-timeline-spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n/* ─────────────────────────────────────────────\n Dark mode\n ───────────────────────────────────────────── */\n[data-prefers-color='dark'] .b-timeline {\n --b-timeline-line-color: oklch(32% 0.012 260);\n --b-timeline-content-color: oklch(82% 0.01 260);\n --b-timeline-label-color: oklch(60% 0.01 260);\n --b-timeline-color-gray: oklch(50% 0.01 260);\n --b-timeline-spinner-border-color: oklch(54.6% 0.245 262.881 / 15%);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-timeline {\n --b-timeline-line-color: oklch(32% 0.012 260);\n --b-timeline-content-color: oklch(82% 0.01 260);\n --b-timeline-label-color: oklch(60% 0.01 260);\n --b-timeline-color-gray: oklch(50% 0.01 260);\n --b-timeline-spinner-border-color: oklch(54.6% 0.245 262.881 / 15%);\n }\n}\n\n/* ─────────────────────────────────────────────\n Reduced motion\n ───────────────────────────────────────────── */\n@media (prefers-reduced-motion: reduce) {\n .b-timeline {\n --b-timeline-transition-duration: 0ms;\n --b-timeline-spinner-duration: 0ms;\n }\n\n .b-timeline-item__dot--pending-spinner {\n animation: none;\n border-top-color: var(--b-timeline-spinner-border-color);\n opacity: 0.6;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFA,EADA,EAAQ,mBAAmB,EAAA,KAAK,EAChC,EAAQ,sBAAsB,EAAA,QAAQ;EAKtC,IAAM,IAAa,QAAe,CAAC,CAAC,EAAA,QAAQ,EACtC,IAAiB,QAAgB,EAAA,YAAY,MAAQ,EAAA,UAAU,EAAA,UAAU,GAAI,EAK7E,IAAe,QACd,EAAA,QACE,EAAA,UAAU,CAAC,GAAG,EAAA,MAAM,CAAC,SAAS,GAAG,EAAA,QADrB,EAAE,CAErB,EAKI,IAAsC;GAAC;GAAQ;GAAO;GAAS;GAAO;EAE5E,SAAS,EAAc,GAAqC;AAC1D,UAAO,CAAC,KAAS,EAAc,SAAS,EAAgB;;EAG1D,SAAS,EAAc,GAAgE;AACjF,UAAC,KAAS,EAAc,EAAM,EAClC,QAAO,EAAE,+BAA+B,GAAO;;EAGjD,SAAS,EAAc,GAAoC;GACzD,IAAM,IAAI,KAAS;AACnB,UAAO,EAAc,EAAE,GAAG,oBAAoB,MAAM;;EAMtD,IAAM,IAAc,QAAe;GACjC;GACA,eAAe,EAAA;GACf,eAAe,EAAA;GACf,eAAe,EAAA;GACf;IACE,uBAAuB,EAAW;IAClC,uBAAuB,EAAA;IACxB;GACF,CAAC;EAKF,SAAS,EAAkB,GAAe,GAA4C;AAQpF,UANI,IACK,MAAc,QAAQ,2BAA2B,0BAEtD,EAAA,SAAS,cACJ,IAAQ,KAAM,IAAI,0BAA0B,2BAE9C,EAAA,SAAS,QAAQ,2BAA2B;;yBAKnD,EAoEK,MAAA;GApEA,OAAK,EAAE,EAAA,MAAW;GAAE,cAAW;MAElB,EAAA,SAAS,EAAA,MAAM,UAAA,EAAA,GAAA,EAC7B,EAkCK,GAAA,EAAA,KAAA,GAAA,EAAA,EAjCiB,EAAA,QAAZ,GAAM,YADhB,EAkCK,MAAA;GAhCF,KAAK;GACN,OAAK,EAAA,CAAC,mBAAiB;IACH,EAAc,EAAK,MAAK;IAAa,EAAkB,GAAG,EAAK,UAAS;kCAA2C,EAAK,SAAO;IAAc,EAAK;;GAMrK,OAAK,EAAA,CAAc,EAAc,EAAK,MAAK,GAAoB,EAAK,OAAqB,EAAK,OAAa,CAAA;;GAM5G,EAAkE,QAAlE,GAAkE,EAA1B,EAAK,SAAK,GAAA,EAAA,EAAA;YAGlD,EAAwD,OAAA;IAAnD,OAAM;IAAwB,eAAY;;GAC/C,EAUM,OAVN,GAUM,CATY,EAAK,QAAA,GAAA,EACnB,EAAuF,QAAA;;IAAjF,OAAM;IAAgC,aAAW,EAAK;IAAM,eAAY;qBAE3D,EAAK,WAAA,GAAA,EACxB,EAAsD,QAAtD,EAAsD,KAAA,GAAA,EAGtD,EAAqC,QAArC,EAAqC,EAAA,CAAA;GAKzC,EAA8D,OAA9D,GAA8D,EAArB,EAAK,QAAO,EAAA,EAAA;mBAMvD,EAAQ,EAAA,QAAA,WAAA,EAAA,KAAA,GAAA,CAAA,EAKF,EAAA,SAAA,GAAA,EADR,EAqBK,MAAA;;GAnBH,OAAK,EAAA,CAAC,4CAA0C,CACvC,EAAkB,EAAA,QAAQ,EAAA,MAAa,SAAM,EAAA,CAAA,CAAA,CAAA;GACtD,cAAW;;YAGX,EAAuC,QAAA,EAAjC,OAAM,0BAAwB,EAAA,MAAA,GAAA;YACpC,EAAwD,OAAA;IAAnD,OAAM;IAAwB,eAAY;;GAC/C,EAUM,OAVN,GAUM,CATJ,EAQO,EAAA,QAAA,cAAA,EAAA,QAAA,CANG,EAAA,cAAA,GAAA,EADR,EAKE,QAAA;;IAHA,OAAM;IACL,aAAW,EAAA;IACZ,eAAY;2BAEd,EAAgF,QAAhF,EAAgF,EAAA,CAAA,CAAA,CAAA;GAGpF,EAAgE,OAAhE,GAAgE,EAAvB,EAAA,MAAc,EAAA,EAAA"}