@7pmlabs/design-system 1.0.9 → 1.0.11

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 (438) hide show
  1. package/README.md +57 -6
  2. package/dist/design-system.css +1 -1
  3. package/dist/design-system.js +74 -60
  4. package/dist/design-system100.js +4 -5
  5. package/dist/design-system100.js.map +1 -1
  6. package/dist/design-system101.js +53 -506
  7. package/dist/design-system101.js.map +1 -1
  8. package/dist/{design-system93.js → design-system102.js} +1 -1
  9. package/dist/design-system102.js.map +1 -0
  10. package/dist/design-system103.js +13 -5
  11. package/dist/design-system103.js.map +1 -1
  12. package/dist/design-system104.js +109 -7
  13. package/dist/design-system104.js.map +1 -1
  14. package/dist/design-system106.js +9 -0
  15. package/dist/design-system106.js.map +1 -0
  16. package/dist/design-system107.js +206 -6
  17. package/dist/design-system107.js.map +1 -1
  18. package/dist/design-system109.js +9 -0
  19. package/dist/design-system109.js.map +1 -0
  20. package/dist/design-system110.js +507 -6
  21. package/dist/design-system110.js.map +1 -1
  22. package/dist/design-system112.js +8 -0
  23. package/dist/design-system112.js.map +1 -0
  24. package/dist/design-system113.js +7 -5
  25. package/dist/design-system113.js.map +1 -1
  26. package/dist/design-system114.js +209 -9
  27. package/dist/design-system114.js.map +1 -1
  28. package/dist/design-system116.js +9 -0
  29. package/dist/design-system116.js.map +1 -0
  30. package/dist/design-system117.js +224 -6
  31. package/dist/design-system117.js.map +1 -1
  32. package/dist/design-system119.js +9 -0
  33. package/dist/design-system119.js.map +1 -0
  34. package/dist/design-system12.js.map +1 -1
  35. package/dist/design-system120.js +163 -5
  36. package/dist/design-system120.js.map +1 -1
  37. package/dist/design-system122.js +5 -90
  38. package/dist/design-system122.js.map +1 -1
  39. package/dist/design-system123.js +12 -0
  40. package/dist/design-system123.js.map +1 -0
  41. package/dist/design-system124.js +274 -5
  42. package/dist/design-system124.js.map +1 -1
  43. package/dist/design-system126.js +9 -0
  44. package/dist/design-system126.js.map +1 -0
  45. package/dist/design-system127.js +16 -5
  46. package/dist/design-system127.js.map +1 -1
  47. package/dist/design-system129.js +8 -0
  48. package/dist/design-system129.js.map +1 -0
  49. package/dist/design-system130.js +12 -5
  50. package/dist/design-system130.js.map +1 -1
  51. package/dist/design-system131.js +76 -137
  52. package/dist/design-system131.js.map +1 -1
  53. package/dist/design-system133.js +1 -1
  54. package/dist/design-system133.js.map +1 -1
  55. package/dist/design-system134.js +37 -90
  56. package/dist/design-system134.js.map +1 -1
  57. package/dist/design-system136.js +1 -1
  58. package/dist/design-system136.js.map +1 -1
  59. package/dist/design-system137.js +226 -20
  60. package/dist/design-system137.js.map +1 -1
  61. package/dist/design-system139.js +4 -5
  62. package/dist/design-system139.js.map +1 -1
  63. package/dist/design-system140.js +151 -9
  64. package/dist/design-system140.js.map +1 -1
  65. package/dist/design-system142.js +3 -2
  66. package/dist/design-system142.js.map +1 -1
  67. package/dist/design-system143.js +93 -19
  68. package/dist/design-system143.js.map +1 -1
  69. package/dist/design-system145.js +5 -158
  70. package/dist/design-system145.js.map +1 -1
  71. package/dist/design-system146.js +12 -0
  72. package/dist/design-system146.js.map +1 -0
  73. package/dist/design-system147.js +37 -5
  74. package/dist/design-system147.js.map +1 -1
  75. package/dist/design-system148.js +4 -307
  76. package/dist/design-system148.js.map +1 -1
  77. package/dist/design-system149.js +24 -0
  78. package/dist/{design-system144.js.map → design-system149.js.map} +1 -1
  79. package/dist/design-system150.js +2 -3
  80. package/dist/design-system150.js.map +1 -1
  81. package/dist/design-system151.js +131 -213
  82. package/dist/design-system151.js.map +1 -1
  83. package/dist/design-system153.js +1 -1
  84. package/dist/design-system153.js.map +1 -1
  85. package/dist/design-system154.js +278 -160
  86. package/dist/design-system154.js.map +1 -1
  87. package/dist/design-system156.js +1 -1
  88. package/dist/design-system156.js.map +1 -1
  89. package/dist/design-system157.js +240 -3
  90. package/dist/design-system157.js.map +1 -1
  91. package/dist/design-system159.js +8 -0
  92. package/dist/design-system159.js.map +1 -0
  93. package/dist/design-system16.js.map +1 -1
  94. package/dist/design-system160.js +189 -6
  95. package/dist/design-system160.js.map +1 -1
  96. package/dist/design-system162.js +8 -0
  97. package/dist/design-system162.js.map +1 -0
  98. package/dist/design-system163.js +3 -6
  99. package/dist/design-system163.js.map +1 -1
  100. package/dist/design-system164.js +46 -57
  101. package/dist/design-system164.js.map +1 -1
  102. package/dist/design-system166.js +2 -2
  103. package/dist/design-system166.js.map +1 -1
  104. package/dist/design-system167.js +44 -170
  105. package/dist/design-system167.js.map +1 -1
  106. package/dist/design-system169.js +2 -2
  107. package/dist/design-system169.js.map +1 -1
  108. package/dist/design-system170.js +55 -101
  109. package/dist/design-system170.js.map +1 -1
  110. package/dist/design-system172.js +5 -4
  111. package/dist/design-system172.js.map +1 -1
  112. package/dist/design-system173.js +182 -11
  113. package/dist/design-system173.js.map +1 -1
  114. package/dist/design-system175.js +9 -0
  115. package/dist/design-system175.js.map +1 -0
  116. package/dist/design-system176.js +115 -6
  117. package/dist/design-system176.js.map +1 -1
  118. package/dist/design-system178.js +8 -0
  119. package/dist/design-system178.js.map +1 -0
  120. package/dist/design-system179.js +11 -5
  121. package/dist/design-system179.js.map +1 -1
  122. package/dist/design-system180.js +452 -90
  123. package/dist/design-system180.js.map +1 -1
  124. package/dist/design-system182.js +5 -4
  125. package/dist/design-system182.js.map +1 -1
  126. package/dist/design-system183.js +33 -106
  127. package/dist/design-system183.js.map +1 -1
  128. package/dist/design-system185.js +4 -5
  129. package/dist/design-system185.js.map +1 -1
  130. package/dist/design-system186.js +71 -89
  131. package/dist/design-system186.js.map +1 -1
  132. package/dist/design-system188.js +4 -5
  133. package/dist/design-system188.js.map +1 -1
  134. package/dist/design-system189.js +25 -727
  135. package/dist/design-system189.js.map +1 -1
  136. package/dist/design-system19.js.map +1 -1
  137. package/dist/design-system191.js +1 -1
  138. package/dist/design-system191.js.map +1 -1
  139. package/dist/design-system192.js +28 -11
  140. package/dist/design-system192.js.map +1 -1
  141. package/dist/design-system194.js +8 -0
  142. package/dist/design-system194.js.map +1 -0
  143. package/dist/design-system195.js +33 -5
  144. package/dist/design-system195.js.map +1 -1
  145. package/dist/design-system197.js +5 -46
  146. package/dist/design-system197.js.map +1 -1
  147. package/dist/design-system198.js +31 -4
  148. package/dist/design-system198.js.map +1 -1
  149. package/dist/design-system200.js +8 -0
  150. package/dist/design-system200.js.map +1 -0
  151. package/dist/design-system201.js +332 -5
  152. package/dist/design-system201.js.map +1 -1
  153. package/dist/design-system203.js +8 -0
  154. package/dist/design-system203.js.map +1 -0
  155. package/dist/design-system204.js +100 -5
  156. package/dist/design-system204.js.map +1 -1
  157. package/dist/design-system206.js +8 -0
  158. package/dist/design-system206.js.map +1 -0
  159. package/dist/design-system207.js +19 -5
  160. package/dist/design-system207.js.map +1 -1
  161. package/dist/design-system208.js +4 -54
  162. package/dist/design-system208.js.map +1 -1
  163. package/dist/design-system209.js +3 -4
  164. package/dist/design-system209.js.map +1 -1
  165. package/dist/design-system210.js +386 -137
  166. package/dist/design-system210.js.map +1 -1
  167. package/dist/design-system212.js +1 -1
  168. package/dist/design-system212.js.map +1 -1
  169. package/dist/design-system213.js +59 -7
  170. package/dist/design-system213.js.map +1 -1
  171. package/dist/design-system215.js +8 -0
  172. package/dist/design-system215.js.map +1 -0
  173. package/dist/design-system216.js +88 -5
  174. package/dist/design-system216.js.map +1 -1
  175. package/dist/design-system217.js +4 -580
  176. package/dist/design-system217.js.map +1 -1
  177. package/dist/design-system218.js +111 -0
  178. package/dist/design-system218.js.map +1 -0
  179. package/dist/design-system22.js.map +1 -1
  180. package/dist/design-system220.js +6 -7
  181. package/dist/design-system220.js.map +1 -1
  182. package/dist/design-system221.js +85 -353
  183. package/dist/design-system221.js.map +1 -1
  184. package/dist/design-system223.js +2 -2
  185. package/dist/design-system223.js.map +1 -1
  186. package/dist/design-system224.js +740 -0
  187. package/dist/design-system224.js.map +1 -0
  188. package/dist/design-system226.js +8 -0
  189. package/dist/design-system226.js.map +1 -0
  190. package/dist/{design-system60.js → design-system227.js} +6 -8
  191. package/dist/design-system227.js.map +1 -0
  192. package/dist/{design-system193.js → design-system228.js} +2 -2
  193. package/dist/design-system228.js.map +1 -0
  194. package/dist/design-system230.js +8 -0
  195. package/dist/design-system230.js.map +1 -0
  196. package/dist/{design-system196.js → design-system231.js} +1 -1
  197. package/dist/{design-system196.js.map → design-system231.js.map} +1 -1
  198. package/dist/design-system232.js +49 -0
  199. package/dist/design-system232.js.map +1 -0
  200. package/dist/design-system233.js +7 -0
  201. package/dist/design-system233.js.map +1 -0
  202. package/dist/{design-system199.js → design-system234.js} +2 -2
  203. package/dist/design-system234.js.map +1 -0
  204. package/dist/design-system236.js +8 -0
  205. package/dist/design-system236.js.map +1 -0
  206. package/dist/{design-system202.js → design-system237.js} +1 -1
  207. package/dist/design-system237.js.map +1 -0
  208. package/dist/design-system239.js +8 -0
  209. package/dist/design-system239.js.map +1 -0
  210. package/dist/{design-system205.js → design-system240.js} +1 -1
  211. package/dist/design-system240.js.map +1 -0
  212. package/dist/design-system242.js +8 -0
  213. package/dist/design-system242.js.map +1 -0
  214. package/dist/design-system243.js +57 -0
  215. package/dist/design-system243.js.map +1 -0
  216. package/dist/design-system244.js +7 -0
  217. package/dist/design-system244.js.map +1 -0
  218. package/dist/design-system245.js +173 -0
  219. package/dist/design-system245.js.map +1 -0
  220. package/dist/design-system247.js +8 -0
  221. package/dist/design-system247.js.map +1 -0
  222. package/dist/design-system248.js +10 -0
  223. package/dist/design-system248.js.map +1 -0
  224. package/dist/{design-system214.js → design-system249.js} +2 -2
  225. package/dist/design-system249.js.map +1 -0
  226. package/dist/design-system25.js.map +1 -1
  227. package/dist/design-system251.js +8 -0
  228. package/dist/design-system251.js.map +1 -0
  229. package/dist/design-system252.js +583 -0
  230. package/dist/design-system252.js.map +1 -0
  231. package/dist/{design-system219.js → design-system254.js} +2 -2
  232. package/dist/{design-system219.js.map → design-system254.js.map} +1 -1
  233. package/dist/design-system255.js +12 -0
  234. package/dist/design-system255.js.map +1 -0
  235. package/dist/design-system256.js +769 -0
  236. package/dist/design-system256.js.map +1 -0
  237. package/dist/design-system258.js +9 -0
  238. package/dist/design-system258.js.map +1 -0
  239. package/dist/design-system259.js +10 -0
  240. package/dist/design-system259.js.map +1 -0
  241. package/dist/design-system260.js +377 -0
  242. package/dist/design-system260.js.map +1 -0
  243. package/dist/design-system262.js +9 -0
  244. package/dist/design-system262.js.map +1 -0
  245. package/dist/design-system28.js.map +1 -1
  246. package/dist/design-system3.js.map +1 -1
  247. package/dist/design-system30.js +21 -138
  248. package/dist/design-system30.js.map +1 -1
  249. package/dist/design-system32.js +5 -4
  250. package/dist/design-system32.js.map +1 -1
  251. package/dist/design-system33.js +488 -14
  252. package/dist/design-system33.js.map +1 -1
  253. package/dist/design-system35.js +1 -1
  254. package/dist/design-system35.js.map +1 -1
  255. package/dist/design-system36.js +135 -17
  256. package/dist/design-system36.js.map +1 -1
  257. package/dist/design-system38.js +1 -1
  258. package/dist/design-system38.js.map +1 -1
  259. package/dist/design-system39.js +16 -11
  260. package/dist/design-system39.js.map +1 -1
  261. package/dist/design-system4.js.map +1 -1
  262. package/dist/design-system41.js +8 -0
  263. package/dist/design-system41.js.map +1 -0
  264. package/dist/design-system42.js +26 -5
  265. package/dist/design-system42.js.map +1 -1
  266. package/dist/design-system44.js +5 -71
  267. package/dist/design-system44.js.map +1 -1
  268. package/dist/design-system45.js +353 -0
  269. package/dist/design-system45.js.map +1 -0
  270. package/dist/design-system47.js +5 -50
  271. package/dist/design-system47.js.map +1 -1
  272. package/dist/design-system48.js +11 -4
  273. package/dist/design-system48.js.map +1 -1
  274. package/dist/design-system49.js +476 -3
  275. package/dist/design-system49.js.map +1 -1
  276. package/dist/design-system51.js +8 -0
  277. package/dist/design-system51.js.map +1 -0
  278. package/dist/design-system52.js +3 -5
  279. package/dist/design-system52.js.map +1 -1
  280. package/dist/design-system53.js +56 -83
  281. package/dist/design-system53.js.map +1 -1
  282. package/dist/design-system55.js +5 -4
  283. package/dist/design-system55.js.map +1 -1
  284. package/dist/design-system56.js +50 -11
  285. package/dist/design-system56.js.map +1 -1
  286. package/dist/design-system57.js +4 -591
  287. package/dist/design-system57.js.map +1 -1
  288. package/dist/design-system58.js +6 -0
  289. package/dist/design-system58.js.map +1 -0
  290. package/dist/design-system59.js +64 -5
  291. package/dist/design-system59.js.map +1 -1
  292. package/dist/design-system61.js +5 -696
  293. package/dist/design-system61.js.map +1 -1
  294. package/dist/design-system62.js +101 -0
  295. package/dist/design-system62.js.map +1 -0
  296. package/dist/design-system64.js +5 -158
  297. package/dist/design-system64.js.map +1 -1
  298. package/dist/design-system65.js +14 -0
  299. package/dist/design-system65.js.map +1 -0
  300. package/dist/design-system66.js +591 -5
  301. package/dist/design-system66.js.map +1 -1
  302. package/dist/design-system68.js +3 -2
  303. package/dist/design-system68.js.map +1 -1
  304. package/dist/design-system69.js +13 -49
  305. package/dist/design-system69.js.map +1 -1
  306. package/dist/design-system7.js.map +1 -1
  307. package/dist/design-system70.js +699 -0
  308. package/dist/{design-system63.js.map → design-system70.js.map} +1 -1
  309. package/dist/design-system72.js +5 -199
  310. package/dist/design-system72.js.map +1 -1
  311. package/dist/design-system73.js +161 -0
  312. package/dist/design-system73.js.map +1 -0
  313. package/dist/design-system75.js +5 -7
  314. package/dist/design-system75.js.map +1 -1
  315. package/dist/design-system76.js +25 -269
  316. package/dist/design-system76.js.map +1 -1
  317. package/dist/design-system77.js +7 -0
  318. package/dist/design-system77.js.map +1 -0
  319. package/dist/design-system78.js +49 -5
  320. package/dist/design-system78.js.map +1 -1
  321. package/dist/{design-system71.js → design-system80.js} +2 -2
  322. package/dist/{design-system71.js.map → design-system80.js.map} +1 -1
  323. package/dist/design-system81.js +199 -5
  324. package/dist/design-system81.js.map +1 -1
  325. package/dist/design-system83.js +5 -99
  326. package/dist/design-system83.js.map +1 -1
  327. package/dist/design-system84.js +10 -0
  328. package/dist/design-system84.js.map +1 -0
  329. package/dist/design-system85.js +273 -5
  330. package/dist/design-system85.js.map +1 -1
  331. package/dist/design-system87.js +8 -0
  332. package/dist/design-system87.js.map +1 -0
  333. package/dist/design-system88.js +57 -5
  334. package/dist/design-system88.js.map +1 -1
  335. package/dist/design-system90.js +8 -0
  336. package/dist/design-system90.js.map +1 -0
  337. package/dist/design-system91.js +11 -5
  338. package/dist/design-system91.js.map +1 -1
  339. package/dist/design-system92.js +98 -53
  340. package/dist/design-system92.js.map +1 -1
  341. package/dist/design-system94.js +5 -13
  342. package/dist/design-system94.js.map +1 -1
  343. package/dist/design-system95.js +61 -104
  344. package/dist/design-system95.js.map +1 -1
  345. package/dist/design-system97.js +4 -5
  346. package/dist/design-system97.js.map +1 -1
  347. package/dist/design-system98.js +80 -198
  348. package/dist/design-system98.js.map +1 -1
  349. package/dist/types/components/BCalendar/BCalendar.spec.d.ts +1 -0
  350. package/dist/types/components/BCalendar/BCalendar.vue.d.ts +114 -0
  351. package/dist/types/components/BCalendar/index.d.ts +2 -0
  352. package/dist/types/components/BCalendar/types.d.ts +54 -0
  353. package/dist/types/components/BCarousel/BCarousel.spec.d.ts +1 -0
  354. package/dist/types/components/BCarousel/BCarousel.vue.d.ts +133 -0
  355. package/dist/types/components/BCarousel/index.d.ts +2 -0
  356. package/dist/types/components/BCarousel/types.d.ts +15 -0
  357. package/dist/types/components/BPagination/BPagination.vue.d.ts +1 -1
  358. package/dist/types/components/BSkeleton/BSkeleton.spec.d.ts +1 -0
  359. package/dist/types/components/BSkeleton/BSkeleton.vue.d.ts +46 -0
  360. package/dist/types/components/BSkeleton/BSkeletonAvatar.vue.d.ts +12 -0
  361. package/dist/types/components/BSkeleton/BSkeletonButton.vue.d.ts +14 -0
  362. package/dist/types/components/BSkeleton/BSkeletonImage.vue.d.ts +7 -0
  363. package/dist/types/components/BSkeleton/BSkeletonInput.vue.d.ts +12 -0
  364. package/dist/types/components/BSkeleton/BSkeletonNode.vue.d.ts +19 -0
  365. package/dist/types/components/BSkeleton/index.d.ts +7 -0
  366. package/dist/types/components/BSkeleton/types.d.ts +20 -0
  367. package/dist/types/components/BSplitter/BSplitter.spec.d.ts +1 -0
  368. package/dist/types/components/BSplitter/BSplitter.vue.d.ts +45 -0
  369. package/dist/types/components/BSplitter/BSplitterPanel.vue.d.ts +40 -0
  370. package/dist/types/components/BSplitter/index.d.ts +3 -0
  371. package/dist/types/components/BSplitter/types.d.ts +42 -0
  372. package/dist/types/components/BStatistic/BStatistic.spec.d.ts +1 -0
  373. package/dist/types/components/BStatistic/BStatistic.vue.d.ts +44 -0
  374. package/dist/types/components/BStatistic/BStatisticTimer.vue.d.ts +50 -0
  375. package/dist/types/components/BStatistic/index.d.ts +3 -0
  376. package/dist/types/components/BStatistic/types.d.ts +6 -0
  377. package/dist/types/components/BTreeSelect/BTreeSelect.spec.d.ts +1 -0
  378. package/dist/types/components/BTreeSelect/BTreeSelect.vue.d.ts +143 -0
  379. package/dist/types/components/BTreeSelect/index.d.ts +2 -0
  380. package/dist/types/components/BTreeSelect/types.d.ts +77 -0
  381. package/dist/types/components/index.d.ts +6 -0
  382. package/dist/types/types.d.ts +3 -0
  383. package/package.json +6 -3
  384. package/dist/design-system105.js +0 -212
  385. package/dist/design-system105.js.map +0 -1
  386. package/dist/design-system108.js +0 -227
  387. package/dist/design-system108.js.map +0 -1
  388. package/dist/design-system111.js +0 -166
  389. package/dist/design-system111.js.map +0 -1
  390. package/dist/design-system115.js +0 -277
  391. package/dist/design-system115.js.map +0 -1
  392. package/dist/design-system118.js +0 -19
  393. package/dist/design-system118.js.map +0 -1
  394. package/dist/design-system121.js +0 -15
  395. package/dist/design-system121.js.map +0 -1
  396. package/dist/design-system125.js +0 -45
  397. package/dist/design-system125.js.map +0 -1
  398. package/dist/design-system128.js +0 -236
  399. package/dist/design-system128.js.map +0 -1
  400. package/dist/design-system141.js +0 -40
  401. package/dist/design-system141.js.map +0 -1
  402. package/dist/design-system144.js +0 -7
  403. package/dist/design-system158.js +0 -61
  404. package/dist/design-system158.js.map +0 -1
  405. package/dist/design-system161.js +0 -59
  406. package/dist/design-system161.js.map +0 -1
  407. package/dist/design-system174.js +0 -465
  408. package/dist/design-system174.js.map +0 -1
  409. package/dist/design-system177.js +0 -335
  410. package/dist/design-system177.js.map +0 -1
  411. package/dist/design-system193.js.map +0 -1
  412. package/dist/design-system199.js.map +0 -1
  413. package/dist/design-system202.js.map +0 -1
  414. package/dist/design-system205.js.map +0 -1
  415. package/dist/design-system214.js.map +0 -1
  416. package/dist/design-system40.js +0 -479
  417. package/dist/design-system40.js.map +0 -1
  418. package/dist/design-system43.js +0 -6
  419. package/dist/design-system43.js.map +0 -1
  420. package/dist/design-system46.js +0 -9
  421. package/dist/design-system46.js.map +0 -1
  422. package/dist/design-system50.js +0 -67
  423. package/dist/design-system50.js.map +0 -1
  424. package/dist/design-system60.js.map +0 -1
  425. package/dist/design-system63.js +0 -8
  426. package/dist/design-system67.js +0 -32
  427. package/dist/design-system67.js.map +0 -1
  428. package/dist/design-system74.js +0 -8
  429. package/dist/design-system74.js.map +0 -1
  430. package/dist/design-system79.js +0 -60
  431. package/dist/design-system79.js.map +0 -1
  432. package/dist/design-system82.js +0 -14
  433. package/dist/design-system82.js.map +0 -1
  434. package/dist/design-system86.js +0 -69
  435. package/dist/design-system86.js.map +0 -1
  436. package/dist/design-system89.js +0 -91
  437. package/dist/design-system89.js.map +0 -1
  438. package/dist/design-system93.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import e from "./design-system33.js";
2
2
  /* empty css */
3
- //#region src/components/BCard/BCardGrid.vue
3
+ //#region src/components/BCalendar/BCalendar.vue
4
4
  var t = e;
5
5
  //#endregion
6
6
  export { t as default };
@@ -1 +1 @@
1
- {"version":3,"file":"design-system35.js","names":[],"sources":["../src/components/BCard/BCardGrid.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst { hoverable = false } = defineProps<{\n /** Whether to apply hover styling to the grid item. @default false */\n hoverable?: boolean;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Content inside the grid item */\n default?: (props: Record<string, never>) => unknown;\n}>();\n</script>\n\n<template>\n <div\n class=\"b-card-grid\"\n :class=\"{ 'b-card-grid--hoverable': hoverable }\"\n :role=\"$attrs['aria-label'] ? 'region' : undefined\"\n >\n <slot />\n </div>\n</template>\n\n<style>\n.b-card-grid {\n --b-card-grid-width: 33.33%;\n --b-card-grid-padding: 24px;\n --b-card-grid-border-color: oklch(90% 0.01 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 12%);\n --b-card-grid-transition-duration: 200ms;\n\n float: left;\n width: var(--b-card-grid-width);\n padding: var(--b-card-grid-padding);\n border: 0;\n border-radius: 0;\n box-shadow:\n 1px 0 0 0 var(--b-card-grid-border-color),\n 0 1px 0 0 var(--b-card-grid-border-color),\n 1px 1px 0 0 var(--b-card-grid-border-color),\n 1px 0 0 0 var(--b-card-grid-border-color) inset,\n 0 1px 0 0 var(--b-card-grid-border-color) inset;\n box-sizing: border-box;\n transition: box-shadow var(--b-card-grid-transition-duration) ease;\n}\n\n.b-card-grid--hoverable {\n cursor: pointer;\n}\n\n.b-card-grid--hoverable:hover {\n position: relative;\n z-index: 1;\n box-shadow: var(--b-card-grid-shadow-hover);\n}\n\n.b-card-grid--hoverable:focus-visible {\n outline: 2px solid oklch(46% 0.24 264);\n outline-offset: -2px;\n position: relative;\n z-index: 1;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-card-grid {\n --b-card-grid-transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"design-system35.js","names":[],"sources":["../src/components/BCalendar/BCalendar.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\n\nimport { useComponentId } from '@/composables/useComponentId';\nimport BModal from '@/components/BModal/BModal.vue';\n\nimport type {\n BCalendarCellSlotScope,\n BCalendarEvent,\n BCalendarEventDetailsSlotScope,\n BCalendarHeaderSlotScope,\n BCalendarMode,\n BCalendarSelectInfo,\n} from './types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n modelValue,\n defaultValue,\n mode,\n defaultMode = 'month',\n fullscreen = true,\n showWeek = false,\n validRange,\n locale,\n disabledDate,\n ariaLabel = 'Calendar',\n events,\n showEventDetails = true,\n maxEventsVisible = 3,\n} = defineProps<{\n /**\n * Controlled selected date. Pair with `v-model` for two-way binding.\n * AntD: `value`.\n */\n modelValue?: Date | null;\n /**\n * Initial selected date when uncontrolled.\n * AntD: `defaultValue`.\n */\n defaultValue?: Date;\n /**\n * Controlled panel mode (month / year). When omitted, the component\n * manages its own mode starting from `defaultMode`.\n * AntD: `mode`.\n */\n mode?: BCalendarMode;\n /**\n * Initial panel mode when uncontrolled.\n * @default 'month'\n */\n defaultMode?: BCalendarMode;\n /**\n * Full-screen layout when `true`, mini layout when `false`.\n * AntD: `fullscreen`.\n * @default true\n */\n fullscreen?: boolean;\n /**\n * Show a week-number column in month mode.\n * AntD: `showWeek`.\n * @default false\n */\n showWeek?: boolean;\n /**\n * Inclusive [start, end] range outside which dates are disabled.\n * AntD: `validRange`.\n */\n validRange?: [Date, Date];\n /**\n * BCP 47 locale tag for weekday / month labels (e.g. `'en-US'`, `'vi-VN'`).\n * AntD: `locale` (object). We accept a locale string and use Intl.\n */\n locale?: string;\n /**\n * Predicate to disable specific dates.\n * AntD: `disabledDate`.\n */\n disabledDate?: (date: Date) => boolean;\n /** Accessible label for the calendar root region. */\n ariaLabel?: string;\n /**\n * Returns events for a given date. When provided, event titles are auto-rendered\n * inside each day cell (unless the `dateCell` slot replaces them).\n */\n events?: (date: Date) => BCalendarEvent[];\n /**\n * Open a details modal when clicking a date that has events.\n * Set `false` to keep clicks selection-only.\n * @default true\n */\n showEventDetails?: boolean;\n /**\n * Maximum number of events shown inline per day cell. Extra events collapse\n * into a \"+N more\" indicator (full list is still available in the modal).\n * @default 3\n */\n maxEventsVisible?: number;\n}>();\n\n// ─────────────────────────────────────────────\n// Emits\n// ─────────────────────────────────────────────\nconst emit = defineEmits<{\n /** Two-way binding for the selected date. */\n 'update:modelValue': [date: Date];\n /** Two-way binding for the panel mode. */\n 'update:mode': [mode: BCalendarMode];\n /** Fires when the selected date changes. AntD: `onChange`. */\n change: [date: Date];\n /** Fires on date / month / year selection. AntD: `onSelect`. */\n select: [date: Date, info: BCalendarSelectInfo];\n /** Fires when panel value or mode changes. AntD: `onPanelChange`. */\n panelChange: [date: Date, mode: BCalendarMode];\n}>();\n\n// ─────────────────────────────────────────────\n// Slots (parity with AntD render props)\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Custom header. AntD: `headerRender`. */\n header?(scope: BCalendarHeaderSlotScope): unknown;\n /** Inject extra content into a date cell. AntD: `cellRender` (date). */\n dateCell?(scope: BCalendarCellSlotScope): unknown;\n /** Inject extra content into a month cell. AntD: `cellRender` (month). */\n monthCell?(scope: BCalendarCellSlotScope): unknown;\n /** Replace the entire date cell. AntD: `fullCellRender` / `dateFullCellRender`. */\n dateFullCell?(scope: BCalendarCellSlotScope): unknown;\n /** Replace the entire month cell. AntD: `fullCellRender` / `monthFullCellRender`. */\n monthFullCell?(scope: BCalendarCellSlotScope): unknown;\n /** Replace the contents of the event-details modal. */\n eventDetails?(scope: BCalendarEventDetailsSlotScope): unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// State\n// ─────────────────────────────────────────────\nconst { componentUID } = useComponentId();\nconst ROOT_ID = `b-calendar-${componentUID.value}`;\n\nconst internalValue = ref<Date | null>(defaultValue ?? null);\nconst internalMode = ref<BCalendarMode>(defaultMode);\n// The currently displayed panel anchor. Always a real Date (today as fallback).\nconst panelDate = ref<Date>(stripTime(defaultValue ?? modelValue ?? new Date()));\n\nconst isControlledValue = computed(() => modelValue !== undefined);\nconst isControlledMode = computed(() => mode !== undefined);\n\nconst selectedDate = computed<Date | null>(() =>\n isControlledValue.value ? (modelValue ?? null) : internalValue.value,\n);\n\nconst activeMode = computed<BCalendarMode>(() =>\n isControlledMode.value ? (mode as BCalendarMode) : internalMode.value,\n);\n\nwatch(\n () => modelValue,\n (val) => {\n if (val) panelDate.value = stripTime(val);\n },\n);\n\n// ─────────────────────────────────────────────\n// Locale helpers\n// ─────────────────────────────────────────────\nconst resolvedLocale = computed(() => {\n const tag =\n locale ??\n (typeof navigator !== 'undefined' ? navigator.language : undefined) ??\n 'en-US';\n try {\n Intl.DateTimeFormat(tag);\n return tag;\n } catch {\n return 'en-US';\n }\n});\n\nconst weekdayLabels = computed(() => {\n const loc = resolvedLocale.value;\n // Sunday-start: 2024-01-07 is a Sunday.\n return Array.from({ length: 7 }, (_, i) =>\n new Date(2024, 0, 7 + i).toLocaleDateString(loc, { weekday: 'short' }),\n );\n});\n\nconst monthLabels = computed(() => {\n const loc = resolvedLocale.value;\n return Array.from({ length: 12 }, (_, i) =>\n new Date(2024, i, 1).toLocaleDateString(loc, { month: fullscreen ? 'long' : 'short' }),\n );\n});\n\nconst monthLabelsShort = computed(() => {\n const loc = resolvedLocale.value;\n return Array.from({ length: 12 }, (_, i) =>\n new Date(2024, i, 1).toLocaleDateString(loc, { month: 'short' }),\n );\n});\n\nconst todayLabel = computed(() => {\n try {\n const rtf = new Intl.RelativeTimeFormat(resolvedLocale.value, { numeric: 'auto' });\n const v = rtf.formatToParts(0, 'day').find((p) => p.type === 'literal')?.value;\n if (v && v.trim()) return v.trim().charAt(0).toUpperCase() + v.trim().slice(1);\n } catch {\n /* no-op */\n }\n return 'Today';\n});\n\n// ─────────────────────────────────────────────\n// Date helpers\n// ─────────────────────────────────────────────\nfunction stripTime(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\nfunction isSameMonth(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();\n}\n\nfunction getWeekNumber(d: Date): number {\n const c = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));\n c.setUTCDate(c.getUTCDate() + 4 - (c.getUTCDay() || 7));\n const yearStart = new Date(Date.UTC(c.getUTCFullYear(), 0, 1));\n return Math.ceil(((c.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nfunction isOutOfValidRange(d: Date): boolean {\n if (!validRange) return false;\n const start = stripTime(validRange[0]);\n const end = stripTime(validRange[1]);\n const t = stripTime(d);\n return t < start || t > end;\n}\n\nfunction isDateDisabled(d: Date): boolean {\n if (isOutOfValidRange(d)) return true;\n if (disabledDate) return disabledDate(d);\n return false;\n}\n\nfunction isMonthDisabled(year: number, month: number): boolean {\n // Month is disabled only when no day in it falls inside the valid range.\n if (!validRange) return false;\n const startMonth = new Date(validRange[0].getFullYear(), validRange[0].getMonth(), 1);\n const endMonth = new Date(validRange[1].getFullYear(), validRange[1].getMonth(), 1);\n const m = new Date(year, month, 1);\n return m < startMonth || m > endMonth;\n}\n\n// ─────────────────────────────────────────────\n// Grid generation\n// ─────────────────────────────────────────────\nconst today = computed(() => stripTime(new Date()));\n\ninterface DateCell {\n date: Date;\n outside: boolean;\n}\n\nconst monthGrid = computed<DateCell[]>(() => {\n const year = panelDate.value.getFullYear();\n const month = panelDate.value.getMonth();\n const firstDay = new Date(year, month, 1);\n const startOffset = firstDay.getDay(); // 0..6 (Sunday-start)\n const cells: DateCell[] = [];\n\n // Leading days from previous month.\n for (let i = startOffset - 1; i >= 0; i--) {\n cells.push({ date: new Date(year, month, -i), outside: true });\n }\n // Current month.\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n for (let i = 1; i <= daysInMonth; i++) {\n cells.push({ date: new Date(year, month, i), outside: false });\n }\n // Trailing days to fill 6 weeks (42 cells).\n let trailing = 1;\n while (cells.length < 42) {\n cells.push({ date: new Date(year, month + 1, trailing++), outside: true });\n }\n return cells;\n});\n\nconst monthRows = computed(() => {\n const rows: DateCell[][] = [];\n const cells = monthGrid.value;\n for (let i = 0; i < 6; i++) rows.push(cells.slice(i * 7, i * 7 + 7));\n return rows;\n});\n\nconst yearGrid = computed(() => {\n const year = panelDate.value.getFullYear();\n return Array.from({ length: 12 }, (_, i) => ({\n date: new Date(year, i, 1),\n month: i,\n year,\n }));\n});\n\nconst headerYearOptions = computed(() => {\n const center = panelDate.value.getFullYear();\n const min = validRange ? validRange[0].getFullYear() : center - 10;\n const max = validRange ? validRange[1].getFullYear() : center + 10;\n const out: number[] = [];\n for (let y = min; y <= max; y++) out.push(y);\n return out;\n});\n\nconst headerMonthOptions = computed(() =>\n monthLabels.value.map((label, idx) => ({\n label,\n value: idx,\n disabled: isMonthDisabled(panelDate.value.getFullYear(), idx),\n })),\n);\n\nconst panelYear = computed(() => panelDate.value.getFullYear());\nconst panelMonth = computed(() => panelDate.value.getMonth());\n\n// ─────────────────────────────────────────────\n// Events feature\n// ─────────────────────────────────────────────\nfunction getEventsForDate(date: Date): BCalendarEvent[] {\n if (!events) return [];\n try {\n return events(date) ?? [];\n } catch {\n return [];\n }\n}\n\nconst eventModalOpen = ref(false);\nconst modalDate = ref<Date | null>(null);\nconst modalEvents = computed<BCalendarEvent[]>(() =>\n modalDate.value ? getEventsForDate(modalDate.value) : [],\n);\n\nfunction closeEventModal() {\n eventModalOpen.value = false;\n}\n\nconst modalDateLabel = computed(() => {\n if (!modalDate.value) return '';\n try {\n return modalDate.value.toLocaleDateString(resolvedLocale.value, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n } catch {\n return formatISODate(modalDate.value);\n }\n});\n\n// ─────────────────────────────────────────────\n// Behavior\n// ─────────────────────────────────────────────\nfunction setSelected(date: Date) {\n if (!isControlledValue.value) {\n internalValue.value = date;\n }\n emit('update:modelValue', date);\n emit('change', date);\n}\n\nfunction setMode(next: BCalendarMode) {\n if (!isControlledMode.value) {\n internalMode.value = next;\n }\n emit('update:mode', next);\n emit('panelChange', panelDate.value, next);\n}\n\nfunction setPanelDate(date: Date) {\n panelDate.value = stripTime(date);\n emit('panelChange', panelDate.value, activeMode.value);\n}\n\nfunction selectDate(date: Date) {\n if (isDateDisabled(date)) return;\n panelDate.value = stripTime(date);\n setSelected(stripTime(date));\n emit('select', stripTime(date), { source: 'date' });\n if (showEventDetails && events) {\n const list = getEventsForDate(date);\n if (list.length > 0) {\n modalDate.value = stripTime(date);\n eventModalOpen.value = true;\n }\n }\n}\n\nfunction selectMonth(year: number, month: number) {\n if (isMonthDisabled(year, month)) return;\n const date = new Date(year, month, 1);\n panelDate.value = date;\n if (activeMode.value === 'year') {\n // Drill down: go to month view, no actual selection yet.\n setMode('month');\n emit('select', date, { source: 'month' });\n } else {\n setSelected(date);\n emit('select', date, { source: 'month' });\n }\n}\n\nfunction onYearSelectChange(e: Event) {\n const y = Number((e.target as HTMLSelectElement).value);\n if (Number.isNaN(y)) return;\n const next = new Date(y, panelDate.value.getMonth(), 1);\n panelDate.value = next;\n emit('select', next, { source: 'year' });\n emit('panelChange', next, activeMode.value);\n}\n\nfunction onMonthSelectChange(e: Event) {\n const m = Number((e.target as HTMLSelectElement).value);\n if (Number.isNaN(m)) return;\n const next = new Date(panelDate.value.getFullYear(), m, 1);\n panelDate.value = next;\n emit('panelChange', next, activeMode.value);\n}\n\nfunction onModeChange(e: Event) {\n setMode((e.target as HTMLInputElement).value as BCalendarMode);\n}\n\nfunction selectToday() {\n const t = stripTime(new Date());\n panelDate.value = t;\n setSelected(t);\n emit('select', t, { source: 'date' });\n}\n\n// ─────────────────────────────────────────────\n// Keyboard navigation (month grid)\n// ─────────────────────────────────────────────\nconst focusedDate = ref<Date | null>(null);\nconst gridRef = ref<HTMLElement | null>(null);\n\nfunction onCellKeydown(e: KeyboardEvent, cell: DateCell) {\n let delta = 0;\n switch (e.key) {\n case 'ArrowLeft':\n delta = -1;\n break;\n case 'ArrowRight':\n delta = 1;\n break;\n case 'ArrowUp':\n delta = -7;\n break;\n case 'ArrowDown':\n delta = 7;\n break;\n case 'PageUp':\n delta = e.shiftKey ? -365 : -30;\n break;\n case 'PageDown':\n delta = e.shiftKey ? 365 : 30;\n break;\n case 'Home':\n e.preventDefault();\n moveFocusTo(new Date(cell.date.getFullYear(), cell.date.getMonth(), 1));\n return;\n case 'End': {\n e.preventDefault();\n const eom = new Date(cell.date.getFullYear(), cell.date.getMonth() + 1, 0);\n moveFocusTo(eom);\n return;\n }\n case 'Enter':\n case ' ':\n e.preventDefault();\n selectDate(cell.date);\n return;\n default:\n return;\n }\n e.preventDefault();\n const next = new Date(cell.date);\n next.setDate(next.getDate() + delta);\n moveFocusTo(next);\n}\n\nfunction moveFocusTo(date: Date) {\n if (!isSameMonth(date, panelDate.value)) {\n panelDate.value = new Date(date.getFullYear(), date.getMonth(), 1);\n emit('panelChange', panelDate.value, activeMode.value);\n }\n focusedDate.value = stripTime(date);\n // Wait one tick so the rendered cell with new tabindex=0 can be focused.\n queueMicrotask(() => {\n const sel = `[data-b-calendar-date=\"${formatISODate(date)}\"]`;\n const el = gridRef.value?.querySelector<HTMLElement>(sel);\n el?.focus();\n });\n}\n\nfunction formatISODate(d: Date): string {\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;\n}\n\nfunction isCellFocusable(cell: DateCell): boolean {\n // Roving tabindex anchor: focusedDate || selectedDate || today (clamped to current panel).\n const anchor = focusedDate.value ?? selectedDate.value ?? today.value;\n if (isSameMonth(anchor, panelDate.value)) {\n return isSameDay(cell.date, anchor) && !cell.outside;\n }\n // Anchor is in another month: pick first non-outside day of the panel.\n const firstOfMonth = new Date(panelDate.value.getFullYear(), panelDate.value.getMonth(), 1);\n return isSameDay(cell.date, firstOfMonth) && !cell.outside;\n}\n\n// ─────────────────────────────────────────────\n// Header scope (for custom slot)\n// ─────────────────────────────────────────────\nconst headerScope = computed<BCalendarHeaderSlotScope>(() => ({\n value: panelDate.value,\n mode: activeMode.value,\n onTypeChange: setMode,\n onChange: setPanelDate,\n}));\n\n// ─────────────────────────────────────────────\n// Cell scope helper\n// ─────────────────────────────────────────────\nfunction dateCellScope(cell: DateCell): BCalendarCellSlotScope {\n return {\n date: cell.date,\n selected: !!selectedDate.value && isSameDay(cell.date, selectedDate.value),\n today: isSameDay(cell.date, today.value),\n outside: cell.outside,\n disabled: isDateDisabled(cell.date),\n };\n}\n\nfunction monthCellScope(year: number, month: number): BCalendarCellSlotScope {\n const date = new Date(year, month, 1);\n return {\n date,\n selected:\n !!selectedDate.value &&\n selectedDate.value.getFullYear() === year &&\n selectedDate.value.getMonth() === month,\n today: today.value.getFullYear() === year && today.value.getMonth() === month,\n outside: false,\n disabled: isMonthDisabled(year, month),\n };\n}\n\n// ─────────────────────────────────────────────\n// Expose\n// ─────────────────────────────────────────────\ndefineExpose({\n /** Programmatically select a date. */\n select: (d: Date) => selectDate(d),\n /** Programmatically change the panel mode. */\n setMode,\n /** Move the panel to a specific date without selecting. */\n goTo: setPanelDate,\n});\n</script>\n\n<template>\n <section\n :id=\"ROOT_ID\"\n class=\"b-calendar\"\n :class=\"{\n 'b-calendar--fullscreen': fullscreen,\n 'b-calendar--mini': !fullscreen,\n 'b-calendar--mode-month': activeMode === 'month',\n 'b-calendar--mode-year': activeMode === 'year',\n 'b-calendar--show-week': showWeek,\n }\"\n role=\"region\"\n :aria-label=\"ariaLabel\"\n >\n <!-- ── Header ── -->\n <header v-if=\"$slots.header\" class=\"b-calendar__header\">\n <slot name=\"header\" v-bind=\"headerScope\" />\n </header>\n <header v-else class=\"b-calendar__header\">\n <div class=\"b-calendar__header-controls\">\n <label class=\"b-calendar__sr-only\" :for=\"`${ROOT_ID}-year`\">Year</label>\n <span class=\"b-calendar__select-wrapper\">\n <select\n :id=\"`${ROOT_ID}-year`\"\n class=\"b-calendar__select b-calendar__select--year\"\n :value=\"panelYear\"\n aria-label=\"Select year\"\n @change=\"onYearSelectChange\"\n >\n <option v-for=\"y in headerYearOptions\" :key=\"y\" :value=\"y\">\n {{ y }}\n </option>\n </select>\n </span>\n\n <template v-if=\"activeMode === 'month'\">\n <label class=\"b-calendar__sr-only\" :for=\"`${ROOT_ID}-month`\">Month</label>\n <span class=\"b-calendar__select-wrapper\">\n <select\n :id=\"`${ROOT_ID}-month`\"\n class=\"b-calendar__select b-calendar__select--month\"\n :value=\"panelMonth\"\n aria-label=\"Select month\"\n @change=\"onMonthSelectChange\"\n >\n <option\n v-for=\"opt in headerMonthOptions\"\n :key=\"opt.value\"\n :value=\"opt.value\"\n :disabled=\"opt.disabled\"\n >\n {{ opt.label }}\n </option>\n </select>\n </span>\n </template>\n\n <div\n class=\"b-calendar__mode-switch\"\n role=\"radiogroup\"\n aria-label=\"Calendar mode\"\n >\n <label\n class=\"b-calendar__mode-option\"\n :class=\"{ 'b-calendar__mode-option--active': activeMode === 'month' }\"\n >\n <input\n type=\"radio\"\n :name=\"`${ROOT_ID}-mode`\"\n value=\"month\"\n :checked=\"activeMode === 'month'\"\n class=\"b-calendar__sr-only\"\n @change=\"onModeChange\"\n />\n <span>Month</span>\n </label>\n <label\n class=\"b-calendar__mode-option\"\n :class=\"{ 'b-calendar__mode-option--active': activeMode === 'year' }\"\n >\n <input\n type=\"radio\"\n :name=\"`${ROOT_ID}-mode`\"\n value=\"year\"\n :checked=\"activeMode === 'year'\"\n class=\"b-calendar__sr-only\"\n @change=\"onModeChange\"\n />\n <span>Year</span>\n </label>\n </div>\n </div>\n <button\n type=\"button\"\n class=\"b-calendar__today-btn\"\n @click=\"selectToday\"\n >\n {{ todayLabel }}\n </button>\n </header>\n\n <!-- ── Body ── -->\n <div class=\"b-calendar__body\">\n <!-- Month grid -->\n <table\n v-if=\"activeMode === 'month'\"\n ref=\"gridRef\"\n class=\"b-calendar__table\"\n role=\"grid\"\n :aria-label=\"`${ariaLabel} dates`\"\n >\n <thead>\n <tr role=\"row\">\n <th\n v-if=\"showWeek\"\n class=\"b-calendar__weekday b-calendar__weekday--week\"\n scope=\"col\"\n aria-label=\"Week\"\n >\n #\n </th>\n <th\n v-for=\"day in weekdayLabels\"\n :key=\"day\"\n class=\"b-calendar__weekday\"\n scope=\"col\"\n :aria-label=\"day\"\n >\n {{ day }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr v-for=\"(row, ri) in monthRows\" :key=\"ri\" role=\"row\">\n <td\n v-if=\"showWeek\"\n class=\"b-calendar__week-number\"\n role=\"rowheader\"\n >\n {{ getWeekNumber(row[0].date) }}\n </td>\n <td\n v-for=\"cell in row\"\n :key=\"formatISODate(cell.date)\"\n class=\"b-calendar__cell\"\n :class=\"{\n 'b-calendar__cell--outside': cell.outside,\n 'b-calendar__cell--today': isSameDay(cell.date, today),\n 'b-calendar__cell--selected': dateCellScope(cell).selected,\n 'b-calendar__cell--disabled': isDateDisabled(cell.date),\n }\"\n role=\"gridcell\"\n :aria-selected=\"dateCellScope(cell).selected || undefined\"\n :aria-disabled=\"isDateDisabled(cell.date) || undefined\"\n :aria-current=\"isSameDay(cell.date, today) ? 'date' : undefined\"\n :data-b-calendar-date=\"formatISODate(cell.date)\"\n :tabindex=\"isCellFocusable(cell) ? 0 : -1\"\n @click=\"!isDateDisabled(cell.date) && selectDate(cell.date)\"\n @keydown=\"onCellKeydown($event, cell)\"\n >\n <slot\n v-if=\"$slots.dateFullCell\"\n name=\"dateFullCell\"\n v-bind=\"dateCellScope(cell)\"\n />\n <div v-else class=\"b-calendar__date\">\n <div class=\"b-calendar__date-value\">{{ cell.date.getDate() }}</div>\n <div class=\"b-calendar__date-content\">\n <slot\n v-if=\"$slots.dateCell\"\n name=\"dateCell\"\n v-bind=\"dateCellScope(cell)\"\n />\n <template v-else-if=\"events && getEventsForDate(cell.date).length > 0\">\n <ul class=\"b-calendar__events\">\n <li\n v-for=\"(ev, idx) in getEventsForDate(cell.date).slice(0, maxEventsVisible)\"\n :key=\"idx\"\n class=\"b-calendar__event\"\n :class=\"`b-calendar__event--${ev.type ?? 'default'}`\"\n :title=\"ev.title\"\n >\n <span class=\"b-calendar__event-dot\" aria-hidden=\"true\" />\n <span class=\"b-calendar__event-title\">{{ ev.title }}</span>\n </li>\n </ul>\n <div\n v-if=\"getEventsForDate(cell.date).length > maxEventsVisible\"\n class=\"b-calendar__events-more\"\n >\n +{{ getEventsForDate(cell.date).length - maxEventsVisible }} more\n </div>\n </template>\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n\n <!-- Year grid -->\n <table\n v-else\n class=\"b-calendar__table b-calendar__table--year\"\n role=\"grid\"\n :aria-label=\"`${ariaLabel} months`\"\n >\n <tbody>\n <tr v-for=\"rowIdx in 4\" :key=\"rowIdx\" role=\"row\">\n <td\n v-for=\"m in yearGrid.slice((rowIdx - 1) * 3, rowIdx * 3)\"\n :key=\"m.month\"\n class=\"b-calendar__cell b-calendar__cell--month\"\n :class=\"{\n 'b-calendar__cell--selected': monthCellScope(m.year, m.month).selected,\n 'b-calendar__cell--today': monthCellScope(m.year, m.month).today,\n 'b-calendar__cell--disabled': isMonthDisabled(m.year, m.month),\n }\"\n role=\"gridcell\"\n :aria-selected=\"monthCellScope(m.year, m.month).selected || undefined\"\n :aria-disabled=\"isMonthDisabled(m.year, m.month) || undefined\"\n :tabindex=\"\n monthCellScope(m.year, m.month).selected ||\n (!selectedDate && m.month === today.getMonth() && m.year === today.getFullYear())\n ? 0\n : -1\n \"\n @click=\"!isMonthDisabled(m.year, m.month) && selectMonth(m.year, m.month)\"\n @keydown.enter.prevent=\"selectMonth(m.year, m.month)\"\n @keydown.space.prevent=\"selectMonth(m.year, m.month)\"\n >\n <slot\n v-if=\"$slots.monthFullCell\"\n name=\"monthFullCell\"\n v-bind=\"monthCellScope(m.year, m.month)\"\n />\n <div v-else class=\"b-calendar__month\">\n <div class=\"b-calendar__month-value\">{{ monthLabelsShort[m.month] }}</div>\n <div class=\"b-calendar__month-content\">\n <slot name=\"monthCell\" v-bind=\"monthCellScope(m.year, m.month)\" />\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- ── Live region for screen readers ── -->\n <div class=\"b-calendar__sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ activeMode === 'month' ? monthLabels[panelMonth] : '' }} {{ panelYear }}\n </div>\n\n <!-- ── Event details modal ── -->\n <BModal\n v-if=\"showEventDetails && events\"\n v-model=\"eventModalOpen\"\n class=\"b-calendar__modal\"\n >\n <slot\n v-if=\"$slots.eventDetails && modalDate\"\n name=\"eventDetails\"\n :date=\"modalDate\"\n :events=\"modalEvents\"\n :close=\"closeEventModal\"\n />\n <div v-else-if=\"modalDate\" class=\"b-calendar__modal-body\">\n <header class=\"b-calendar__modal-header\">\n <h3 class=\"b-calendar__modal-title\">{{ modalDateLabel }}</h3>\n <button\n type=\"button\"\n class=\"b-calendar__modal-close\"\n aria-label=\"Close\"\n @click=\"closeEventModal\"\n >\n ×\n </button>\n </header>\n <ul v-if=\"modalEvents.length > 0\" class=\"b-calendar__modal-events\">\n <li\n v-for=\"(ev, idx) in modalEvents\"\n :key=\"idx\"\n class=\"b-calendar__modal-event\"\n :class=\"`b-calendar__modal-event--${ev.type ?? 'default'}`\"\n >\n <span class=\"b-calendar__event-dot\" aria-hidden=\"true\" />\n <div class=\"b-calendar__modal-event-text\">\n <div class=\"b-calendar__modal-event-title\">{{ ev.title }}</div>\n <div\n v-if=\"ev.description\"\n class=\"b-calendar__modal-event-description\"\n >\n {{ ev.description }}\n </div>\n </div>\n </li>\n </ul>\n <p v-else class=\"b-calendar__modal-empty\">No events.</p>\n </div>\n </BModal>\n </section>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BCalendar - tokens scoped to .b-calendar\n ───────────────────────────────────────────── */\n.b-calendar {\n /* ── AntD-aligned tokens ── */\n --b-calendar-full-bg: oklch(100% 0 0);\n --b-calendar-full-panel-bg: oklch(100% 0 0);\n --b-calendar-item-active-bg: oklch(95% 0.04 250);\n --b-calendar-mini-content-height: 256px;\n --b-calendar-month-control-width: 70px;\n --b-calendar-year-control-width: 80px;\n\n /* ── Local extras ── */\n --b-calendar-text-color: oklch(20% 0.005 260 / 88%);\n --b-calendar-text-color-secondary: oklch(45% 0.005 260);\n --b-calendar-text-color-disabled: oklch(50% 0.005 260);\n --b-calendar-border-color: oklch(85% 0.005 260);\n --b-calendar-border-radius: 8px;\n --b-calendar-cell-radius: 4px;\n --b-calendar-primary-color: oklch(54.6% 0.245 262.881);\n --b-calendar-primary-color-text: oklch(100% 0 0);\n --b-calendar-cell-hover-bg: oklch(95% 0.005 260);\n --b-calendar-cell-disabled-bg: oklch(96% 0.002 260);\n --b-calendar-padding: 16px;\n --b-calendar-font-size: 14px;\n --b-calendar-motion-duration: 200ms;\n --b-calendar-focus-ring: 0 0 0 2px oklch(54.6% 0.245 262.881 / 35%);\n\n /* ── Event tokens (WCAG-friendly defaults) ── */\n --b-calendar-event-color-default: oklch(45% 0.005 260);\n --b-calendar-event-color-success: oklch(48% 0.16 145);\n --b-calendar-event-color-info: oklch(50% 0.18 250);\n --b-calendar-event-color-warning: oklch(58% 0.16 75);\n --b-calendar-event-color-error: oklch(48% 0.21 25);\n\n position: relative;\n display: block;\n box-sizing: border-box;\n width: 100%;\n font-family:\n -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: var(--b-calendar-font-size);\n color: var(--b-calendar-text-color);\n background: var(--b-calendar-full-bg);\n border-radius: var(--b-calendar-border-radius);\n}\n\n.b-calendar--fullscreen {\n padding: var(--b-calendar-padding);\n}\n\n.b-calendar--mini {\n padding: 8px;\n border: 1px solid var(--b-calendar-border-color);\n}\n\n/* ── Header ── */\n.b-calendar__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 0 0 12px;\n flex-wrap: wrap;\n}\n\n.b-calendar__header-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.b-calendar__select-wrapper {\n position: relative;\n display: inline-flex;\n align-items: center;\n}\n\n.b-calendar__select-wrapper::after {\n content: '';\n position: absolute;\n right: 8px;\n top: 50%;\n width: 8px;\n height: 8px;\n border: solid var(--b-calendar-text-color-secondary);\n border-width: 0 1.5px 1.5px 0;\n transform: translateY(-75%) rotate(45deg);\n pointer-events: none;\n}\n\n.b-calendar__select {\n appearance: none;\n -webkit-appearance: none;\n height: 28px;\n padding: 0 24px 0 11px;\n border: 1px solid var(--b-calendar-border-color);\n border-radius: var(--b-calendar-cell-radius);\n background-color: var(--b-calendar-full-bg);\n color: inherit;\n font: inherit;\n cursor: pointer;\n transition:\n border-color var(--b-calendar-motion-duration),\n background-color var(--b-calendar-motion-duration);\n}\n\n.b-calendar__select--year {\n min-width: var(--b-calendar-year-control-width);\n}\n\n.b-calendar__select--month {\n min-width: var(--b-calendar-month-control-width);\n}\n\n.b-calendar__select:hover {\n border-color: var(--b-calendar-primary-color);\n}\n\n.b-calendar__select:focus-visible {\n outline: none;\n border-color: var(--b-calendar-primary-color);\n box-shadow: var(--b-calendar-focus-ring);\n}\n\n.b-calendar__mode-switch {\n display: inline-flex;\n gap: 4px;\n}\n\n.b-calendar__mode-option {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 28px;\n padding: 0 14px;\n border: 1px solid var(--b-calendar-border-color);\n border-radius: var(--b-calendar-cell-radius);\n background: transparent;\n cursor: pointer;\n transition:\n border-color var(--b-calendar-motion-duration),\n color var(--b-calendar-motion-duration);\n}\n\n.b-calendar__mode-option:hover {\n color: var(--b-calendar-primary-color);\n border-color: var(--b-calendar-primary-color);\n}\n\n.b-calendar__mode-option--active {\n border-color: var(--b-calendar-primary-color);\n color: var(--b-calendar-primary-color);\n}\n\n.b-calendar__mode-option:has(input:focus-visible) {\n box-shadow: var(--b-calendar-focus-ring);\n}\n\n.b-calendar__today-btn {\n height: 28px;\n padding: 0 12px;\n border: 1px solid var(--b-calendar-border-color);\n border-radius: var(--b-calendar-cell-radius);\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: pointer;\n transition:\n background var(--b-calendar-motion-duration),\n color var(--b-calendar-motion-duration);\n}\n\n.b-calendar__today-btn:hover {\n color: var(--b-calendar-primary-color);\n border-color: var(--b-calendar-primary-color);\n}\n\n.b-calendar__today-btn:focus-visible {\n outline: none;\n border-color: var(--b-calendar-primary-color);\n box-shadow: var(--b-calendar-focus-ring);\n}\n\n/* ── Body / table ── */\n.b-calendar__body {\n background: var(--b-calendar-full-panel-bg);\n}\n\n.b-calendar--mini .b-calendar__body {\n min-height: var(--b-calendar-mini-content-height);\n}\n\n.b-calendar__table {\n width: 100%;\n border-collapse: separate;\n border-spacing: 0;\n table-layout: fixed;\n}\n\n.b-calendar__weekday {\n padding: 8px 12px;\n font-size: 12px;\n font-weight: 500;\n color: var(--b-calendar-text-color-secondary);\n text-align: right;\n}\n\n.b-calendar--mini .b-calendar__weekday {\n text-align: center;\n padding: 8px 0;\n}\n\n.b-calendar__weekday--week {\n width: 32px;\n text-align: center;\n}\n\n.b-calendar__week-number {\n width: 32px;\n text-align: center;\n font-size: 12px;\n color: var(--b-calendar-text-color-disabled);\n vertical-align: top;\n padding-top: 8px;\n}\n\n.b-calendar__cell {\n padding: 0;\n vertical-align: top;\n cursor: pointer;\n}\n\n.b-calendar--mini .b-calendar__cell {\n text-align: center;\n padding: 0;\n}\n\n.b-calendar__cell:focus-visible {\n outline: none;\n}\n\n.b-calendar__cell:focus-visible .b-calendar__date,\n.b-calendar__cell:focus-visible .b-calendar__month {\n box-shadow: var(--b-calendar-focus-ring);\n border-radius: var(--b-calendar-cell-radius);\n}\n\n.b-calendar__cell--outside .b-calendar__date-value {\n color: var(--b-calendar-text-color-disabled);\n}\n\n.b-calendar__cell--today .b-calendar__date,\n.b-calendar__cell--today .b-calendar__month {\n border-top-color: var(--b-calendar-primary-color);\n}\n\n.b-calendar__cell--selected .b-calendar__date,\n.b-calendar__cell--selected .b-calendar__month {\n border-top-color: var(--b-calendar-primary-color);\n background: var(--b-calendar-item-active-bg);\n}\n\n.b-calendar__cell--selected .b-calendar__date-value,\n.b-calendar__cell--selected .b-calendar__month-value {\n color: var(--b-calendar-primary-color);\n font-weight: 600;\n}\n\n.b-calendar__cell--disabled {\n cursor: not-allowed;\n}\n\n.b-calendar__cell--disabled .b-calendar__date,\n.b-calendar__cell--disabled .b-calendar__month {\n background: var(--b-calendar-cell-disabled-bg);\n}\n\n.b-calendar__cell--disabled .b-calendar__date-value,\n.b-calendar__cell--disabled .b-calendar__month-value {\n color: var(--b-calendar-text-color-disabled);\n}\n\n.b-calendar__date {\n height: 116px;\n margin: 0 4px;\n padding: 4px 8px 0;\n display: flex;\n flex-direction: column;\n border-top: 2px solid var(--b-calendar-border-color);\n overflow: hidden;\n transition:\n border-color var(--b-calendar-motion-duration),\n background var(--b-calendar-motion-duration);\n}\n\n.b-calendar__cell:hover:not(.b-calendar__cell--disabled) .b-calendar__date,\n.b-calendar__cell:hover:not(.b-calendar__cell--disabled) .b-calendar__month {\n background: var(--b-calendar-cell-hover-bg);\n}\n\n.b-calendar--mini .b-calendar__date {\n min-height: 24px;\n height: auto;\n margin: 0;\n padding: 4px 0;\n border-top: none;\n align-items: center;\n overflow: visible;\n}\n\n.b-calendar__date-value {\n text-align: right;\n font-size: 14px;\n font-weight: 500;\n line-height: 1.5;\n margin-bottom: 2px;\n}\n\n.b-calendar--mini .b-calendar__date-value {\n text-align: center;\n}\n\n.b-calendar__date-content {\n flex: 1;\n font-size: 12px;\n color: var(--b-calendar-text-color-secondary);\n overflow: hidden;\n min-height: 0;\n}\n\n.b-calendar--mini .b-calendar__date-content {\n display: none;\n}\n\n/* ── Year (month-grid) view ── */\n.b-calendar__table--year .b-calendar__cell--month {\n padding: 0;\n text-align: left;\n}\n\n.b-calendar__month {\n min-height: 116px;\n margin: 0 4px;\n padding: 4px 8px 0;\n display: flex;\n flex-direction: column;\n border-top: 2px solid var(--b-calendar-border-color);\n transition:\n border-color var(--b-calendar-motion-duration),\n background var(--b-calendar-motion-duration);\n}\n\n.b-calendar--mini .b-calendar__month {\n min-height: 36px;\n margin: 0;\n padding: 8px 0;\n border-top: none;\n align-items: center;\n}\n\n.b-calendar__month-value {\n text-align: right;\n font-size: 14px;\n font-weight: 500;\n}\n\n.b-calendar--mini .b-calendar__month-value {\n text-align: center;\n}\n\n.b-calendar__month-content {\n flex: 1;\n font-size: 12px;\n color: var(--b-calendar-text-color-secondary);\n}\n\n.b-calendar--mini .b-calendar__month-content {\n display: none;\n}\n\n/* ── Visually hidden helper ── */\n.b-calendar__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/* ── Events inside day cells ── */\n.b-calendar__events {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.b-calendar__event {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 1px 4px;\n font-size: 12px;\n line-height: 1.4;\n border-radius: 3px;\n color: var(--b-calendar-text-color);\n background: oklch(95% 0.005 260);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.b-calendar__event-dot {\n flex: 0 0 auto;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--b-event-color, var(--b-calendar-event-color-default));\n}\n\n.b-calendar__event--default {\n --b-event-color: var(--b-calendar-event-color-default);\n}\n\n.b-calendar__event--success {\n --b-event-color: var(--b-calendar-event-color-success);\n}\n\n.b-calendar__event--info {\n --b-event-color: var(--b-calendar-event-color-info);\n}\n\n.b-calendar__event--warning {\n --b-event-color: var(--b-calendar-event-color-warning);\n}\n\n.b-calendar__event--error {\n --b-event-color: var(--b-calendar-event-color-error);\n}\n\n.b-calendar__event-title {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.b-calendar__events-more {\n margin-top: 2px;\n padding: 0 4px;\n font-size: 12px;\n font-weight: 500;\n color: var(--b-calendar-text-color-secondary);\n}\n\n/* ── Event details modal ── */\n.b-calendar__modal-body {\n min-width: 320px;\n max-width: 480px;\n color: var(--b-calendar-text-color);\n}\n\n.b-calendar__modal-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.b-calendar__modal-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n}\n\n.b-calendar__modal-close {\n width: 28px;\n height: 28px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: var(--b-calendar-cell-radius);\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n color: inherit;\n transition: background var(--b-calendar-motion-duration);\n}\n\n.b-calendar__modal-close:hover {\n background: var(--b-calendar-cell-hover-bg);\n}\n\n.b-calendar__modal-close:focus-visible {\n outline: none;\n box-shadow: var(--b-calendar-focus-ring);\n}\n\n.b-calendar__modal-events {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.b-calendar__modal-event {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 8px 10px;\n border-radius: var(--b-calendar-cell-radius);\n background: oklch(97% 0.003 260);\n}\n\n.b-calendar__modal-event--default {\n --b-event-color: var(--b-calendar-event-color-default);\n}\n\n.b-calendar__modal-event--success {\n --b-event-color: var(--b-calendar-event-color-success);\n}\n\n.b-calendar__modal-event--info {\n --b-event-color: var(--b-calendar-event-color-info);\n}\n\n.b-calendar__modal-event--warning {\n --b-event-color: var(--b-calendar-event-color-warning);\n}\n\n.b-calendar__modal-event--error {\n --b-event-color: var(--b-calendar-event-color-error);\n}\n\n.b-calendar__modal-event .b-calendar__event-dot {\n width: 10px;\n height: 10px;\n margin-top: 6px;\n}\n\n.b-calendar__modal-event-text {\n flex: 1;\n min-width: 0;\n}\n\n.b-calendar__modal-event-title {\n font-weight: 600;\n color: var(--b-event-color, inherit);\n}\n\n.b-calendar__modal-event-description {\n margin-top: 2px;\n color: var(--b-calendar-text-color-secondary);\n font-size: 13px;\n line-height: 1.5;\n}\n\n.b-calendar__modal-empty {\n margin: 0;\n color: var(--b-calendar-text-color-secondary);\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-calendar {\n --b-calendar-full-bg: oklch(20% 0.005 260);\n --b-calendar-full-panel-bg: oklch(20% 0.005 260);\n --b-calendar-item-active-bg: oklch(35% 0.06 262);\n --b-calendar-text-color: oklch(95% 0 0 / 88%);\n --b-calendar-text-color-secondary: oklch(95% 0 0 / 65%);\n --b-calendar-text-color-disabled: oklch(95% 0 0 / 50%);\n --b-calendar-border-color: oklch(35% 0.005 260);\n --b-calendar-cell-hover-bg: oklch(28% 0.005 260);\n --b-calendar-cell-disabled-bg: oklch(24% 0.005 260);\n --b-calendar-primary-color: oklch(58% 0.22 262);\n --b-calendar-event-color-default: oklch(75% 0.005 260);\n --b-calendar-event-color-success: oklch(72% 0.18 145);\n --b-calendar-event-color-info: oklch(72% 0.18 250);\n --b-calendar-event-color-warning: oklch(80% 0.16 75);\n --b-calendar-event-color-error: oklch(70% 0.21 25);\n}\n\n[data-prefers-color='dark'] .b-calendar__event {\n background: oklch(28% 0.005 260);\n}\n\n[data-prefers-color='dark'] .b-calendar__modal-event {\n background: oklch(25% 0.005 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-calendar {\n --b-calendar-full-bg: oklch(20% 0.005 260);\n --b-calendar-full-panel-bg: oklch(20% 0.005 260);\n --b-calendar-item-active-bg: oklch(35% 0.06 262);\n --b-calendar-text-color: oklch(95% 0 0 / 88%);\n --b-calendar-text-color-secondary: oklch(95% 0 0 / 45%);\n --b-calendar-text-color-disabled: oklch(95% 0 0 / 25%);\n --b-calendar-border-color: oklch(35% 0.005 260);\n --b-calendar-cell-hover-bg: oklch(28% 0.005 260);\n --b-calendar-cell-disabled-bg: oklch(24% 0.005 260);\n --b-calendar-primary-color: oklch(58% 0.22 262);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-calendar,\n .b-calendar__select,\n .b-calendar__cell,\n .b-calendar__mode-option,\n .b-calendar__today-btn {\n transition: none !important;\n }\n}\n</style>\n"],"mappings":""}
@@ -1,29 +1,147 @@
1
- import { createCommentVNode as e, createElementBlock as t, createTextVNode as n, defineComponent as r, openBlock as i, renderSlot as a, toDisplayString as o, unref as s, useSlots as c } from "vue";
2
- //#region src/components/BCard/BCardMeta.vue?vue&type=script&setup=true&lang.ts
3
- var l = { class: "b-card-meta" }, u = {
1
+ import { BCardSize as e, BCardType as t } from "./design-system3.js";
2
+ import { Fragment as n, computed as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, defineComponent as c, mergeProps as l, normalizeClass as u, normalizeStyle as d, openBlock as f, ref as p, renderList as m, renderSlot as h, toDisplayString as g, unref as _, useId as v, useSlots as y, watch as b } from "vue";
3
+ //#region src/components/BCard/BCard.vue?vue&type=script&setup=true&lang.ts
4
+ var x = {
4
5
  key: 0,
5
- class: "b-card-meta__avatar"
6
- }, d = {
6
+ class: "b-card__cover"
7
+ }, S = {
7
8
  key: 1,
8
- class: "b-card-meta__detail"
9
- }, f = {
9
+ class: "b-card__head"
10
+ }, C = { class: "b-card__head-wrapper" }, w = {
10
11
  key: 0,
11
- class: "b-card-meta__title"
12
- }, p = {
12
+ class: "b-card__head-title"
13
+ }, T = {
13
14
  key: 1,
14
- class: "b-card-meta__description"
15
- }, m = /* @__PURE__ */ r({
16
- __name: "BCardMeta",
15
+ class: "b-card__extra"
16
+ }, E = {
17
+ key: 0,
18
+ class: "b-card__tabs"
19
+ }, D = ["aria-label"], O = [
20
+ "id",
21
+ "aria-selected",
22
+ "aria-controls",
23
+ "tabindex",
24
+ "disabled",
25
+ "onClick",
26
+ "onKeydown"
27
+ ], k = {
28
+ key: 0,
29
+ class: "b-card__tab-extra"
30
+ }, A = [
31
+ "id",
32
+ "role",
33
+ "aria-labelledby"
34
+ ], j = {
35
+ key: 0,
36
+ class: "b-card__loading",
37
+ role: "status",
38
+ "aria-busy": "true",
39
+ "aria-label": "Loading card content"
40
+ }, M = {
41
+ key: 2,
42
+ class: "b-card__actions",
43
+ role: "group",
44
+ "aria-label": "Card actions"
45
+ }, N = /* @__PURE__ */ c({
46
+ __name: "BCard",
17
47
  props: {
48
+ bordered: {
49
+ type: Boolean,
50
+ default: !0
51
+ },
52
+ hoverable: {
53
+ type: Boolean,
54
+ default: !1
55
+ },
56
+ loading: {
57
+ type: Boolean,
58
+ default: !1
59
+ },
60
+ size: { default: () => e.Default },
61
+ type: { default: () => t.Default },
18
62
  title: {},
19
- description: {}
63
+ extra: {},
64
+ tabList: {},
65
+ activeTabKey: {},
66
+ defaultActiveTabKey: {},
67
+ tabBarExtraContent: {},
68
+ tabProps: {}
20
69
  },
21
- setup(r) {
22
- let m = c();
23
- return (c, h) => (i(), t("div", l, [s(m).avatar ? (i(), t("div", u, [a(c.$slots, "avatar")])) : e("", !0), r.title || s(m).title || r.description || s(m).description ? (i(), t("div", d, [r.title || s(m).title ? (i(), t("div", f, [a(c.$slots, "title", {}, () => [n(o(r.title), 1)])])) : e("", !0), r.description || s(m).description ? (i(), t("div", p, [a(c.$slots, "description", {}, () => [n(o(r.description), 1)])])) : e("", !0)])) : e("", !0)]));
70
+ emits: ["tabChange", "update:activeTabKey"],
71
+ setup(c, { emit: N }) {
72
+ let P = N, F = y(), I = v(), L = p(c.defaultActiveTabKey ?? (c.tabList && c.tabList.length > 0 ? c.tabList[0].key : "")), R = r(() => c.activeTabKey === void 0 ? L.value : c.activeTabKey);
73
+ b(() => c.activeTabKey, (e) => {
74
+ e !== void 0 && (L.value = e);
75
+ });
76
+ let z = r(() => !!(c.title || F.title || c.extra || F.extra || c.tabList && c.tabList.length > 0)), B = r(() => ["b-card", {
77
+ "b-card--bordered": c.bordered,
78
+ "b-card--hoverable": c.hoverable,
79
+ "b-card--loading": c.loading,
80
+ "b-card--small": c.size === e.Small,
81
+ "b-card--inner": c.type === t.Inner,
82
+ "b-card--has-tabs": c.tabList && c.tabList.length > 0,
83
+ "b-card--has-cover": !!F.cover,
84
+ "b-card--has-actions": !!F.actions
85
+ }]), V = r(() => `${I}-tabpanel`);
86
+ function H(e) {
87
+ L.value = e, P("update:activeTabKey", e), P("tabChange", e);
88
+ }
89
+ function U(e, t) {
90
+ if (!c.tabList) return;
91
+ let n = c.tabList.filter((e) => !e.disabled), r = n.findIndex((e) => e.key === c.tabList[t].key);
92
+ if (r === -1) return;
93
+ let i = -1;
94
+ if (e.key === "ArrowRight" || e.key === "ArrowDown" ? (e.preventDefault(), i = (r + 1) % n.length) : e.key === "ArrowLeft" || e.key === "ArrowUp" ? (e.preventDefault(), i = (r - 1 + n.length) % n.length) : e.key === "Home" ? (e.preventDefault(), i = 0) : e.key === "End" && (e.preventDefault(), i = n.length - 1), i >= 0) {
95
+ let e = n[i].key;
96
+ H(e), document.getElementById(`${I}-tab-${e}`)?.focus();
97
+ }
98
+ }
99
+ let W = [
100
+ 100,
101
+ 75,
102
+ 90,
103
+ 60
104
+ ];
105
+ return (e, t) => (f(), a("div", { class: u(B.value) }, [
106
+ e.$slots.cover ? (f(), a("div", x, [h(e.$slots, "cover")])) : i("", !0),
107
+ z.value ? (f(), a("div", S, [o("div", C, [c.title || e.$slots.title ? (f(), a("div", w, [h(e.$slots, "title", {}, () => [s(g(c.title), 1)])])) : i("", !0), c.extra || e.$slots.extra ? (f(), a("div", T, [h(e.$slots, "extra", {}, () => [s(g(c.extra), 1)])])) : i("", !0)]), c.tabList && c.tabList.length > 0 ? (f(), a("div", E, [o("div", {
108
+ role: "tablist",
109
+ class: "b-card__tab-list",
110
+ "aria-label": c.title ? `${c.title} tabs` : "Card tabs"
111
+ }, [(f(!0), a(n, null, m(c.tabList, (t, n) => (f(), a("button", l({
112
+ id: `${_(I)}-tab-${t.key}`,
113
+ key: t.key,
114
+ role: "tab",
115
+ class: ["b-card__tab", {
116
+ "b-card__tab--active": R.value === t.key,
117
+ "b-card__tab--disabled": t.disabled
118
+ }],
119
+ "aria-selected": R.value === t.key,
120
+ "aria-controls": V.value,
121
+ tabindex: R.value === t.key ? 0 : -1,
122
+ disabled: t.disabled
123
+ }, { ref_for: !0 }, c.tabProps, {
124
+ onClick: (e) => H(t.key),
125
+ onKeydown: (e) => U(e, n)
126
+ }), [h(e.$slots, "customTab", {
127
+ item: t,
128
+ isActive: R.value === t.key
129
+ }, () => [s(g(t.tab), 1)])], 16, O))), 128))], 8, D), c.tabBarExtraContent || e.$slots.tabBarExtraContent ? (f(), a("div", k, [h(e.$slots, "tabBarExtraContent", {}, () => [s(g(c.tabBarExtraContent), 1)])])) : i("", !0)])) : i("", !0)])) : i("", !0),
130
+ o("div", {
131
+ class: "b-card__body",
132
+ id: c.tabList && c.tabList.length > 0 ? V.value : void 0,
133
+ role: c.tabList && c.tabList.length > 0 ? "tabpanel" : void 0,
134
+ "aria-labelledby": c.tabList && c.tabList.length > 0 ? `${_(I)}-tab-${R.value}` : void 0
135
+ }, [c.loading ? (f(), a("div", j, [(f(), a(n, null, m(W, (e, t) => o("div", {
136
+ key: t,
137
+ class: "b-card__loading-line",
138
+ style: d({ width: `${e}%` })
139
+ }, null, 4)), 64))])) : h(e.$slots, "default", { key: 1 })], 8, A),
140
+ e.$slots.actions ? (f(), a("div", M, [h(e.$slots, "actions")])) : i("", !0)
141
+ ], 2));
24
142
  }
25
143
  });
26
144
  //#endregion
27
- export { m as default };
145
+ export { N as default };
28
146
 
29
147
  //# sourceMappingURL=design-system36.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"design-system36.js","names":[],"sources":["../src/components/BCard/BCardMeta.vue?vue&type=script&setup=true&lang.ts"],"sourcesContent":["import { defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, renderSlot as _renderSlot, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode } from \"vue\"\n\nconst _hoisted_1 = { class: \"b-card-meta\" }\nconst _hoisted_2 = {\n key: 0,\n class: \"b-card-meta__avatar\"\n}\nconst _hoisted_3 = {\n key: 1,\n class: \"b-card-meta__detail\"\n}\nconst _hoisted_4 = {\n key: 0,\n class: \"b-card-meta__title\"\n}\nconst _hoisted_5 = {\n key: 1,\n class: \"b-card-meta__description\"\n}\n\nimport { useSlots } from 'vue';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\n\nexport default /*@__PURE__*/_defineComponent({\n __name: 'BCardMeta',\n props: {\n title: {},\n description: {}\n },\n setup(__props: any) {\n\n\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\n\n\nconst slots = useSlots();\n\nreturn (_ctx: any,_cache: any) => {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_unref(slots).avatar)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_2, [\n _renderSlot(_ctx.$slots, \"avatar\")\n ]))\n : _createCommentVNode(\"\", true),\n (__props.title || _unref(slots).title || __props.description || _unref(slots).description)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_3, [\n (__props.title || _unref(slots).title)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_4, [\n _renderSlot(_ctx.$slots, \"title\", {}, () => [\n _createTextVNode(_toDisplayString(__props.title), 1)\n ])\n ]))\n : _createCommentVNode(\"\", true),\n (__props.description || _unref(slots).description)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_5, [\n _renderSlot(_ctx.$slots, \"description\", {}, () => [\n _createTextVNode(_toDisplayString(__props.description), 1)\n ])\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n : _createCommentVNode(\"\", true)\n ]))\n}\n}\n\n})"],"mappings":";;AAGA,IAAM,IAAa,EAAE,OAAO,eAAe,EACrC,IAAa;CACjB,KAAK;CACL,OAAO;CACR,EACK,IAAa;CACjB,KAAK;CACL,OAAO;CACR,EACK,IAAa;CACjB,KAAK;CACL,OAAO;CACR,EACK,IAAa;CACjB,KAAK;CACL,OAAO;CACR,EAQD,IAA4B,kBAAiB;CAC3C,QAAQ;CACR,OAAO;EACL,OAAO,EAAE;EACT,aAAa,EAAE;EAChB;CACD,MAAM,GAAc;EAStB,IAAM,IAAQ,GAAU;AAExB,UAAQ,GAAU,OACR,GAAY,EAAE,EAAoB,OAAO,GAAY,CAC1D,EAAO,EAAM,CAAC,UACV,GAAY,EAAE,EAAoB,OAAO,GAAY,CACpD,EAAY,EAAK,QAAQ,SAAS,CACnC,CAAC,IACF,EAAoB,IAAI,GAAK,EAChC,EAAQ,SAAS,EAAO,EAAM,CAAC,SAAS,EAAQ,eAAe,EAAO,EAAM,CAAC,eACzE,GAAY,EAAE,EAAoB,OAAO,GAAY,CACnD,EAAQ,SAAS,EAAO,EAAM,CAAC,SAC3B,GAAY,EAAE,EAAoB,OAAO,GAAY,CACpD,EAAY,EAAK,QAAQ,SAAS,EAAE,QAAQ,CAC1C,EAAiB,EAAiB,EAAQ,MAAM,EAAE,EAAE,CACrD,CAAC,CACH,CAAC,IACF,EAAoB,IAAI,GAAK,EAChC,EAAQ,eAAe,EAAO,EAAM,CAAC,eACjC,GAAY,EAAE,EAAoB,OAAO,GAAY,CACpD,EAAY,EAAK,QAAQ,eAAe,EAAE,QAAQ,CAChD,EAAiB,EAAiB,EAAQ,YAAY,EAAE,EAAE,CAC3D,CAAC,CACH,CAAC,IACF,EAAoB,IAAI,GAAK,CAClC,CAAC,IACF,EAAoB,IAAI,GAAK,CAClC,CAAC;;CAIH,CAAA"}
1
+ {"version":3,"file":"design-system36.js","names":["$slots"],"sources":["../src/components/BCard/BCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useId, useSlots, watch } from 'vue';\n\nimport type { BCardTabItem } from '@/types';\nimport { BCardSize, BCardType } from '@/types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n bordered = true,\n hoverable = false,\n loading = false,\n size = BCardSize.Default,\n type = BCardType.Default,\n title,\n extra,\n tabList,\n activeTabKey,\n defaultActiveTabKey,\n tabBarExtraContent,\n tabProps,\n} = defineProps<{\n /** Whether to render the card border. @default true */\n bordered?: boolean;\n /** Lift the card on hover. @default false */\n hoverable?: boolean;\n /** Shows a placeholder while content is loading. @default false */\n loading?: boolean;\n /** Size of the card. @default 'default' */\n size?: `${BCardSize}`;\n /** Card type: default or inner. @default 'default' */\n type?: `${BCardType}`;\n /** Card title */\n title?: string;\n /** Content to render in the top-right corner of the card */\n extra?: string;\n /** List of tabs at the top of the card */\n tabList?: BCardTabItem[];\n /** Active tab key (controlled). Use with v-model:activeTabKey */\n activeTabKey?: string;\n /** Default active tab key (uncontrolled) */\n defaultActiveTabKey?: string;\n /** Extra content in the tab bar */\n tabBarExtraContent?: string;\n /** Additional HTML attributes to pass to the tab buttons */\n tabProps?: Record<string, unknown>;\n}>();\n\n// ─────────────────────────────────────────────\n// Emits\n// ─────────────────────────────────────────────\nconst emit = defineEmits<{\n /** Fired when the active tab changes */\n (e: 'tabChange', key: string): void;\n /** Sync active tab key for v-model:activeTabKey */\n (e: 'update:activeTabKey', key: string): void;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Main content of the card */\n default?: (props: Record<string, never>) => unknown;\n /** Card title area. Overrides the `title` prop */\n title?: (props: Record<string, never>) => unknown;\n /** Extra content in the top-right corner. Overrides the `extra` prop */\n extra?: (props: Record<string, never>) => unknown;\n /** Cover image/content above the card body */\n cover?: (props: Record<string, never>) => unknown;\n /** Action items rendered at the card footer */\n actions?: (props: Record<string, never>) => unknown;\n /** Tab bar extra content slot. Overrides the `tabBarExtraContent` prop */\n tabBarExtraContent?: (props: Record<string, never>) => unknown;\n /** Custom tab rendering. Receives { item: BCardTabItem, isActive: boolean } */\n customTab?: (props: { item: BCardTabItem; isActive: boolean }) => unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst slots = useSlots();\nconst cardId = useId();\n\nconst internalActiveTab = ref(\n defaultActiveTabKey ?? (tabList && tabList.length > 0 ? tabList[0].key : ''),\n);\n\nconst currentTabKey = computed(() =>\n activeTabKey !== undefined ? activeTabKey : internalActiveTab.value,\n);\n\nwatch(\n () => activeTabKey,\n (val) => {\n if (val !== undefined) {\n internalActiveTab.value = val;\n }\n },\n);\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst hasHeader = computed(() => {\n return !!(title || slots.title || extra || slots.extra || (tabList && tabList.length > 0));\n});\n\nconst rootClasses = computed(() => [\n 'b-card',\n {\n 'b-card--bordered': bordered,\n 'b-card--hoverable': hoverable,\n 'b-card--loading': loading,\n 'b-card--small': size === BCardSize.Small,\n 'b-card--inner': type === BCardType.Inner,\n 'b-card--has-tabs': tabList && tabList.length > 0,\n 'b-card--has-cover': !!slots.cover,\n 'b-card--has-actions': !!slots.actions,\n },\n]);\n\nconst tabPanelId = computed(() => `${cardId}-tabpanel`);\n\n// ─────────────────────────────────────────────\n// Tab handling\n// ─────────────────────────────────────────────\nfunction handleTabClick(key: string) {\n internalActiveTab.value = key;\n emit('update:activeTabKey', key);\n emit('tabChange', key);\n}\n\nfunction handleTabKeydown(event: KeyboardEvent, index: number) {\n if (!tabList) return;\n const enabledTabs = tabList.filter((t) => !t.disabled);\n const currentEnabled = enabledTabs.findIndex((t) => t.key === tabList[index].key);\n if (currentEnabled === -1) return;\n\n let targetIndex = -1;\n\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n targetIndex = (currentEnabled + 1) % enabledTabs.length;\n } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n targetIndex = (currentEnabled - 1 + enabledTabs.length) % enabledTabs.length;\n } else if (event.key === 'Home') {\n event.preventDefault();\n targetIndex = 0;\n } else if (event.key === 'End') {\n event.preventDefault();\n targetIndex = enabledTabs.length - 1;\n }\n\n if (targetIndex >= 0) {\n const targetKey = enabledTabs[targetIndex].key;\n handleTabClick(targetKey);\n const tabEl = document.getElementById(`${cardId}-tab-${targetKey}`);\n tabEl?.focus();\n }\n}\n\n// ─────────────────────────────────────────────\n// Loading skeleton lines\n// ─────────────────────────────────────────────\nconst skeletonRows = [100, 75, 90, 60];\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <!-- Cover -->\n <div v-if=\"$slots.cover\" class=\"b-card__cover\">\n <slot name=\"cover\" />\n </div>\n\n <!-- Header -->\n <div v-if=\"hasHeader\" class=\"b-card__head\">\n <div class=\"b-card__head-wrapper\">\n <div v-if=\"title || $slots.title\" class=\"b-card__head-title\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"extra || $slots.extra\" class=\"b-card__extra\">\n <slot name=\"extra\">{{ extra }}</slot>\n </div>\n </div>\n\n <!-- Tabs -->\n <div v-if=\"tabList && tabList.length > 0\" class=\"b-card__tabs\">\n <div\n role=\"tablist\"\n class=\"b-card__tab-list\"\n :aria-label=\"title ? `${title} tabs` : 'Card tabs'\"\n >\n <button\n v-for=\"(tab, index) in tabList\"\n :id=\"`${cardId}-tab-${tab.key}`\"\n :key=\"tab.key\"\n role=\"tab\"\n class=\"b-card__tab\"\n :class=\"{\n 'b-card__tab--active': currentTabKey === tab.key,\n 'b-card__tab--disabled': tab.disabled,\n }\"\n :aria-selected=\"currentTabKey === tab.key\"\n :aria-controls=\"tabPanelId\"\n :tabindex=\"currentTabKey === tab.key ? 0 : -1\"\n :disabled=\"tab.disabled\"\n v-bind=\"tabProps\"\n @click=\"handleTabClick(tab.key)\"\n @keydown=\"handleTabKeydown($event, index)\"\n >\n <slot name=\"customTab\" :item=\"tab\" :is-active=\"currentTabKey === tab.key\">\n {{ tab.tab }}\n </slot>\n </button>\n </div>\n <div v-if=\"tabBarExtraContent || $slots.tabBarExtraContent\" class=\"b-card__tab-extra\">\n <slot name=\"tabBarExtraContent\">{{ tabBarExtraContent }}</slot>\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div\n class=\"b-card__body\"\n :id=\"tabList && tabList.length > 0 ? tabPanelId : undefined\"\n :role=\"tabList && tabList.length > 0 ? 'tabpanel' : undefined\"\n :aria-labelledby=\"\n tabList && tabList.length > 0 ? `${cardId}-tab-${currentTabKey}` : undefined\n \"\n >\n <!-- Loading skeleton -->\n <div\n v-if=\"loading\"\n class=\"b-card__loading\"\n role=\"status\"\n aria-busy=\"true\"\n aria-label=\"Loading card content\"\n >\n <div\n v-for=\"(width, i) in skeletonRows\"\n :key=\"i\"\n class=\"b-card__loading-line\"\n :style=\"{ width: `${width}%` }\"\n />\n </div>\n\n <!-- Content -->\n <template v-else>\n <slot />\n </template>\n </div>\n\n <!-- Actions -->\n <div v-if=\"$slots.actions\" class=\"b-card__actions\" role=\"group\" aria-label=\"Card actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BCard - CSS custom properties (scoped to root)\n ───────────────────────────────────────────── */\n.b-card {\n /* Surface */\n --b-card-bg: oklch(100% 0 0);\n --b-card-color: oklch(20% 0.02 260);\n --b-card-border-radius: 8px;\n --b-card-border-color: oklch(85% 0.01 260);\n --b-card-border-width: 1px;\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 6%), 0 1px 3px 0 oklch(0% 0 0 / 10%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 12%);\n --b-card-transition-duration: 200ms;\n\n /* Head */\n --b-card-head-padding: 16px 24px;\n --b-card-head-padding-sm: 8px 16px;\n --b-card-head-font-size: 16px;\n --b-card-head-font-size-sm: 14px;\n --b-card-head-font-weight: 600;\n --b-card-head-color: oklch(20% 0.02 260);\n --b-card-head-border-color: oklch(90% 0.01 260);\n --b-card-head-min-height: 56px;\n --b-card-head-min-height-sm: 40px;\n\n /* Body */\n --b-card-body-padding: 24px;\n --b-card-body-padding-sm: 16px;\n\n /* Extra */\n --b-card-extra-color: oklch(45% 0.02 260);\n --b-card-extra-font-size: 14px;\n\n /* Cover */\n --b-card-cover-border-radius: var(--b-card-border-radius) var(--b-card-border-radius) 0 0;\n\n /* Actions */\n --b-card-actions-padding: 12px 24px;\n --b-card-actions-border-color: oklch(90% 0.01 260);\n --b-card-actions-bg: transparent;\n\n /* Tabs */\n --b-card-tab-color: oklch(45% 0.02 260);\n --b-card-tab-active-color: oklch(46% 0.24 264);\n --b-card-tab-hover-color: oklch(46% 0.24 264);\n --b-card-tab-disabled-color: oklch(70% 0.01 260);\n --b-card-tab-bar-border-color: oklch(90% 0.01 260);\n --b-card-tab-indicator-color: oklch(46% 0.24 264);\n --b-card-tab-font-size: 14px;\n --b-card-tab-padding: 12px 16px;\n\n /* Inner card */\n --b-card-inner-bg: oklch(97% 0 0);\n\n /* Loading */\n --b-card-loading-line-bg: oklch(92% 0.01 260);\n --b-card-loading-shine-color: oklch(96% 0 0);\n --b-card-loading-line-height: 16px;\n --b-card-loading-line-radius: 4px;\n --b-card-loading-gap: 12px;\n\n /* Layout */\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--b-card-bg);\n color: var(--b-card-color);\n border-radius: var(--b-card-border-radius);\n font-size: 14px;\n line-height: 1.5715;\n box-sizing: border-box;\n transition:\n box-shadow var(--b-card-transition-duration) ease,\n border-color var(--b-card-transition-duration) ease;\n}\n\n/* ── Border ── */\n.b-card--bordered {\n border: var(--b-card-border-width) solid var(--b-card-border-color);\n}\n\n.b-card:not(.b-card--bordered) {\n box-shadow: var(--b-card-shadow);\n}\n\n/* ── Hoverable ── */\n.b-card--hoverable {\n cursor: pointer;\n}\n\n.b-card--hoverable:hover {\n box-shadow: var(--b-card-shadow-hover);\n}\n\n.b-card--bordered.b-card--hoverable:hover {\n border-color: transparent;\n box-shadow: var(--b-card-shadow-hover);\n}\n\n/* ── Inner card ── */\n.b-card--inner {\n background: var(--b-card-inner-bg);\n}\n\n/* ── Small size ── */\n.b-card--small .b-card__head {\n padding: var(--b-card-head-padding-sm);\n min-height: var(--b-card-head-min-height-sm);\n font-size: var(--b-card-head-font-size-sm);\n}\n\n.b-card--small .b-card__body {\n padding: var(--b-card-body-padding-sm);\n}\n\n/* ── Cover ── */\n.b-card__cover {\n overflow: hidden;\n border-radius: var(--b-card-cover-border-radius);\n}\n\n.b-card--bordered .b-card__cover {\n margin-top: -1px;\n margin-inline: -1px;\n}\n\n.b-card__cover img,\n.b-card__cover video {\n display: block;\n width: 100%;\n height: auto;\n}\n\n/* ── Head ── */\n.b-card__head {\n display: flex;\n flex-direction: column;\n padding: var(--b-card-head-padding);\n border-bottom: 1px solid var(--b-card-head-border-color);\n min-height: var(--b-card-head-min-height);\n font-size: var(--b-card-head-font-size);\n box-sizing: border-box;\n}\n\n.b-card--has-tabs .b-card__head {\n padding-bottom: 0;\n border-bottom: none;\n}\n\n.b-card__head-wrapper {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.b-card__head-title {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: var(--b-card-head-font-weight);\n color: var(--b-card-head-color);\n}\n\n.b-card__extra {\n flex: none;\n color: var(--b-card-extra-color);\n font-size: var(--b-card-extra-font-size);\n font-weight: 400;\n}\n\n/* ── Tabs ── */\n.b-card__tabs {\n display: flex;\n align-items: center;\n justify-content: space-between;\n border-bottom: 1px solid var(--b-card-tab-bar-border-color);\n margin-top: 4px;\n}\n\n.b-card__tab-list {\n display: flex;\n gap: 0;\n}\n\n.b-card__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--b-card-tab-padding);\n border: none;\n background: none;\n color: var(--b-card-tab-color);\n font-size: var(--b-card-tab-font-size);\n font-family: inherit;\n cursor: pointer;\n transition: color var(--b-card-transition-duration) ease;\n outline: none;\n}\n\n.b-card__tab::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 50%;\n width: 0;\n height: 2px;\n background: var(--b-card-tab-indicator-color);\n border-radius: 1px;\n transition:\n width var(--b-card-transition-duration) ease,\n left var(--b-card-transition-duration) ease;\n}\n\n.b-card__tab:hover:not(:disabled) {\n color: var(--b-card-tab-hover-color);\n}\n\n.b-card__tab:focus-visible {\n outline: 2px solid var(--b-card-tab-active-color);\n outline-offset: -2px;\n border-radius: 4px;\n}\n\n.b-card__tab--active {\n color: var(--b-card-tab-active-color);\n font-weight: 500;\n}\n\n.b-card__tab--active::after {\n width: 100%;\n left: 0;\n}\n\n.b-card__tab--disabled {\n color: var(--b-card-tab-disabled-color);\n cursor: not-allowed;\n}\n\n.b-card__tab-extra {\n flex: none;\n padding: 0 16px;\n color: var(--b-card-extra-color);\n font-size: var(--b-card-extra-font-size);\n}\n\n/* ── Body ── */\n.b-card__body {\n flex: 1;\n padding: var(--b-card-body-padding);\n}\n\n/* ── Actions ── */\n.b-card__actions {\n display: flex;\n align-items: center;\n justify-content: space-evenly;\n padding: var(--b-card-actions-padding);\n border-top: 1px solid var(--b-card-actions-border-color);\n background: var(--b-card-actions-bg);\n border-radius: 0 0 var(--b-card-border-radius) var(--b-card-border-radius);\n}\n\n/* ── Loading skeleton ── */\n.b-card__loading {\n display: flex;\n flex-direction: column;\n gap: var(--b-card-loading-gap);\n}\n\n.b-card__loading-line {\n height: var(--b-card-loading-line-height);\n border-radius: var(--b-card-loading-line-radius);\n background: linear-gradient(\n 90deg,\n var(--b-card-loading-line-bg) 25%,\n var(--b-card-loading-shine-color) 50%,\n var(--b-card-loading-line-bg) 75%\n );\n background-size: 200% 100%;\n animation: b-card-loading-shimmer 1.5s infinite ease-in-out;\n}\n\n@keyframes b-card-loading-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card {\n --b-card-bg: oklch(20% 0.02 260);\n --b-card-color: oklch(88% 0.01 260);\n --b-card-border-color: oklch(35% 0.02 260);\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 20%), 0 1px 3px 0 oklch(0% 0 0 / 25%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n --b-card-head-color: oklch(92% 0.01 260);\n --b-card-head-border-color: oklch(35% 0.02 260);\n --b-card-extra-color: oklch(65% 0.01 260);\n --b-card-tab-color: oklch(65% 0.01 260);\n --b-card-tab-active-color: oklch(70% 0.18 264);\n --b-card-tab-hover-color: oklch(70% 0.18 264);\n --b-card-tab-disabled-color: oklch(40% 0.01 260);\n --b-card-tab-bar-border-color: oklch(35% 0.02 260);\n --b-card-tab-indicator-color: oklch(70% 0.18 264);\n --b-card-actions-border-color: oklch(35% 0.02 260);\n --b-card-inner-bg: oklch(25% 0.02 260);\n --b-card-loading-line-bg: oklch(30% 0.02 260);\n --b-card-loading-shine-color: oklch(35% 0.02 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card {\n --b-card-bg: oklch(20% 0.02 260);\n --b-card-color: oklch(88% 0.01 260);\n --b-card-border-color: oklch(35% 0.02 260);\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 20%), 0 1px 3px 0 oklch(0% 0 0 / 25%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n --b-card-head-color: oklch(92% 0.01 260);\n --b-card-head-border-color: oklch(35% 0.02 260);\n --b-card-extra-color: oklch(65% 0.01 260);\n --b-card-tab-color: oklch(65% 0.01 260);\n --b-card-tab-active-color: oklch(70% 0.18 264);\n --b-card-tab-hover-color: oklch(70% 0.18 264);\n --b-card-tab-disabled-color: oklch(40% 0.01 260);\n --b-card-tab-bar-border-color: oklch(35% 0.02 260);\n --b-card-tab-indicator-color: oklch(70% 0.18 264);\n --b-card-actions-border-color: oklch(35% 0.02 260);\n --b-card-inner-bg: oklch(25% 0.02 260);\n --b-card-loading-line-bg: oklch(30% 0.02 260);\n --b-card-loading-shine-color: oklch(35% 0.02 260);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-card {\n --b-card-transition-duration: 0ms;\n }\n\n .b-card__loading-line {\n animation: none;\n }\n}\n</style>\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import e from "./design-system36.js";
2
2
  /* empty css */
3
- //#region src/components/BCard/BCardMeta.vue
3
+ //#region src/components/BCard/BCard.vue
4
4
  var t = e;
5
5
  //#endregion
6
6
  export { t as default };
@@ -1 +1 @@
1
- {"version":3,"file":"design-system38.js","names":[],"sources":["../src/components/BCard/BCardMeta.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { useSlots } from 'vue';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst { title, description } = defineProps<{\n /** Title of the meta section */\n title?: string;\n /** Description text below the title */\n description?: string;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Avatar or icon to the left of the meta content */\n avatar?: (props: Record<string, never>) => unknown;\n /** Custom title content. Overrides the `title` prop */\n title?: (props: Record<string, never>) => unknown;\n /** Custom description content. Overrides the `description` prop */\n description?: (props: Record<string, never>) => unknown;\n}>();\n\nconst slots = useSlots();\n</script>\n\n<template>\n <div class=\"b-card-meta\">\n <div v-if=\"slots.avatar\" class=\"b-card-meta__avatar\">\n <slot name=\"avatar\" />\n </div>\n <div\n v-if=\"title || slots.title || description || slots.description\"\n class=\"b-card-meta__detail\"\n >\n <div v-if=\"title || slots.title\" class=\"b-card-meta__title\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"description || slots.description\" class=\"b-card-meta__description\">\n <slot name=\"description\">{{ description }}</slot>\n </div>\n </div>\n </div>\n</template>\n\n<style>\n.b-card-meta {\n --b-card-meta-title-font-size: 16px;\n --b-card-meta-title-font-weight: 500;\n --b-card-meta-title-color: oklch(20% 0.02 260);\n --b-card-meta-description-font-size: 14px;\n --b-card-meta-description-color: oklch(45% 0.02 260);\n --b-card-meta-avatar-margin-right: 16px;\n\n display: flex;\n align-items: flex-start;\n}\n\n.b-card-meta__avatar {\n flex: none;\n margin-right: var(--b-card-meta-avatar-margin-right);\n}\n\n.b-card-meta__detail {\n flex: 1;\n overflow: hidden;\n}\n\n.b-card-meta__title {\n font-size: var(--b-card-meta-title-font-size);\n font-weight: var(--b-card-meta-title-font-weight);\n color: var(--b-card-meta-title-color);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.b-card-meta__description {\n font-size: var(--b-card-meta-description-font-size);\n color: var(--b-card-meta-description-color);\n margin-top: 4px;\n line-height: 1.5;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card-meta {\n --b-card-meta-title-color: oklch(92% 0.01 260);\n --b-card-meta-description-color: oklch(65% 0.01 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card-meta {\n --b-card-meta-title-color: oklch(92% 0.01 260);\n --b-card-meta-description-color: oklch(65% 0.01 260);\n }\n}\n</style>\n"],"mappings":""}
1
+ {"version":3,"file":"design-system38.js","names":[],"sources":["../src/components/BCard/BCard.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref, useId, useSlots, watch } from 'vue';\n\nimport type { BCardTabItem } from '@/types';\nimport { BCardSize, BCardType } from '@/types';\n\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst {\n bordered = true,\n hoverable = false,\n loading = false,\n size = BCardSize.Default,\n type = BCardType.Default,\n title,\n extra,\n tabList,\n activeTabKey,\n defaultActiveTabKey,\n tabBarExtraContent,\n tabProps,\n} = defineProps<{\n /** Whether to render the card border. @default true */\n bordered?: boolean;\n /** Lift the card on hover. @default false */\n hoverable?: boolean;\n /** Shows a placeholder while content is loading. @default false */\n loading?: boolean;\n /** Size of the card. @default 'default' */\n size?: `${BCardSize}`;\n /** Card type: default or inner. @default 'default' */\n type?: `${BCardType}`;\n /** Card title */\n title?: string;\n /** Content to render in the top-right corner of the card */\n extra?: string;\n /** List of tabs at the top of the card */\n tabList?: BCardTabItem[];\n /** Active tab key (controlled). Use with v-model:activeTabKey */\n activeTabKey?: string;\n /** Default active tab key (uncontrolled) */\n defaultActiveTabKey?: string;\n /** Extra content in the tab bar */\n tabBarExtraContent?: string;\n /** Additional HTML attributes to pass to the tab buttons */\n tabProps?: Record<string, unknown>;\n}>();\n\n// ─────────────────────────────────────────────\n// Emits\n// ─────────────────────────────────────────────\nconst emit = defineEmits<{\n /** Fired when the active tab changes */\n (e: 'tabChange', key: string): void;\n /** Sync active tab key for v-model:activeTabKey */\n (e: 'update:activeTabKey', key: string): void;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Main content of the card */\n default?: (props: Record<string, never>) => unknown;\n /** Card title area. Overrides the `title` prop */\n title?: (props: Record<string, never>) => unknown;\n /** Extra content in the top-right corner. Overrides the `extra` prop */\n extra?: (props: Record<string, never>) => unknown;\n /** Cover image/content above the card body */\n cover?: (props: Record<string, never>) => unknown;\n /** Action items rendered at the card footer */\n actions?: (props: Record<string, never>) => unknown;\n /** Tab bar extra content slot. Overrides the `tabBarExtraContent` prop */\n tabBarExtraContent?: (props: Record<string, never>) => unknown;\n /** Custom tab rendering. Receives { item: BCardTabItem, isActive: boolean } */\n customTab?: (props: { item: BCardTabItem; isActive: boolean }) => unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst slots = useSlots();\nconst cardId = useId();\n\nconst internalActiveTab = ref(\n defaultActiveTabKey ?? (tabList && tabList.length > 0 ? tabList[0].key : ''),\n);\n\nconst currentTabKey = computed(() =>\n activeTabKey !== undefined ? activeTabKey : internalActiveTab.value,\n);\n\nwatch(\n () => activeTabKey,\n (val) => {\n if (val !== undefined) {\n internalActiveTab.value = val;\n }\n },\n);\n\n// ─────────────────────────────────────────────\n// Computed\n// ─────────────────────────────────────────────\nconst hasHeader = computed(() => {\n return !!(title || slots.title || extra || slots.extra || (tabList && tabList.length > 0));\n});\n\nconst rootClasses = computed(() => [\n 'b-card',\n {\n 'b-card--bordered': bordered,\n 'b-card--hoverable': hoverable,\n 'b-card--loading': loading,\n 'b-card--small': size === BCardSize.Small,\n 'b-card--inner': type === BCardType.Inner,\n 'b-card--has-tabs': tabList && tabList.length > 0,\n 'b-card--has-cover': !!slots.cover,\n 'b-card--has-actions': !!slots.actions,\n },\n]);\n\nconst tabPanelId = computed(() => `${cardId}-tabpanel`);\n\n// ─────────────────────────────────────────────\n// Tab handling\n// ─────────────────────────────────────────────\nfunction handleTabClick(key: string) {\n internalActiveTab.value = key;\n emit('update:activeTabKey', key);\n emit('tabChange', key);\n}\n\nfunction handleTabKeydown(event: KeyboardEvent, index: number) {\n if (!tabList) return;\n const enabledTabs = tabList.filter((t) => !t.disabled);\n const currentEnabled = enabledTabs.findIndex((t) => t.key === tabList[index].key);\n if (currentEnabled === -1) return;\n\n let targetIndex = -1;\n\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n targetIndex = (currentEnabled + 1) % enabledTabs.length;\n } else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n targetIndex = (currentEnabled - 1 + enabledTabs.length) % enabledTabs.length;\n } else if (event.key === 'Home') {\n event.preventDefault();\n targetIndex = 0;\n } else if (event.key === 'End') {\n event.preventDefault();\n targetIndex = enabledTabs.length - 1;\n }\n\n if (targetIndex >= 0) {\n const targetKey = enabledTabs[targetIndex].key;\n handleTabClick(targetKey);\n const tabEl = document.getElementById(`${cardId}-tab-${targetKey}`);\n tabEl?.focus();\n }\n}\n\n// ─────────────────────────────────────────────\n// Loading skeleton lines\n// ─────────────────────────────────────────────\nconst skeletonRows = [100, 75, 90, 60];\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <!-- Cover -->\n <div v-if=\"$slots.cover\" class=\"b-card__cover\">\n <slot name=\"cover\" />\n </div>\n\n <!-- Header -->\n <div v-if=\"hasHeader\" class=\"b-card__head\">\n <div class=\"b-card__head-wrapper\">\n <div v-if=\"title || $slots.title\" class=\"b-card__head-title\">\n <slot name=\"title\">{{ title }}</slot>\n </div>\n <div v-if=\"extra || $slots.extra\" class=\"b-card__extra\">\n <slot name=\"extra\">{{ extra }}</slot>\n </div>\n </div>\n\n <!-- Tabs -->\n <div v-if=\"tabList && tabList.length > 0\" class=\"b-card__tabs\">\n <div\n role=\"tablist\"\n class=\"b-card__tab-list\"\n :aria-label=\"title ? `${title} tabs` : 'Card tabs'\"\n >\n <button\n v-for=\"(tab, index) in tabList\"\n :id=\"`${cardId}-tab-${tab.key}`\"\n :key=\"tab.key\"\n role=\"tab\"\n class=\"b-card__tab\"\n :class=\"{\n 'b-card__tab--active': currentTabKey === tab.key,\n 'b-card__tab--disabled': tab.disabled,\n }\"\n :aria-selected=\"currentTabKey === tab.key\"\n :aria-controls=\"tabPanelId\"\n :tabindex=\"currentTabKey === tab.key ? 0 : -1\"\n :disabled=\"tab.disabled\"\n v-bind=\"tabProps\"\n @click=\"handleTabClick(tab.key)\"\n @keydown=\"handleTabKeydown($event, index)\"\n >\n <slot name=\"customTab\" :item=\"tab\" :is-active=\"currentTabKey === tab.key\">\n {{ tab.tab }}\n </slot>\n </button>\n </div>\n <div v-if=\"tabBarExtraContent || $slots.tabBarExtraContent\" class=\"b-card__tab-extra\">\n <slot name=\"tabBarExtraContent\">{{ tabBarExtraContent }}</slot>\n </div>\n </div>\n </div>\n\n <!-- Body -->\n <div\n class=\"b-card__body\"\n :id=\"tabList && tabList.length > 0 ? tabPanelId : undefined\"\n :role=\"tabList && tabList.length > 0 ? 'tabpanel' : undefined\"\n :aria-labelledby=\"\n tabList && tabList.length > 0 ? `${cardId}-tab-${currentTabKey}` : undefined\n \"\n >\n <!-- Loading skeleton -->\n <div\n v-if=\"loading\"\n class=\"b-card__loading\"\n role=\"status\"\n aria-busy=\"true\"\n aria-label=\"Loading card content\"\n >\n <div\n v-for=\"(width, i) in skeletonRows\"\n :key=\"i\"\n class=\"b-card__loading-line\"\n :style=\"{ width: `${width}%` }\"\n />\n </div>\n\n <!-- Content -->\n <template v-else>\n <slot />\n </template>\n </div>\n\n <!-- Actions -->\n <div v-if=\"$slots.actions\" class=\"b-card__actions\" role=\"group\" aria-label=\"Card actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n</template>\n\n<style>\n/* ─────────────────────────────────────────────\n BCard - CSS custom properties (scoped to root)\n ───────────────────────────────────────────── */\n.b-card {\n /* Surface */\n --b-card-bg: oklch(100% 0 0);\n --b-card-color: oklch(20% 0.02 260);\n --b-card-border-radius: 8px;\n --b-card-border-color: oklch(85% 0.01 260);\n --b-card-border-width: 1px;\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 6%), 0 1px 3px 0 oklch(0% 0 0 / 10%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 12%);\n --b-card-transition-duration: 200ms;\n\n /* Head */\n --b-card-head-padding: 16px 24px;\n --b-card-head-padding-sm: 8px 16px;\n --b-card-head-font-size: 16px;\n --b-card-head-font-size-sm: 14px;\n --b-card-head-font-weight: 600;\n --b-card-head-color: oklch(20% 0.02 260);\n --b-card-head-border-color: oklch(90% 0.01 260);\n --b-card-head-min-height: 56px;\n --b-card-head-min-height-sm: 40px;\n\n /* Body */\n --b-card-body-padding: 24px;\n --b-card-body-padding-sm: 16px;\n\n /* Extra */\n --b-card-extra-color: oklch(45% 0.02 260);\n --b-card-extra-font-size: 14px;\n\n /* Cover */\n --b-card-cover-border-radius: var(--b-card-border-radius) var(--b-card-border-radius) 0 0;\n\n /* Actions */\n --b-card-actions-padding: 12px 24px;\n --b-card-actions-border-color: oklch(90% 0.01 260);\n --b-card-actions-bg: transparent;\n\n /* Tabs */\n --b-card-tab-color: oklch(45% 0.02 260);\n --b-card-tab-active-color: oklch(46% 0.24 264);\n --b-card-tab-hover-color: oklch(46% 0.24 264);\n --b-card-tab-disabled-color: oklch(70% 0.01 260);\n --b-card-tab-bar-border-color: oklch(90% 0.01 260);\n --b-card-tab-indicator-color: oklch(46% 0.24 264);\n --b-card-tab-font-size: 14px;\n --b-card-tab-padding: 12px 16px;\n\n /* Inner card */\n --b-card-inner-bg: oklch(97% 0 0);\n\n /* Loading */\n --b-card-loading-line-bg: oklch(92% 0.01 260);\n --b-card-loading-shine-color: oklch(96% 0 0);\n --b-card-loading-line-height: 16px;\n --b-card-loading-line-radius: 4px;\n --b-card-loading-gap: 12px;\n\n /* Layout */\n position: relative;\n display: flex;\n flex-direction: column;\n background: var(--b-card-bg);\n color: var(--b-card-color);\n border-radius: var(--b-card-border-radius);\n font-size: 14px;\n line-height: 1.5715;\n box-sizing: border-box;\n transition:\n box-shadow var(--b-card-transition-duration) ease,\n border-color var(--b-card-transition-duration) ease;\n}\n\n/* ── Border ── */\n.b-card--bordered {\n border: var(--b-card-border-width) solid var(--b-card-border-color);\n}\n\n.b-card:not(.b-card--bordered) {\n box-shadow: var(--b-card-shadow);\n}\n\n/* ── Hoverable ── */\n.b-card--hoverable {\n cursor: pointer;\n}\n\n.b-card--hoverable:hover {\n box-shadow: var(--b-card-shadow-hover);\n}\n\n.b-card--bordered.b-card--hoverable:hover {\n border-color: transparent;\n box-shadow: var(--b-card-shadow-hover);\n}\n\n/* ── Inner card ── */\n.b-card--inner {\n background: var(--b-card-inner-bg);\n}\n\n/* ── Small size ── */\n.b-card--small .b-card__head {\n padding: var(--b-card-head-padding-sm);\n min-height: var(--b-card-head-min-height-sm);\n font-size: var(--b-card-head-font-size-sm);\n}\n\n.b-card--small .b-card__body {\n padding: var(--b-card-body-padding-sm);\n}\n\n/* ── Cover ── */\n.b-card__cover {\n overflow: hidden;\n border-radius: var(--b-card-cover-border-radius);\n}\n\n.b-card--bordered .b-card__cover {\n margin-top: -1px;\n margin-inline: -1px;\n}\n\n.b-card__cover img,\n.b-card__cover video {\n display: block;\n width: 100%;\n height: auto;\n}\n\n/* ── Head ── */\n.b-card__head {\n display: flex;\n flex-direction: column;\n padding: var(--b-card-head-padding);\n border-bottom: 1px solid var(--b-card-head-border-color);\n min-height: var(--b-card-head-min-height);\n font-size: var(--b-card-head-font-size);\n box-sizing: border-box;\n}\n\n.b-card--has-tabs .b-card__head {\n padding-bottom: 0;\n border-bottom: none;\n}\n\n.b-card__head-wrapper {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.b-card__head-title {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: var(--b-card-head-font-weight);\n color: var(--b-card-head-color);\n}\n\n.b-card__extra {\n flex: none;\n color: var(--b-card-extra-color);\n font-size: var(--b-card-extra-font-size);\n font-weight: 400;\n}\n\n/* ── Tabs ── */\n.b-card__tabs {\n display: flex;\n align-items: center;\n justify-content: space-between;\n border-bottom: 1px solid var(--b-card-tab-bar-border-color);\n margin-top: 4px;\n}\n\n.b-card__tab-list {\n display: flex;\n gap: 0;\n}\n\n.b-card__tab {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: var(--b-card-tab-padding);\n border: none;\n background: none;\n color: var(--b-card-tab-color);\n font-size: var(--b-card-tab-font-size);\n font-family: inherit;\n cursor: pointer;\n transition: color var(--b-card-transition-duration) ease;\n outline: none;\n}\n\n.b-card__tab::after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 50%;\n width: 0;\n height: 2px;\n background: var(--b-card-tab-indicator-color);\n border-radius: 1px;\n transition:\n width var(--b-card-transition-duration) ease,\n left var(--b-card-transition-duration) ease;\n}\n\n.b-card__tab:hover:not(:disabled) {\n color: var(--b-card-tab-hover-color);\n}\n\n.b-card__tab:focus-visible {\n outline: 2px solid var(--b-card-tab-active-color);\n outline-offset: -2px;\n border-radius: 4px;\n}\n\n.b-card__tab--active {\n color: var(--b-card-tab-active-color);\n font-weight: 500;\n}\n\n.b-card__tab--active::after {\n width: 100%;\n left: 0;\n}\n\n.b-card__tab--disabled {\n color: var(--b-card-tab-disabled-color);\n cursor: not-allowed;\n}\n\n.b-card__tab-extra {\n flex: none;\n padding: 0 16px;\n color: var(--b-card-extra-color);\n font-size: var(--b-card-extra-font-size);\n}\n\n/* ── Body ── */\n.b-card__body {\n flex: 1;\n padding: var(--b-card-body-padding);\n}\n\n/* ── Actions ── */\n.b-card__actions {\n display: flex;\n align-items: center;\n justify-content: space-evenly;\n padding: var(--b-card-actions-padding);\n border-top: 1px solid var(--b-card-actions-border-color);\n background: var(--b-card-actions-bg);\n border-radius: 0 0 var(--b-card-border-radius) var(--b-card-border-radius);\n}\n\n/* ── Loading skeleton ── */\n.b-card__loading {\n display: flex;\n flex-direction: column;\n gap: var(--b-card-loading-gap);\n}\n\n.b-card__loading-line {\n height: var(--b-card-loading-line-height);\n border-radius: var(--b-card-loading-line-radius);\n background: linear-gradient(\n 90deg,\n var(--b-card-loading-line-bg) 25%,\n var(--b-card-loading-shine-color) 50%,\n var(--b-card-loading-line-bg) 75%\n );\n background-size: 200% 100%;\n animation: b-card-loading-shimmer 1.5s infinite ease-in-out;\n}\n\n@keyframes b-card-loading-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card {\n --b-card-bg: oklch(20% 0.02 260);\n --b-card-color: oklch(88% 0.01 260);\n --b-card-border-color: oklch(35% 0.02 260);\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 20%), 0 1px 3px 0 oklch(0% 0 0 / 25%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n --b-card-head-color: oklch(92% 0.01 260);\n --b-card-head-border-color: oklch(35% 0.02 260);\n --b-card-extra-color: oklch(65% 0.01 260);\n --b-card-tab-color: oklch(65% 0.01 260);\n --b-card-tab-active-color: oklch(70% 0.18 264);\n --b-card-tab-hover-color: oklch(70% 0.18 264);\n --b-card-tab-disabled-color: oklch(40% 0.01 260);\n --b-card-tab-bar-border-color: oklch(35% 0.02 260);\n --b-card-tab-indicator-color: oklch(70% 0.18 264);\n --b-card-actions-border-color: oklch(35% 0.02 260);\n --b-card-inner-bg: oklch(25% 0.02 260);\n --b-card-loading-line-bg: oklch(30% 0.02 260);\n --b-card-loading-shine-color: oklch(35% 0.02 260);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card {\n --b-card-bg: oklch(20% 0.02 260);\n --b-card-color: oklch(88% 0.01 260);\n --b-card-border-color: oklch(35% 0.02 260);\n --b-card-shadow: 0 1px 2px 0 oklch(0% 0 0 / 20%), 0 1px 3px 0 oklch(0% 0 0 / 25%);\n --b-card-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n --b-card-head-color: oklch(92% 0.01 260);\n --b-card-head-border-color: oklch(35% 0.02 260);\n --b-card-extra-color: oklch(65% 0.01 260);\n --b-card-tab-color: oklch(65% 0.01 260);\n --b-card-tab-active-color: oklch(70% 0.18 264);\n --b-card-tab-hover-color: oklch(70% 0.18 264);\n --b-card-tab-disabled-color: oklch(40% 0.01 260);\n --b-card-tab-bar-border-color: oklch(35% 0.02 260);\n --b-card-tab-indicator-color: oklch(70% 0.18 264);\n --b-card-actions-border-color: oklch(35% 0.02 260);\n --b-card-inner-bg: oklch(25% 0.02 260);\n --b-card-loading-line-bg: oklch(30% 0.02 260);\n --b-card-loading-shine-color: oklch(35% 0.02 260);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-card {\n --b-card-transition-duration: 0ms;\n }\n\n .b-card__loading-line {\n animation: none;\n }\n}\n</style>\n"],"mappings":""}
@@ -1,14 +1,19 @@
1
- //#region src/components/BCascader/types.ts
2
- var e = /* @__PURE__ */ function(e) {
3
- return e.Click = "click", e.Hover = "hover", e;
4
- }({}), t = /* @__PURE__ */ function(e) {
5
- return e.BottomLeft = "bottomLeft", e.BottomRight = "bottomRight", e.TopLeft = "topLeft", e.TopRight = "topRight", e;
6
- }({}), n = /* @__PURE__ */ function(e) {
7
- return e.Small = "sm", e.Medium = "md", e.Large = "lg", e;
8
- }({}), r = /* @__PURE__ */ function(e) {
9
- return e.Error = "error", e.Warning = "warning", e;
10
- }({});
1
+ import { createElementBlock as e, defineComponent as t, normalizeClass as n, openBlock as r, renderSlot as i } from "vue";
2
+ //#region src/components/BCard/BCardGrid.vue?vue&type=script&setup=true&lang.ts
3
+ var a = ["role"], o = /* @__PURE__ */ t({
4
+ __name: "BCardGrid",
5
+ props: { hoverable: {
6
+ type: Boolean,
7
+ default: !1
8
+ } },
9
+ setup(t) {
10
+ return (o, s) => (r(), e("div", {
11
+ class: n(["b-card-grid", { "b-card-grid--hoverable": t.hoverable }]),
12
+ role: o.$attrs["aria-label"] ? "region" : void 0
13
+ }, [i(o.$slots, "default")], 10, a));
14
+ }
15
+ });
11
16
  //#endregion
12
- export { e as BCascaderExpandTrigger, t as BCascaderPlacement, n as BCascaderSize, r as BCascaderStatus };
17
+ export { o as default };
13
18
 
14
19
  //# sourceMappingURL=design-system39.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"design-system39.js","names":[],"sources":["../src/components/BCascader/types.ts"],"sourcesContent":["export enum BCascaderExpandTrigger {\n Click = 'click',\n Hover = 'hover',\n}\n\nexport enum BCascaderPlacement {\n BottomLeft = 'bottomLeft',\n BottomRight = 'bottomRight',\n TopLeft = 'topLeft',\n TopRight = 'topRight',\n}\n\nexport enum BCascaderSize {\n Small = 'sm',\n Medium = 'md',\n Large = 'lg',\n}\n\nexport enum BCascaderStatus {\n Error = 'error',\n Warning = 'warning',\n}\n\nexport interface BCascaderOption {\n /** The value used for identification. */\n value: string | number;\n /** The display label. */\n label: string;\n /** Whether this option is disabled. */\n disabled?: boolean;\n /** Child options for the next level. */\n children?: BCascaderOption[];\n /** Whether this is a leaf node (used with lazy loading). */\n isLeaf?: boolean;\n}\n\nexport interface BCascaderFieldNames {\n /** Custom field name for label. */\n label?: string;\n /** Custom field name for value. */\n value?: string;\n /** Custom field name for children. */\n children?: string;\n}\n\nexport type BCascaderValueType = (string | number)[];\n\nexport interface BCascaderShowSearchConfig {\n /** Custom filter function. */\n filter?: (inputValue: string, path: BCascaderOption[]) => boolean;\n /** Maximum number of search results. */\n limit?: number;\n /** Custom render function for search results. */\n render?: (inputValue: string, path: BCascaderOption[]) => string;\n}\n"],"mappings":";AAAA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,SACA,EAAA,QAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,aAAA,cACA,EAAA,cAAA,eACA,EAAA,UAAA,WACA,EAAA,WAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,MACA,EAAA,SAAA,MACA,EAAA,QAAA;KACD,EAEW,IAAL,yBAAA,GAAA;QACL,EAAA,QAAA,SACA,EAAA,UAAA;KACD"}
1
+ {"version":3,"file":"design-system39.js","names":["$attrs"],"sources":["../src/components/BCard/BCardGrid.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst { hoverable = false } = defineProps<{\n /** Whether to apply hover styling to the grid item. @default false */\n hoverable?: boolean;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Content inside the grid item */\n default?: (props: Record<string, never>) => unknown;\n}>();\n</script>\n\n<template>\n <div\n class=\"b-card-grid\"\n :class=\"{ 'b-card-grid--hoverable': hoverable }\"\n :role=\"$attrs['aria-label'] ? 'region' : undefined\"\n >\n <slot />\n </div>\n</template>\n\n<style>\n.b-card-grid {\n --b-card-grid-width: 33.33%;\n --b-card-grid-padding: 24px;\n --b-card-grid-border-color: oklch(90% 0.01 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 12%);\n --b-card-grid-transition-duration: 200ms;\n\n float: left;\n width: var(--b-card-grid-width);\n padding: var(--b-card-grid-padding);\n border: 0;\n border-radius: 0;\n box-shadow:\n 1px 0 0 0 var(--b-card-grid-border-color),\n 0 1px 0 0 var(--b-card-grid-border-color),\n 1px 1px 0 0 var(--b-card-grid-border-color),\n 1px 0 0 0 var(--b-card-grid-border-color) inset,\n 0 1px 0 0 var(--b-card-grid-border-color) inset;\n box-sizing: border-box;\n transition: box-shadow var(--b-card-grid-transition-duration) ease;\n}\n\n.b-card-grid--hoverable {\n cursor: pointer;\n}\n\n.b-card-grid--hoverable:hover {\n position: relative;\n z-index: 1;\n box-shadow: var(--b-card-grid-shadow-hover);\n}\n\n.b-card-grid--hoverable:focus-visible {\n outline: 2px solid oklch(46% 0.24 264);\n outline-offset: -2px;\n position: relative;\n z-index: 1;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-card-grid {\n --b-card-grid-transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":";;;;;;;;;yBAmBE,EAMM,OAAA;GALJ,OAAK,EAAA,CAAC,eAAa,EAAA,0BACiB,EAAA,WAAS,CAAA,CAAA;GAC5C,MAAMA,EAAAA,OAAM,gBAAA,WAA4B,KAAA;MAEzC,EAAQ,EAAA,QAAA,UAAA,CAAA,EAAA,IAAA,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"design-system4.js","names":[],"sources":["../src/components/BAlert/BAlert.vue?vue&type=script&setup=true&lang.ts"],"sourcesContent":["import { useSlots as _useSlots, defineComponent as _defineComponent } from 'vue'\nimport { unref as _unref, renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass, Transition as _Transition, withCtx as _withCtx, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = [\"role\", \"aria-live\", \"aria-describedby\"]\nconst _hoisted_2 = {\n key: 0,\n class: \"b-alert__icon\",\n \"aria-hidden\": \"true\"\n}\nconst _hoisted_3 = {\n class: \"b-alert__icon-svg\",\n viewBox: \"0 0 24 24\",\n xmlns: \"http://www.w3.org/2000/svg\",\n focusable: \"false\"\n}\nconst _hoisted_4 = [\"d\"]\nconst _hoisted_5 = { class: \"b-alert__content\" }\nconst _hoisted_6 = { class: \"b-alert__message\" }\nconst _hoisted_7 = [\"id\"]\nconst _hoisted_8 = {\n key: 1,\n class: \"b-alert__extra\"\n}\nconst _hoisted_9 = {\n key: 0,\n class: \"b-alert__action\"\n}\n\nimport { BAlertType } from '@/types.ts';\nimport { computed, ref, useId } from 'vue';\n\n// ─────────────────────────────────────────────\n// Props & emits\n// ─────────────────────────────────────────────\n\nexport default /*@__PURE__*/_defineComponent({\n __name: 'BAlert',\n props: {\n type: { default: () => (BAlertType.Info) },\n message: { default: '' },\n description: { default: '' },\n showIcon: { type: Boolean, default: false },\n closable: { type: Boolean, default: false },\n banner: { type: Boolean, default: false },\n action: { default: '' },\n modelValue: { type: Boolean, default: () => (undefined) }\n },\n emits: [\"close\", \"afterClose\", \"update:modelValue\"],\n setup(__props: any, { emit: __emit }) {\n\n\n\nconst emit = __emit;\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst descriptionId = useId();\n\n/** Uncontrolled visibility flag. */\nconst internalVisible = ref(true);\n\n/**\n * Effective visibility:\n * - controlled → honour `modelValue`\n * - uncontrolled → use `internalVisible`\n */\nconst isVisible = computed(() => (__props.modelValue !== undefined ? __props.modelValue : internalVisible.value));\n\n// ─────────────────────────────────────────────\n// Derived state\n// ─────────────────────────────────────────────\nconst hasDescription = computed(() => Boolean(__props.description || slots.description));\nconst hasAction = computed(() => Boolean(__props.action || slots.action));\n\n/** ARIA role: 'alert' for errors/warnings (assertive), 'status' for others. */\nconst ariaRole = computed<'alert' | 'status'>(() =>\n __props.type === BAlertType.Error || __props.type === BAlertType.Warning ? 'alert' : 'status',\n);\n\n/** Map type → inline SVG path for the status icon. */\nconst iconPath = computed(() => {\n switch (__props.type) {\n case BAlertType.Success:\n // circle-check\n return 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5-4-4 1.41-1.41L10 13.67l6.59-6.59L18 8.5l-8 8z';\n case BAlertType.Warning:\n // triangle-exclamation\n return 'M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z';\n case BAlertType.Error:\n // circle-xmark\n return 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z';\n default:\n // circle-info\n return 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z';\n }\n});\n\n/** Expose slots ref for slot-presence detection. */\nconst slots = _useSlots();\n\n// ─────────────────────────────────────────────\n// Behaviour\n// ─────────────────────────────────────────────\nfunction handleClose(event: MouseEvent | KeyboardEvent) {\n emit('close', event);\n if (__props.modelValue !== undefined) {\n emit('update:modelValue', false);\n } else {\n internalVisible.value = false;\n }\n}\n\nfunction onCloseClick(event: MouseEvent) {\n handleClose(event);\n}\n\nfunction onCloseKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Escape') {\n event.preventDefault();\n handleClose(event);\n }\n}\n\nfunction onAfterLeave() {\n emit('afterClose');\n}\n\nreturn (_ctx: any,_cache: any) => {\n return (_openBlock(), _createBlock(_Transition, {\n name: \"b-alert-fade\",\n onAfterLeave: onAfterLeave\n }, {\n default: _withCtx(() => [\n (isVisible.value)\n ? (_openBlock(), _createElementBlock(\"div\", {\n key: 0,\n class: _normalizeClass([\"b-alert\", [\n `b-alert--${__props.type}`,\n {\n 'b-alert--with-description': hasDescription.value,\n 'b-alert--banner': __props.banner,\n 'b-alert--with-icon': __props.showIcon,\n 'b-alert--closable': __props.closable,\n },\n ]]),\n role: ariaRole.value,\n \"aria-live\": ariaRole.value === 'alert' ? 'assertive' : 'polite',\n \"aria-atomic\": true,\n \"aria-describedby\": hasDescription.value ? _unref(descriptionId) : undefined\n }, [\n (__props.showIcon)\n ? (_openBlock(), _createElementBlock(\"span\", _hoisted_2, [\n _renderSlot(_ctx.$slots, \"icon\", {}, () => [\n (_openBlock(), _createElementBlock(\"svg\", _hoisted_3, [\n _createElementVNode(\"path\", { d: iconPath.value }, null, 8, _hoisted_4)\n ]))\n ])\n ]))\n : _createCommentVNode(\"\", true),\n _createElementVNode(\"div\", _hoisted_5, [\n _createElementVNode(\"div\", _hoisted_6, [\n _renderSlot(_ctx.$slots, \"default\", {}, () => [\n _createTextVNode(_toDisplayString(__props.message), 1)\n ])\n ]),\n (hasDescription.value)\n ? (_openBlock(), _createElementBlock(\"div\", {\n key: 0,\n id: _unref(descriptionId),\n class: \"b-alert__description\"\n }, [\n _renderSlot(_ctx.$slots, \"description\", {}, () => [\n _createTextVNode(_toDisplayString(__props.description), 1)\n ])\n ], 8, _hoisted_7))\n : _createCommentVNode(\"\", true)\n ]),\n (hasAction.value || __props.closable)\n ? (_openBlock(), _createElementBlock(\"div\", _hoisted_8, [\n (hasAction.value)\n ? (_openBlock(), _createElementBlock(\"span\", _hoisted_9, [\n _renderSlot(_ctx.$slots, \"action\", {}, () => [\n _createTextVNode(_toDisplayString(__props.action), 1)\n ])\n ]))\n : _createCommentVNode(\"\", true),\n (__props.closable)\n ? (_openBlock(), _createElementBlock(\"button\", {\n key: 1,\n type: \"button\",\n class: \"b-alert__close\",\n \"aria-label\": \"Close alert\",\n onClick: onCloseClick,\n onKeydown: onCloseKeydown\n }, [\n _renderSlot(_ctx.$slots, \"closeIcon\", {}, () => [\n _cache[0] || (_cache[0] = _createElementVNode(\"svg\", {\n class: \"b-alert__close-icon\",\n viewBox: \"0 0 24 24\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n focusable: \"false\"\n }, [\n _createElementVNode(\"path\", { d: \"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" })\n ], -1))\n ])\n ], 32))\n : _createCommentVNode(\"\", true)\n ]))\n : _createCommentVNode(\"\", true)\n ], 10, _hoisted_1))\n : _createCommentVNode(\"\", true)\n ]),\n _: 3\n }))\n}\n}\n\n})"],"mappings":"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"}
1
+ {"version":3,"file":"design-system4.js","names":[],"sources":["../src/components/BAlert/BAlert.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { BAlertType } from '@/types.ts';\nimport { computed, ref, useId } from 'vue';\n\n// ─────────────────────────────────────────────\n// Props & emits\n// ─────────────────────────────────────────────\nconst {\n type = BAlertType.Info,\n message = '',\n description = '',\n showIcon = false,\n closable = false,\n banner = false,\n action = '',\n modelValue = undefined,\n} = defineProps<{\n /**\n * Alert type - maps to role / colour scheme.\n * @default 'info'\n */\n type?: `${BAlertType}`;\n /** Primary message text (also accepts the default slot). */\n message?: string;\n /** Secondary description text (also accepts the `description` slot). */\n description?: string;\n /** Show the built-in status icon. */\n showIcon?: boolean;\n /** Show the close button. */\n closable?: boolean;\n /** Render as a top banner (no border-radius, full-width). */\n banner?: boolean;\n /**\n * Text for the action area (also accepts the `action` slot).\n * Displayed in the top-right area next to the close button.\n */\n action?: string;\n /**\n * Controlled visibility - when provided the component operates in\n * controlled mode; otherwise it manages its own visibility.\n * Bind with `v-model`.\n */\n modelValue?: boolean;\n}>();\n\nconst emit = defineEmits<{\n /** Fired synchronously when the close button is activated. */\n (e: 'close', event: MouseEvent | KeyboardEvent): void;\n /** Fired after the leave-transition fully completes. */\n (e: 'afterClose'): void;\n /** v-model support */\n (e: 'update:modelValue', value: boolean): void;\n}>();\n\n// ─────────────────────────────────────────────\n// Internal state\n// ─────────────────────────────────────────────\nconst descriptionId = useId();\n\n/** Uncontrolled visibility flag. */\nconst internalVisible = ref(true);\n\n/**\n * Effective visibility:\n * - controlled → honour `modelValue`\n * - uncontrolled → use `internalVisible`\n */\nconst isVisible = computed(() => (modelValue !== undefined ? modelValue : internalVisible.value));\n\n// ─────────────────────────────────────────────\n// Derived state\n// ─────────────────────────────────────────────\nconst hasDescription = computed(() => Boolean(description || slots.description));\nconst hasAction = computed(() => Boolean(action || slots.action));\n\n/** ARIA role: 'alert' for errors/warnings (assertive), 'status' for others. */\nconst ariaRole = computed<'alert' | 'status'>(() =>\n type === BAlertType.Error || type === BAlertType.Warning ? 'alert' : 'status',\n);\n\n/** Map type → inline SVG path for the status icon. */\nconst iconPath = computed(() => {\n switch (type) {\n case BAlertType.Success:\n // circle-check\n return 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5-4-4 1.41-1.41L10 13.67l6.59-6.59L18 8.5l-8 8z';\n case BAlertType.Warning:\n // triangle-exclamation\n return 'M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z';\n case BAlertType.Error:\n // circle-xmark\n return 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z';\n default:\n // circle-info\n return 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z';\n }\n});\n\n/** Expose slots ref for slot-presence detection. */\nconst slots = defineSlots<{\n /** Overrides the `message` prop. */\n default?(): unknown;\n /** Overrides the `description` prop. */\n description?(): unknown;\n /** Overrides the `action` prop. */\n action?(): unknown;\n /** Overrides the built-in close icon. */\n closeIcon?(): unknown;\n /** Overrides the built-in status icon. */\n icon?(): unknown;\n}>();\n\n// ─────────────────────────────────────────────\n// Behaviour\n// ─────────────────────────────────────────────\nfunction handleClose(event: MouseEvent | KeyboardEvent) {\n emit('close', event);\n if (modelValue !== undefined) {\n emit('update:modelValue', false);\n } else {\n internalVisible.value = false;\n }\n}\n\nfunction onCloseClick(event: MouseEvent) {\n handleClose(event);\n}\n\nfunction onCloseKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Escape') {\n event.preventDefault();\n handleClose(event);\n }\n}\n\nfunction onAfterLeave() {\n emit('afterClose');\n}\n</script>\n\n<template>\n <Transition name=\"b-alert-fade\" @after-leave=\"onAfterLeave\">\n <div\n v-if=\"isVisible\"\n class=\"b-alert\"\n :class=\"[\n `b-alert--${type}`,\n {\n 'b-alert--with-description': hasDescription,\n 'b-alert--banner': banner,\n 'b-alert--with-icon': showIcon,\n 'b-alert--closable': closable,\n },\n ]\"\n :role=\"ariaRole\"\n :aria-live=\"ariaRole === 'alert' ? 'assertive' : 'polite'\"\n :aria-atomic=\"true\"\n :aria-describedby=\"hasDescription ? descriptionId : undefined\"\n >\n <!-- Status icon -->\n <span v-if=\"showIcon\" class=\"b-alert__icon\" aria-hidden=\"true\">\n <slot name=\"icon\">\n <svg\n class=\"b-alert__icon-svg\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n focusable=\"false\"\n >\n <path :d=\"iconPath\" />\n </svg>\n </slot>\n </span>\n\n <!-- Content -->\n <div class=\"b-alert__content\">\n <!-- Message -->\n <div class=\"b-alert__message\">\n <slot>{{ message }}</slot>\n </div>\n\n <!-- Description -->\n <div v-if=\"hasDescription\" :id=\"descriptionId\" class=\"b-alert__description\">\n <slot name=\"description\">{{ description }}</slot>\n </div>\n </div>\n\n <!-- Action + Close -->\n <div v-if=\"hasAction || closable\" class=\"b-alert__extra\">\n <!-- Action slot -->\n <span v-if=\"hasAction\" class=\"b-alert__action\">\n <slot name=\"action\">{{ action }}</slot>\n </span>\n\n <!-- Close button -->\n <button\n v-if=\"closable\"\n type=\"button\"\n class=\"b-alert__close\"\n aria-label=\"Close alert\"\n @click=\"onCloseClick\"\n @keydown=\"onCloseKeydown\"\n >\n <slot name=\"closeIcon\">\n <svg\n class=\"b-alert__close-icon\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n />\n </svg>\n </slot>\n </button>\n </div>\n </div>\n </Transition>\n</template>\n\n<style>\n/* ────────────────────────────────────────────\n CSS Custom Properties (tokens)\n ──────────────────────────────────────────── */\n.b-alert {\n /* Layout */\n --b-alert-padding-v: 0.5rem;\n --b-alert-padding-h: 1rem;\n --b-alert-border-width: 1px;\n --b-alert-border-radius: 0.5rem;\n --b-alert-icon-size: 1rem;\n --b-alert-icon-size-with-desc: 1.5rem;\n --b-alert-gap: 0.5rem;\n\n /* Colours - info (default) */\n --b-alert-bg: oklch(95% 0.04 240);\n --b-alert-border-color: oklch(80% 0.1 240);\n --b-alert-color: oklch(35% 0.12 240);\n --b-alert-icon-color: oklch(62.3% 0.214 259.815); /* --color-info */\n --b-alert-close-color: oklch(50% 0.05 240);\n --b-alert-close-hover-color: oklch(35% 0.12 240);\n\n /* Animation */\n --b-alert-transition-duration: 300ms;\n}\n\n/* ── Variant colour tokens ── */\n.b-alert--success {\n --b-alert-bg: oklch(95% 0.05 145);\n --b-alert-border-color: oklch(80% 0.12 149);\n --b-alert-color: oklch(32% 0.1 149);\n --b-alert-icon-color: oklch(72.3% 0.219 149.579); /* --color-success */\n --b-alert-close-color: oklch(50% 0.08 149);\n --b-alert-close-hover-color: oklch(32% 0.1 149);\n}\n\n.b-alert--warning {\n --b-alert-bg: oklch(97% 0.06 75);\n --b-alert-border-color: oklch(85% 0.14 60);\n --b-alert-color: oklch(35% 0.1 55);\n --b-alert-icon-color: oklch(75% 0.183 55.934); /* --color-warning */\n --b-alert-close-color: oklch(55% 0.08 55);\n --b-alert-close-hover-color: oklch(35% 0.1 55);\n}\n\n.b-alert--error {\n --b-alert-bg: oklch(96% 0.04 20);\n --b-alert-border-color: oklch(80% 0.12 20);\n --b-alert-color: oklch(35% 0.12 20);\n --b-alert-icon-color: oklch(63.7% 0.237 25.331); /* --color-failure */\n --b-alert-close-color: oklch(55% 0.08 20);\n --b-alert-close-hover-color: oklch(35% 0.12 20);\n}\n\n/* ── Dark mode (mirrors Ant Design pattern) ──────────────────────────────\n The <html> element carries data-prefers-color=\"dark\"|\"light\".\n color-scheme is set on html itself (see main.css / preview.ts decorator).\n Component styles only need the attribute selector - no @media needed.\n ──────────────────────────────────────────────────────────────────────── */\n[data-prefers-color='dark'] .b-alert {\n --b-alert-bg: oklch(20% 0.04 240);\n --b-alert-border-color: oklch(35% 0.1 240);\n --b-alert-color: oklch(85% 0.05 240);\n --b-alert-close-color: oklch(65% 0.04 240);\n --b-alert-close-hover-color: oklch(85% 0.05 240);\n}\n\n[data-prefers-color='dark'] .b-alert--success {\n --b-alert-bg: oklch(18% 0.05 149);\n --b-alert-border-color: oklch(35% 0.12 149);\n --b-alert-color: oklch(82% 0.07 149);\n --b-alert-close-color: oklch(60% 0.06 149);\n --b-alert-close-hover-color: oklch(82% 0.07 149);\n}\n\n[data-prefers-color='dark'] .b-alert--warning {\n --b-alert-bg: oklch(18% 0.05 55);\n --b-alert-border-color: oklch(38% 0.14 55);\n --b-alert-color: oklch(88% 0.08 55);\n --b-alert-close-color: oklch(62% 0.06 55);\n --b-alert-close-hover-color: oklch(88% 0.08 55);\n}\n\n[data-prefers-color='dark'] .b-alert--error {\n --b-alert-bg: oklch(18% 0.04 20);\n --b-alert-border-color: oklch(35% 0.12 20);\n --b-alert-color: oklch(85% 0.07 20);\n --b-alert-close-color: oklch(62% 0.06 20);\n --b-alert-close-hover-color: oklch(85% 0.07 20);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-alert {\n --b-alert-bg: oklch(20% 0.04 240);\n --b-alert-border-color: oklch(35% 0.1 240);\n --b-alert-color: oklch(85% 0.05 240);\n --b-alert-close-color: oklch(65% 0.04 240);\n --b-alert-close-hover-color: oklch(85% 0.05 240);\n }\n [data-prefers-color='system'] .b-alert--success {\n --b-alert-bg: oklch(18% 0.05 149);\n --b-alert-border-color: oklch(35% 0.12 149);\n --b-alert-color: oklch(82% 0.07 149);\n --b-alert-close-color: oklch(60% 0.06 149);\n --b-alert-close-hover-color: oklch(82% 0.07 149);\n }\n [data-prefers-color='system'] .b-alert--warning {\n --b-alert-bg: oklch(18% 0.05 55);\n --b-alert-border-color: oklch(38% 0.14 55);\n --b-alert-color: oklch(88% 0.08 55);\n --b-alert-close-color: oklch(62% 0.06 55);\n --b-alert-close-hover-color: oklch(88% 0.08 55);\n }\n [data-prefers-color='system'] .b-alert--error {\n --b-alert-bg: oklch(18% 0.04 20);\n --b-alert-border-color: oklch(35% 0.12 20);\n --b-alert-color: oklch(85% 0.07 20);\n --b-alert-close-color: oklch(62% 0.06 20);\n --b-alert-close-hover-color: oklch(85% 0.07 20);\n }\n}\n\n/* ─────────────────────────────────────────────\n Base layout\n ───────────────────────────────────────────── */\n.b-alert {\n position: relative;\n display: flex;\n align-items: flex-start;\n gap: var(--b-alert-gap);\n padding: var(--b-alert-padding-v) var(--b-alert-padding-h);\n border: var(--b-alert-border-width) solid var(--b-alert-border-color);\n border-radius: var(--b-alert-border-radius);\n background-color: var(--b-alert-bg);\n color: var(--b-alert-color);\n box-sizing: border-box;\n word-break: break-word;\n}\n\n/* Banner variant: no border-radius, no top/bottom borders, full width */\n.b-alert--banner {\n border-radius: 0;\n border-left: none;\n border-right: none;\n}\n\n/* ── Icon ── */\n.b-alert__icon {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n color: var(--b-alert-icon-color);\n font-size: var(--b-alert-icon-size);\n line-height: 1;\n /* align icon with single-line message */\n margin-top: 0.15em;\n}\n\n.b-alert--with-description .b-alert__icon {\n font-size: var(--b-alert-icon-size-with-desc);\n margin-top: 0;\n}\n\n.b-alert__icon-svg {\n width: 1em;\n height: 1em;\n fill: currentColor;\n display: block;\n}\n\n/* ── Content ── */\n.b-alert__content {\n flex: 1;\n min-width: 0;\n}\n\n.b-alert__message {\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.b-alert--with-description .b-alert__message {\n font-weight: 600;\n font-size: 1rem;\n}\n\n.b-alert__description {\n margin-top: 0.25rem;\n font-size: 0.875rem;\n line-height: 1.5;\n opacity: 0.85;\n}\n\n/* ── Extra (action + close) ── */\n.b-alert__extra {\n display: inline-flex;\n flex-shrink: 0;\n align-items: flex-start;\n gap: 0.5rem;\n /* align with message baseline */\n margin-top: 0.1em;\n}\n\n.b-alert__action {\n font-size: 0.875rem;\n line-height: 1.5;\n color: inherit;\n}\n\n/* ── Close button ── */\n.b-alert__close {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: none;\n border-radius: 0.25rem;\n background: transparent;\n color: var(--b-alert-close-color);\n cursor: pointer;\n line-height: 1;\n font-size: 1rem;\n /* match icon-only click area */\n width: 1.25rem;\n height: 1.25rem;\n transition: color var(--b-alert-transition-duration) ease;\n}\n\n.b-alert__close:hover {\n color: var(--b-alert-close-hover-color);\n}\n\n.b-alert__close:focus-visible {\n outline: 2px solid var(--b-alert-icon-color);\n outline-offset: 2px;\n}\n\n.b-alert__close-icon {\n width: 1em;\n height: 1em;\n fill: currentColor;\n display: block;\n}\n\n/* ─────────────────────────────────────────────\n Transition (fade + collapse)\n ───────────────────────────────────────────── */\n.b-alert-fade-enter-active,\n.b-alert-fade-leave-active {\n transition:\n opacity var(--b-alert-transition-duration) ease,\n max-height var(--b-alert-transition-duration) ease,\n margin-bottom var(--b-alert-transition-duration) ease,\n padding-top var(--b-alert-transition-duration) ease,\n padding-bottom var(--b-alert-transition-duration) ease;\n max-height: 200px;\n overflow: hidden;\n}\n\n.b-alert-fade-enter-from,\n.b-alert-fade-leave-to {\n opacity: 0;\n max-height: 0;\n padding-top: 0;\n padding-bottom: 0;\n}\n\n/* Respect prefers-reduced-motion */\n@media (prefers-reduced-motion: reduce) {\n .b-alert-fade-enter-active,\n .b-alert-fade-leave-active {\n transition: opacity var(--b-alert-transition-duration) ease;\n max-height: none;\n overflow: visible;\n }\n}\n</style>\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import e from "./design-system39.js";
2
+ /* empty css */
3
+ //#region src/components/BCard/BCardGrid.vue
4
+ var t = e;
5
+ //#endregion
6
+ export { t as default };
7
+
8
+ //# sourceMappingURL=design-system41.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"design-system41.js","names":[],"sources":["../src/components/BCard/BCardGrid.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// ─────────────────────────────────────────────\n// Props\n// ─────────────────────────────────────────────\nconst { hoverable = false } = defineProps<{\n /** Whether to apply hover styling to the grid item. @default false */\n hoverable?: boolean;\n}>();\n\n// ─────────────────────────────────────────────\n// Slots\n// ─────────────────────────────────────────────\ndefineSlots<{\n /** Content inside the grid item */\n default?: (props: Record<string, never>) => unknown;\n}>();\n</script>\n\n<template>\n <div\n class=\"b-card-grid\"\n :class=\"{ 'b-card-grid--hoverable': hoverable }\"\n :role=\"$attrs['aria-label'] ? 'region' : undefined\"\n >\n <slot />\n </div>\n</template>\n\n<style>\n.b-card-grid {\n --b-card-grid-width: 33.33%;\n --b-card-grid-padding: 24px;\n --b-card-grid-border-color: oklch(90% 0.01 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 12%);\n --b-card-grid-transition-duration: 200ms;\n\n float: left;\n width: var(--b-card-grid-width);\n padding: var(--b-card-grid-padding);\n border: 0;\n border-radius: 0;\n box-shadow:\n 1px 0 0 0 var(--b-card-grid-border-color),\n 0 1px 0 0 var(--b-card-grid-border-color),\n 1px 1px 0 0 var(--b-card-grid-border-color),\n 1px 0 0 0 var(--b-card-grid-border-color) inset,\n 0 1px 0 0 var(--b-card-grid-border-color) inset;\n box-sizing: border-box;\n transition: box-shadow var(--b-card-grid-transition-duration) ease;\n}\n\n.b-card-grid--hoverable {\n cursor: pointer;\n}\n\n.b-card-grid--hoverable:hover {\n position: relative;\n z-index: 1;\n box-shadow: var(--b-card-grid-shadow-hover);\n}\n\n.b-card-grid--hoverable:focus-visible {\n outline: 2px solid oklch(46% 0.24 264);\n outline-offset: -2px;\n position: relative;\n z-index: 1;\n}\n\n/* ── Dark mode ── */\n[data-prefers-color='dark'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n}\n\n@media (prefers-color-scheme: dark) {\n [data-prefers-color='system'] .b-card-grid {\n --b-card-grid-border-color: oklch(35% 0.02 260);\n --b-card-grid-shadow-hover: 0 4px 12px oklch(0% 0 0 / 30%);\n }\n}\n\n/* ── Reduced motion ── */\n@media (prefers-reduced-motion: reduce) {\n .b-card-grid {\n --b-card-grid-transition-duration: 0ms;\n }\n}\n</style>\n"],"mappings":""}