tekivex-ui 2.5.14 → 2.5.16

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 (392) hide show
  1. package/dist/charts.cjs +1 -1
  2. package/dist/charts.js +22 -553
  3. package/dist/chunk-B3ph66Zb.js +1 -0
  4. package/dist/chunk-Bc16rJT-.js +1 -0
  5. package/dist/chunk-BiHAhNbu.js +3 -0
  6. package/dist/chunk-CVRuGUFA.js +1 -0
  7. package/dist/chunk-Dc4_ud5s.js +1 -0
  8. package/dist/chunk-Dj40UFcz.js +1 -0
  9. package/dist/chunk-DjxOP8W4.js +1 -0
  10. package/dist/chunk-DmRB1Blb.js +1 -0
  11. package/dist/chunk-PJ50l0JC.js +1 -0
  12. package/dist/headless.cjs +1 -1
  13. package/dist/headless.js +1 -442
  14. package/dist/i18n.cjs +1 -1
  15. package/dist/i18n.js +1 -733
  16. package/dist/index.cjs +1 -147
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.js +419 -16193
  19. package/dist/quantum.cjs +1 -89
  20. package/dist/quantum.js +74 -2551
  21. package/dist/realtime.cjs +1 -23
  22. package/dist/realtime.js +1 -804
  23. package/dist/src/a11y/index.d.ts +0 -1
  24. package/dist/src/charts/TkxAreaChart.d.ts +0 -5
  25. package/dist/src/charts/TkxBarChart.d.ts +0 -3
  26. package/dist/src/charts/TkxDonutChart.d.ts +0 -5
  27. package/dist/src/charts/TkxLineChart.d.ts +0 -1
  28. package/dist/src/charts/TkxPieChart.d.ts +0 -3
  29. package/dist/src/charts/TkxRadarChart.d.ts +0 -3
  30. package/dist/src/charts/TkxScatterChart.d.ts +0 -2
  31. package/dist/src/charts/index.d.ts +0 -1
  32. package/dist/src/charts/shared.d.ts +0 -3
  33. package/dist/src/components/TkxAIChatBubble.d.ts +0 -9
  34. package/dist/src/components/TkxAIConfidenceBar.d.ts +0 -6
  35. package/dist/src/components/TkxAIThinking.d.ts +0 -6
  36. package/dist/src/components/TkxAccordion.d.ts +0 -1
  37. package/dist/src/components/TkxAffix.d.ts +0 -1
  38. package/dist/src/components/TkxAlert.d.ts +0 -1
  39. package/dist/src/components/TkxAnchor.d.ts +0 -1
  40. package/dist/src/components/TkxAppBar.d.ts +0 -1
  41. package/dist/src/components/TkxAutocomplete.d.ts +0 -1
  42. package/dist/src/components/TkxAvatar.d.ts +0 -1
  43. package/dist/src/components/TkxBadge.d.ts +0 -1
  44. package/dist/src/components/TkxBottomNav.d.ts +0 -1
  45. package/dist/src/components/TkxBreadcrumb.d.ts +0 -1
  46. package/dist/src/components/TkxButton.d.ts +0 -1
  47. package/dist/src/components/TkxCard.d.ts +0 -1
  48. package/dist/src/components/TkxCarousel.d.ts +0 -1
  49. package/dist/src/components/TkxCascader.d.ts +0 -1
  50. package/dist/src/components/TkxChat.d.ts +0 -1
  51. package/dist/src/components/TkxCheckbox.d.ts +0 -1
  52. package/dist/src/components/TkxClock.d.ts +0 -1
  53. package/dist/src/components/TkxColorPicker.d.ts +0 -1
  54. package/dist/src/components/TkxCommand.d.ts +0 -1
  55. package/dist/src/components/TkxConfigProvider.d.ts +0 -30
  56. package/dist/src/components/TkxDataGrid.d.ts +0 -15
  57. package/dist/src/components/TkxDatePicker.d.ts +0 -1
  58. package/dist/src/components/TkxDivider.d.ts +0 -1
  59. package/dist/src/components/TkxDrawer.d.ts +0 -1
  60. package/dist/src/components/TkxDropdown.d.ts +0 -1
  61. package/dist/src/components/TkxEmpty.d.ts +0 -1
  62. package/dist/src/components/TkxFileUpload.d.ts +0 -1
  63. package/dist/src/components/TkxForm.d.ts +0 -35
  64. package/dist/src/components/TkxIcon.d.ts +0 -1
  65. package/dist/src/components/TkxImage.d.ts +0 -1
  66. package/dist/src/components/TkxInput.d.ts +0 -1
  67. package/dist/src/components/TkxLayout.d.ts +0 -22
  68. package/dist/src/components/TkxList.d.ts +0 -1
  69. package/dist/src/components/TkxLiveFeed.d.ts +0 -1
  70. package/dist/src/components/TkxLiveLog.d.ts +0 -1
  71. package/dist/src/components/TkxLiveMetrics.d.ts +0 -1
  72. package/dist/src/components/TkxLogo.d.ts +0 -1
  73. package/dist/src/components/TkxMarkdown.d.ts +19 -0
  74. package/dist/src/components/TkxMasonry.d.ts +0 -1
  75. package/dist/src/components/TkxMentions.d.ts +0 -1
  76. package/dist/src/components/TkxMenu.d.ts +0 -1
  77. package/dist/src/components/TkxModal.d.ts +0 -1
  78. package/dist/src/components/TkxNumberInput.d.ts +0 -1
  79. package/dist/src/components/TkxOTP.d.ts +0 -1
  80. package/dist/src/components/TkxPagination.d.ts +0 -1
  81. package/dist/src/components/TkxPlayground.d.ts +0 -13
  82. package/dist/src/components/TkxPopover.d.ts +0 -1
  83. package/dist/src/components/TkxProgress.d.ts +0 -1
  84. package/dist/src/components/TkxQRCode.d.ts +0 -1
  85. package/dist/src/components/TkxQuantumForm.d.ts +0 -1
  86. package/dist/src/components/TkxRadio.d.ts +0 -1
  87. package/dist/src/components/TkxRating.d.ts +0 -1
  88. package/dist/src/components/TkxRealTimeChart.d.ts +0 -1
  89. package/dist/src/components/TkxResult.d.ts +0 -1
  90. package/dist/src/components/TkxRichTextDisplay.d.ts +0 -1
  91. package/dist/src/components/TkxSegmented.d.ts +0 -1
  92. package/dist/src/components/TkxSelect.d.ts +0 -3
  93. package/dist/src/components/TkxSkeleton.d.ts +0 -1
  94. package/dist/src/components/TkxSlider.d.ts +0 -1
  95. package/dist/src/components/TkxSnackbar.d.ts +0 -1
  96. package/dist/src/components/TkxSpeedDial.d.ts +0 -1
  97. package/dist/src/components/TkxSpin.d.ts +0 -1
  98. package/dist/src/components/TkxStatistic.d.ts +0 -1
  99. package/dist/src/components/TkxStepper.d.ts +0 -1
  100. package/dist/src/components/TkxTable.d.ts +0 -1
  101. package/dist/src/components/TkxTabs.d.ts +0 -1
  102. package/dist/src/components/TkxTag.d.ts +0 -1
  103. package/dist/src/components/TkxThemeBuilder.d.ts +0 -1
  104. package/dist/src/components/TkxTimeline.d.ts +0 -1
  105. package/dist/src/components/TkxToast.d.ts +0 -1
  106. package/dist/src/components/TkxToggle.d.ts +0 -1
  107. package/dist/src/components/TkxToolbar.d.ts +0 -1
  108. package/dist/src/components/TkxTooltip.d.ts +0 -1
  109. package/dist/src/components/TkxTour.d.ts +0 -1
  110. package/dist/src/components/TkxTransferList.d.ts +0 -1
  111. package/dist/src/components/TkxTreeView.d.ts +0 -1
  112. package/dist/src/components/TkxTypography.d.ts +0 -1
  113. package/dist/src/components/TkxVideoPlayer.d.ts +0 -1
  114. package/dist/src/components/TkxWatermark.d.ts +0 -1
  115. package/dist/src/components/index.d.ts +1 -1
  116. package/dist/src/engine/css.d.ts +0 -1
  117. package/dist/src/engine/index.d.ts +0 -1
  118. package/dist/src/engine/quantum-ai.d.ts +0 -73
  119. package/dist/src/engine/quantum.d.ts +0 -1
  120. package/dist/src/engine/security.d.ts +0 -9
  121. package/dist/src/engine/tkx.d.ts +0 -53
  122. package/dist/src/engine/wcag.d.ts +0 -1
  123. package/dist/src/headless/index.d.ts +0 -1
  124. package/dist/src/headless/useControllable.d.ts +0 -15
  125. package/dist/src/headless/useDebounce.d.ts +0 -12
  126. package/dist/src/headless/useDisclosure.d.ts +0 -13
  127. package/dist/src/headless/useFormState.d.ts +0 -13
  128. package/dist/src/headless/useInfiniteQuery.d.ts +0 -11
  129. package/dist/src/headless/useIntersectionObserver.d.ts +0 -10
  130. package/dist/src/headless/useListSelection.d.ts +0 -9
  131. package/dist/src/headless/useLocalStorage.d.ts +0 -8
  132. package/dist/src/headless/useMediaQuery.d.ts +0 -10
  133. package/dist/src/headless/useRovingTabIndex.d.ts +0 -15
  134. package/dist/src/headless/useSSE.d.ts +0 -9
  135. package/dist/src/headless/useThrottle.d.ts +0 -7
  136. package/dist/src/headless/useWebSocket.d.ts +0 -9
  137. package/dist/src/hooks/index.d.ts +0 -1
  138. package/dist/src/i18n/I18nProvider.d.ts +0 -1
  139. package/dist/src/i18n/index.d.ts +0 -1
  140. package/dist/src/quantum/index.d.ts +0 -1
  141. package/dist/src/realtime/index.d.ts +0 -1
  142. package/dist/src/themes/index.d.ts +0 -1
  143. package/package.json +5 -3
  144. package/dist/TkxForm-BaO4wvXt.js +0 -320
  145. package/dist/TkxForm-M6ttomry.cjs +0 -12
  146. package/dist/chunk-Bmb41Sf3.cjs +0 -1
  147. package/dist/hooks-6pRsPOyG.js +0 -58
  148. package/dist/hooks-mivgRljH.cjs +0 -1
  149. package/dist/index.d.ts.map +0 -1
  150. package/dist/src/a11y/index.d.ts.map +0 -1
  151. package/dist/src/charts/TkxAreaChart.d.ts.map +0 -1
  152. package/dist/src/charts/TkxBarChart.d.ts.map +0 -1
  153. package/dist/src/charts/TkxDonutChart.d.ts.map +0 -1
  154. package/dist/src/charts/TkxLineChart.d.ts.map +0 -1
  155. package/dist/src/charts/TkxPieChart.d.ts.map +0 -1
  156. package/dist/src/charts/TkxRadarChart.d.ts.map +0 -1
  157. package/dist/src/charts/TkxScatterChart.d.ts.map +0 -1
  158. package/dist/src/charts/index.d.ts.map +0 -1
  159. package/dist/src/charts/shared.d.ts.map +0 -1
  160. package/dist/src/components/TkxAIChatBubble.d.ts.map +0 -1
  161. package/dist/src/components/TkxAIConfidenceBar.d.ts.map +0 -1
  162. package/dist/src/components/TkxAIThinking.d.ts.map +0 -1
  163. package/dist/src/components/TkxAccordion.d.ts.map +0 -1
  164. package/dist/src/components/TkxAffix.d.ts.map +0 -1
  165. package/dist/src/components/TkxAlert.d.ts.map +0 -1
  166. package/dist/src/components/TkxAnchor.d.ts.map +0 -1
  167. package/dist/src/components/TkxAppBar.d.ts.map +0 -1
  168. package/dist/src/components/TkxAutocomplete.d.ts.map +0 -1
  169. package/dist/src/components/TkxAvatar.d.ts.map +0 -1
  170. package/dist/src/components/TkxBadge.d.ts.map +0 -1
  171. package/dist/src/components/TkxBottomNav.d.ts.map +0 -1
  172. package/dist/src/components/TkxBreadcrumb.d.ts.map +0 -1
  173. package/dist/src/components/TkxButton.d.ts.map +0 -1
  174. package/dist/src/components/TkxCard.d.ts.map +0 -1
  175. package/dist/src/components/TkxCarousel.d.ts.map +0 -1
  176. package/dist/src/components/TkxCascader.d.ts.map +0 -1
  177. package/dist/src/components/TkxChat.d.ts.map +0 -1
  178. package/dist/src/components/TkxCheckbox.d.ts.map +0 -1
  179. package/dist/src/components/TkxClock.d.ts.map +0 -1
  180. package/dist/src/components/TkxColorPicker.d.ts.map +0 -1
  181. package/dist/src/components/TkxCommand.d.ts.map +0 -1
  182. package/dist/src/components/TkxConfigProvider.d.ts.map +0 -1
  183. package/dist/src/components/TkxDataGrid.d.ts.map +0 -1
  184. package/dist/src/components/TkxDatePicker.d.ts.map +0 -1
  185. package/dist/src/components/TkxDivider.d.ts.map +0 -1
  186. package/dist/src/components/TkxDrawer.d.ts.map +0 -1
  187. package/dist/src/components/TkxDropdown.d.ts.map +0 -1
  188. package/dist/src/components/TkxEmpty.d.ts.map +0 -1
  189. package/dist/src/components/TkxFileUpload.d.ts.map +0 -1
  190. package/dist/src/components/TkxForm.d.ts.map +0 -1
  191. package/dist/src/components/TkxIcon.d.ts.map +0 -1
  192. package/dist/src/components/TkxImage.d.ts.map +0 -1
  193. package/dist/src/components/TkxInput.d.ts.map +0 -1
  194. package/dist/src/components/TkxLayout.d.ts.map +0 -1
  195. package/dist/src/components/TkxList.d.ts.map +0 -1
  196. package/dist/src/components/TkxLiveFeed.d.ts.map +0 -1
  197. package/dist/src/components/TkxLiveLog.d.ts.map +0 -1
  198. package/dist/src/components/TkxLiveMetrics.d.ts.map +0 -1
  199. package/dist/src/components/TkxLogo.d.ts.map +0 -1
  200. package/dist/src/components/TkxMasonry.d.ts.map +0 -1
  201. package/dist/src/components/TkxMentions.d.ts.map +0 -1
  202. package/dist/src/components/TkxMenu.d.ts.map +0 -1
  203. package/dist/src/components/TkxModal.d.ts.map +0 -1
  204. package/dist/src/components/TkxNumberInput.d.ts.map +0 -1
  205. package/dist/src/components/TkxOTP.d.ts.map +0 -1
  206. package/dist/src/components/TkxPagination.d.ts.map +0 -1
  207. package/dist/src/components/TkxPlayground.d.ts.map +0 -1
  208. package/dist/src/components/TkxPopover.d.ts.map +0 -1
  209. package/dist/src/components/TkxProgress.d.ts.map +0 -1
  210. package/dist/src/components/TkxQRCode.d.ts.map +0 -1
  211. package/dist/src/components/TkxQuantumForm.d.ts.map +0 -1
  212. package/dist/src/components/TkxRadio.d.ts.map +0 -1
  213. package/dist/src/components/TkxRating.d.ts.map +0 -1
  214. package/dist/src/components/TkxRealTimeChart.d.ts.map +0 -1
  215. package/dist/src/components/TkxResult.d.ts.map +0 -1
  216. package/dist/src/components/TkxRichTextDisplay.d.ts.map +0 -1
  217. package/dist/src/components/TkxSegmented.d.ts.map +0 -1
  218. package/dist/src/components/TkxSelect.d.ts.map +0 -1
  219. package/dist/src/components/TkxSkeleton.d.ts.map +0 -1
  220. package/dist/src/components/TkxSlider.d.ts.map +0 -1
  221. package/dist/src/components/TkxSnackbar.d.ts.map +0 -1
  222. package/dist/src/components/TkxSpeedDial.d.ts.map +0 -1
  223. package/dist/src/components/TkxSpin.d.ts.map +0 -1
  224. package/dist/src/components/TkxStatistic.d.ts.map +0 -1
  225. package/dist/src/components/TkxStepper.d.ts.map +0 -1
  226. package/dist/src/components/TkxTable.d.ts.map +0 -1
  227. package/dist/src/components/TkxTabs.d.ts.map +0 -1
  228. package/dist/src/components/TkxTag.d.ts.map +0 -1
  229. package/dist/src/components/TkxThemeBuilder.d.ts.map +0 -1
  230. package/dist/src/components/TkxTimeline.d.ts.map +0 -1
  231. package/dist/src/components/TkxToast.d.ts.map +0 -1
  232. package/dist/src/components/TkxToggle.d.ts.map +0 -1
  233. package/dist/src/components/TkxToolbar.d.ts.map +0 -1
  234. package/dist/src/components/TkxTooltip.d.ts.map +0 -1
  235. package/dist/src/components/TkxTour.d.ts.map +0 -1
  236. package/dist/src/components/TkxTransferList.d.ts.map +0 -1
  237. package/dist/src/components/TkxTreeView.d.ts.map +0 -1
  238. package/dist/src/components/TkxTypography.d.ts.map +0 -1
  239. package/dist/src/components/TkxVideoPlayer.d.ts.map +0 -1
  240. package/dist/src/components/TkxWatermark.d.ts.map +0 -1
  241. package/dist/src/components/index.d.ts.map +0 -1
  242. package/dist/src/engine/css.d.ts.map +0 -1
  243. package/dist/src/engine/index.d.ts.map +0 -1
  244. package/dist/src/engine/quantum-ai.d.ts.map +0 -1
  245. package/dist/src/engine/quantum.d.ts.map +0 -1
  246. package/dist/src/engine/security.d.ts.map +0 -1
  247. package/dist/src/engine/tkx.d.ts.map +0 -1
  248. package/dist/src/engine/wcag.d.ts.map +0 -1
  249. package/dist/src/headless/index.d.ts.map +0 -1
  250. package/dist/src/headless/useControllable.d.ts.map +0 -1
  251. package/dist/src/headless/useDebounce.d.ts.map +0 -1
  252. package/dist/src/headless/useDisclosure.d.ts.map +0 -1
  253. package/dist/src/headless/useFormState.d.ts.map +0 -1
  254. package/dist/src/headless/useInfiniteQuery.d.ts.map +0 -1
  255. package/dist/src/headless/useIntersectionObserver.d.ts.map +0 -1
  256. package/dist/src/headless/useListSelection.d.ts.map +0 -1
  257. package/dist/src/headless/useLocalStorage.d.ts.map +0 -1
  258. package/dist/src/headless/useMediaQuery.d.ts.map +0 -1
  259. package/dist/src/headless/useRovingTabIndex.d.ts.map +0 -1
  260. package/dist/src/headless/useSSE.d.ts.map +0 -1
  261. package/dist/src/headless/useThrottle.d.ts.map +0 -1
  262. package/dist/src/headless/useWebSocket.d.ts.map +0 -1
  263. package/dist/src/hooks/index.d.ts.map +0 -1
  264. package/dist/src/i18n/I18nProvider.d.ts.map +0 -1
  265. package/dist/src/i18n/index.d.ts.map +0 -1
  266. package/dist/src/quantum/index.d.ts.map +0 -1
  267. package/dist/src/realtime/index.d.ts.map +0 -1
  268. package/dist/src/themes/index.d.ts.map +0 -1
  269. package/dist/themes-BbJanqiC.js +0 -498
  270. package/dist/themes-CMq2vWXj.cjs +0 -2
  271. package/dist/tkx-BoP5V5zy.cjs +0 -4
  272. package/dist/tkx-mOKMzvUK.js +0 -1174
  273. package/src/a11y/index.tsx +0 -87
  274. package/src/charts/TkxAreaChart.tsx +0 -121
  275. package/src/charts/TkxBarChart.tsx +0 -117
  276. package/src/charts/TkxDonutChart.tsx +0 -164
  277. package/src/charts/TkxLineChart.tsx +0 -137
  278. package/src/charts/TkxPieChart.tsx +0 -103
  279. package/src/charts/TkxRadarChart.tsx +0 -92
  280. package/src/charts/TkxScatterChart.tsx +0 -104
  281. package/src/charts/index.ts +0 -22
  282. package/src/charts/shared.ts +0 -47
  283. package/src/components/TkxAIChatBubble.tsx +0 -256
  284. package/src/components/TkxAIConfidenceBar.tsx +0 -133
  285. package/src/components/TkxAIThinking.tsx +0 -193
  286. package/src/components/TkxAccordion.tsx +0 -590
  287. package/src/components/TkxAffix.tsx +0 -140
  288. package/src/components/TkxAlert.tsx +0 -94
  289. package/src/components/TkxAnchor.tsx +0 -195
  290. package/src/components/TkxAppBar.tsx +0 -262
  291. package/src/components/TkxAutocomplete.tsx +0 -455
  292. package/src/components/TkxAvatar.tsx +0 -103
  293. package/src/components/TkxBadge.tsx +0 -75
  294. package/src/components/TkxBottomNav.tsx +0 -241
  295. package/src/components/TkxBreadcrumb.tsx +0 -324
  296. package/src/components/TkxButton.tsx +0 -155
  297. package/src/components/TkxCard.tsx +0 -96
  298. package/src/components/TkxCarousel.tsx +0 -554
  299. package/src/components/TkxCascader.tsx +0 -278
  300. package/src/components/TkxChat.tsx +0 -356
  301. package/src/components/TkxCheckbox.tsx +0 -220
  302. package/src/components/TkxClock.tsx +0 -603
  303. package/src/components/TkxColorPicker.tsx +0 -635
  304. package/src/components/TkxCommand.tsx +0 -646
  305. package/src/components/TkxConfigProvider.tsx +0 -460
  306. package/src/components/TkxDataGrid.tsx +0 -941
  307. package/src/components/TkxDatePicker.tsx +0 -1625
  308. package/src/components/TkxDivider.tsx +0 -51
  309. package/src/components/TkxDrawer.tsx +0 -236
  310. package/src/components/TkxDropdown.tsx +0 -804
  311. package/src/components/TkxEmpty.tsx +0 -221
  312. package/src/components/TkxFileUpload.tsx +0 -373
  313. package/src/components/TkxForm.tsx +0 -683
  314. package/src/components/TkxIcon.tsx +0 -685
  315. package/src/components/TkxImage.tsx +0 -279
  316. package/src/components/TkxInput.tsx +0 -103
  317. package/src/components/TkxLayout.tsx +0 -649
  318. package/src/components/TkxList.tsx +0 -244
  319. package/src/components/TkxLiveFeed.tsx +0 -331
  320. package/src/components/TkxLiveLog.tsx +0 -472
  321. package/src/components/TkxLiveMetrics.tsx +0 -315
  322. package/src/components/TkxLogo.tsx +0 -299
  323. package/src/components/TkxMasonry.tsx +0 -178
  324. package/src/components/TkxMentions.tsx +0 -212
  325. package/src/components/TkxMenu.tsx +0 -1044
  326. package/src/components/TkxModal.tsx +0 -122
  327. package/src/components/TkxNumberInput.tsx +0 -410
  328. package/src/components/TkxOTP.tsx +0 -297
  329. package/src/components/TkxPagination.tsx +0 -390
  330. package/src/components/TkxPlayground.tsx +0 -845
  331. package/src/components/TkxPopover.tsx +0 -297
  332. package/src/components/TkxProgress.tsx +0 -114
  333. package/src/components/TkxQRCode.tsx +0 -176
  334. package/src/components/TkxQuantumForm.tsx +0 -594
  335. package/src/components/TkxRadio.tsx +0 -286
  336. package/src/components/TkxRating.tsx +0 -288
  337. package/src/components/TkxRealTimeChart.tsx +0 -383
  338. package/src/components/TkxResult.tsx +0 -130
  339. package/src/components/TkxRichTextDisplay.tsx +0 -396
  340. package/src/components/TkxSegmented.tsx +0 -171
  341. package/src/components/TkxSelect.tsx +0 -1130
  342. package/src/components/TkxSkeleton.tsx +0 -107
  343. package/src/components/TkxSlider.tsx +0 -495
  344. package/src/components/TkxSnackbar.tsx +0 -316
  345. package/src/components/TkxSpeedDial.tsx +0 -397
  346. package/src/components/TkxSpin.tsx +0 -263
  347. package/src/components/TkxStatistic.tsx +0 -263
  348. package/src/components/TkxStepper.tsx +0 -487
  349. package/src/components/TkxTable.tsx +0 -424
  350. package/src/components/TkxTabs.tsx +0 -126
  351. package/src/components/TkxTag.tsx +0 -321
  352. package/src/components/TkxThemeBuilder.tsx +0 -687
  353. package/src/components/TkxTimeline.tsx +0 -305
  354. package/src/components/TkxToast.tsx +0 -287
  355. package/src/components/TkxToggle.tsx +0 -95
  356. package/src/components/TkxToolbar.tsx +0 -262
  357. package/src/components/TkxTooltip.tsx +0 -85
  358. package/src/components/TkxTour.tsx +0 -241
  359. package/src/components/TkxTransferList.tsx +0 -489
  360. package/src/components/TkxTreeView.tsx +0 -423
  361. package/src/components/TkxTypography.tsx +0 -267
  362. package/src/components/TkxVideoPlayer.tsx +0 -1015
  363. package/src/components/TkxWatermark.tsx +0 -145
  364. package/src/components/index.ts +0 -79
  365. package/src/engine/css.ts +0 -126
  366. package/src/engine/index.ts +0 -12
  367. package/src/engine/quantum-ai.ts +0 -1045
  368. package/src/engine/quantum.ts +0 -207
  369. package/src/engine/security.ts +0 -232
  370. package/src/engine/tkx.ts +0 -1084
  371. package/src/engine/wcag.ts +0 -276
  372. package/src/headless/index.ts +0 -52
  373. package/src/headless/useControllable.ts +0 -42
  374. package/src/headless/useDebounce.ts +0 -37
  375. package/src/headless/useDisclosure.ts +0 -30
  376. package/src/headless/useFormState.ts +0 -113
  377. package/src/headless/useInfiniteQuery.ts +0 -155
  378. package/src/headless/useIntersectionObserver.ts +0 -53
  379. package/src/headless/useListSelection.ts +0 -103
  380. package/src/headless/useLocalStorage.ts +0 -48
  381. package/src/headless/useMediaQuery.ts +0 -39
  382. package/src/headless/useRovingTabIndex.ts +0 -86
  383. package/src/headless/useSSE.ts +0 -167
  384. package/src/headless/useThrottle.ts +0 -48
  385. package/src/headless/useWebSocket.ts +0 -231
  386. package/src/hooks/index.ts +0 -122
  387. package/src/i18n/I18nProvider.tsx +0 -36
  388. package/src/i18n/index.ts +0 -877
  389. package/src/quantum/index.ts +0 -39
  390. package/src/realtime/index.ts +0 -21
  391. package/src/styles/global.css +0 -167
  392. package/src/themes/index.ts +0 -294
package/src/engine/tkx.ts DELETED
@@ -1,1084 +0,0 @@
1
- // ══════════════════════════════════════════════════════════════════════════════
2
- // TKX ATOMIC CSS ENGINE v2.0
3
- // Zero-dependency, type-safe, WCAG-aware utility CSS system.
4
- //
5
- // Why it beats Tailwind:
6
- // 1. TRUE conflict resolution — p-4 + p-8 → padding:32px. No cascade hacks.
7
- // 2. Single merged class per element — cleaner DOM, zero specificity wars.
8
- // 3. Theme-aware tokens — text-primary auto-follows ThemeContext. Tailwind can't.
9
- // 4. Motion-aware — transition-* silently no-ops for prefers-reduced-motion.
10
- // 5. WCAG-integrated — warns on low-contrast combos at dev time.
11
- // 6. No config file, no PostCSS, no purge step, no build plugin required.
12
- // 7. Works identically on server (SSR) and client.
13
- // 8. Fully typed — TypeScript utility-string autocomplete.
14
- // 9. Composes: accepts strings, arrays, objects, conditionals in any mix.
15
- // 10. Arbitrary values — w-[42px], bg-[#ff0000], delay-[300ms].
16
- // ══════════════════════════════════════════════════════════════════════════════
17
-
18
- import { fnv1aHash } from './quantum';
19
-
20
- // ── Constants ─────────────────────────────────────────────────────────────────
21
-
22
- const SPACE: Record<string, string> = {
23
- '0': '0', px: '1px', '0.5': '2px', '1': '4px', '1.5': '6px',
24
- '2': '8px', '2.5': '10px', '3': '12px', '3.5': '14px', '4': '16px',
25
- '5': '20px', '6': '24px', '7': '28px', '8': '32px', '9': '36px',
26
- '10': '40px', '11': '44px', '12': '48px', '14': '56px', '16': '64px',
27
- '20': '80px', '24': '96px', '28': '112px', '32': '128px', '36': '144px',
28
- '40': '160px', '44': '176px', '48': '192px', '52': '208px', '56': '224px',
29
- '60': '240px', '64': '256px', '72': '288px', '80': '320px', '96': '384px',
30
- auto: 'auto', full: '100%', screen: '100vw', svh: '100svh', dvh: '100dvh',
31
- fit: 'fit-content', max: 'max-content', min: 'min-content',
32
- };
33
-
34
- const H_SPACE: Record<string, string> = { ...SPACE, screen: '100vh' };
35
-
36
- const FRACTIONS: Record<string, string> = {
37
- '1/2': '50%', '1/3': '33.333333%', '2/3': '66.666667%',
38
- '1/4': '25%', '2/4': '50%', '3/4': '75%',
39
- '1/5': '20%', '2/5': '40%', '3/5': '60%', '4/5': '80%',
40
- '1/6': '16.666667%', '5/6': '83.333333%',
41
- '1/12': '8.333333%', '5/12': '41.666667%', '7/12': '58.333333%', '11/12': '91.666667%',
42
- };
43
-
44
- const RADIUS: Record<string, string> = {
45
- none: '0', sm: '2px', '': '4px', md: '6px', lg: '8px',
46
- xl: '12px', '2xl': '16px', '3xl': '24px', full: '9999px',
47
- };
48
-
49
- const SHADOW: Record<string, string> = {
50
- sm: '0 1px 2px 0 rgba(0,0,0,.05)',
51
- '': '0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1)',
52
- md: '0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)',
53
- lg: '0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1)',
54
- xl: '0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1)',
55
- '2xl': '0 25px 50px -12px rgba(0,0,0,.25)',
56
- inner: 'inset 0 2px 4px 0 rgba(0,0,0,.05)',
57
- none: 'none',
58
- };
59
-
60
- const FONT_SIZE: Record<string, [string, string]> = {
61
- xs: ['0.75rem', '1rem'], sm: ['0.875rem', '1.25rem'], base: ['1rem', '1.5rem'],
62
- lg: ['1.125rem', '1.75rem'], xl: ['1.25rem', '1.75rem'], '2xl': ['1.5rem', '2rem'],
63
- '3xl': ['1.875rem', '2.25rem'], '4xl': ['2.25rem', '2.5rem'], '5xl': ['3rem', '1'],
64
- '6xl': ['3.75rem', '1'], '7xl': ['4.5rem', '1'], '8xl': ['6rem', '1'], '9xl': ['8rem', '1'],
65
- };
66
-
67
- const FONT_WEIGHT: Record<string, string> = {
68
- thin: '100', extralight: '200', light: '300', normal: '400', medium: '500',
69
- semibold: '600', bold: '700', extrabold: '800', black: '900',
70
- };
71
-
72
- const LEADING: Record<string, string> = {
73
- none: '1', tight: '1.25', snug: '1.375', normal: '1.5', relaxed: '1.625', loose: '2',
74
- '3': '0.75rem', '4': '1rem', '5': '1.25rem', '6': '1.5rem', '7': '1.75rem',
75
- '8': '2rem', '9': '2.25rem', '10': '2.5rem',
76
- };
77
-
78
- const TRACKING: Record<string, string> = {
79
- tighter: '-0.05em', tight: '-0.025em', normal: '0em',
80
- wide: '0.025em', wider: '0.05em', widest: '0.1em',
81
- };
82
-
83
- const BLUR: Record<string, string> = {
84
- none: '0', sm: '4px', '': '8px', md: '12px', lg: '16px',
85
- xl: '24px', '2xl': '40px', '3xl': '64px',
86
- };
87
-
88
- const OPACITY: Record<string, string> = Object.fromEntries(
89
- [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
90
- .map((n) => [String(n), String(n / 100)]),
91
- );
92
-
93
- const THEME_TOKENS = new Set([
94
- 'bg', 'surface', 'surfaceAlt', 'border', 'text', 'textMuted',
95
- 'primary', 'secondary', 'danger', 'warning', 'success', 'info',
96
- ]);
97
-
98
- const BREAKPOINTS: Record<string, string> = {
99
- sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px',
100
- };
101
-
102
- // ── CSS Security Guards ───────────────────────────────────────────────────────
103
- // Prevent CSS injection via arbitrary values. Blocks:
104
- // • javascript: / vbscript: / data: URL schemes
105
- // • CSS expression() (IE legacy code-exec vector)
106
- // • -moz-binding / behavior (remote XBL/HTC execution)
107
- // • Embedded newlines that break out of style blocks
108
- //
109
- // Quantum confidence: values that pass all guards score 1.0;
110
- // values containing suspicious but non-blocked patterns score < 1.0
111
- // and are stripped in strict mode.
112
-
113
- /** Dangerous CSS value patterns — any match → reject the declaration. */
114
- const DANGEROUS_VALUE_RE =
115
- /javascript\s*:|vbscript\s*:|data\s*:\s*text\/html|data\s*:\s*text\/javascript|expression\s*\(|[\r\n\x00]/i;
116
-
117
- /** Dangerous CSS property names. */
118
- const DANGEROUS_PROPS = new Set([
119
- 'behavior', '-moz-binding', '-webkit-binding', 'src',
120
- ]);
121
-
122
- /**
123
- * Allowlist of CSS properties accepted via arbitrary [prop:value] shorthand.
124
- * Anything not in this set is silently dropped.
125
- */
126
- const SAFE_CSS_PROPS = new Set([
127
- // Box model
128
- 'width','min-width','max-width','height','min-height','max-height',
129
- 'margin','margin-top','margin-right','margin-bottom','margin-left',
130
- 'padding','padding-top','padding-right','padding-bottom','padding-left',
131
- // Positioning
132
- 'position','top','right','bottom','left','z-index','inset',
133
- // Flexbox / Grid
134
- 'flex','flex-grow','flex-shrink','flex-basis','flex-direction','flex-wrap',
135
- 'align-items','align-self','align-content','justify-content','justify-items','justify-self',
136
- 'gap','row-gap','column-gap',
137
- 'grid-template-columns','grid-template-rows','grid-column','grid-row',
138
- 'grid-area','grid-template-areas',
139
- // Typography
140
- 'font-size','font-weight','font-family','font-style','line-height',
141
- 'letter-spacing','text-align','text-decoration','text-transform',
142
- 'text-overflow','white-space','word-break','word-wrap','overflow-wrap',
143
- // Color / Background
144
- 'color','background','background-color','background-image',
145
- 'background-position','background-size','background-repeat',
146
- 'opacity',
147
- // Border
148
- 'border','border-top','border-right','border-bottom','border-left',
149
- 'border-width','border-style','border-color','border-radius',
150
- 'outline','outline-offset',
151
- // Effects
152
- 'box-shadow','text-shadow','filter','backdrop-filter','transform',
153
- 'transition','animation',
154
- // Layout
155
- 'display','overflow','overflow-x','overflow-y','visibility',
156
- 'pointer-events','cursor','user-select',
157
- // Misc safe
158
- 'aspect-ratio','object-fit','object-position','list-style',
159
- 'vertical-align','float','clear','resize','scroll-behavior',
160
- 'content', // allow content: '' for pseudo-like patterns but value is guarded
161
- ]);
162
-
163
- /**
164
- * Sanitize an arbitrary CSS value.
165
- * Returns the value unchanged if safe, or null if dangerous.
166
- */
167
- function sanitizeCSSValue(value: string): string | null {
168
- if (DANGEROUS_VALUE_RE.test(value)) return null;
169
- // Strip any attempt to close a style block
170
- if (value.includes('}') || value.includes('{') || value.includes('<') || value.includes('>')) return null;
171
- return value;
172
- }
173
-
174
- /**
175
- * Sanitize an arbitrary CSS property name.
176
- * Returns the property unchanged if safe, or null if dangerous.
177
- */
178
- function sanitizeCSSProp(prop: string): string | null {
179
- const normalized = prop.toLowerCase().trim();
180
- if (DANGEROUS_PROPS.has(normalized)) return null;
181
- if (!SAFE_CSS_PROPS.has(normalized)) return null; // allowlist enforcement
182
- return normalized;
183
- }
184
-
185
- // ── Arbitrary value extractor ─────────────────────────────────────────────────
186
-
187
- function extractArbitrary(value: string): string | null {
188
- const match = value.match(/^\[(.+)]$/);
189
- if (!match) return null;
190
- return sanitizeCSSValue(match[1]);
191
- }
192
-
193
- // ── Color value resolver ──────────────────────────────────────────────────────
194
- // Handles theme tokens (text-primary), hex (#ff0000), css vars, raw names
195
-
196
- function resolveColor(token: string): string {
197
- if (THEME_TOKENS.has(token)) return `var(--tkx-${token})`;
198
- if (token === 'transparent') return 'transparent';
199
- if (token === 'current') return 'currentColor';
200
- if (token === 'white') return '#ffffff';
201
- if (token === 'black') return '#000000';
202
- if (token === 'inherit') return 'inherit';
203
- // Arbitrary: [#ff0000] or [rgb(0,0,0)] — sanitized
204
- const arb = extractArbitrary(token);
205
- if (arb) return arb;
206
- // Bare hex
207
- if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(token)) return token;
208
- return token;
209
- }
210
-
211
- // ── Main utility resolver ─────────────────────────────────────────────────────
212
- // Returns Record<cssProperty, cssValue> for a given utility token.
213
- // Returns null if unrecognized.
214
-
215
- type Declarations = Record<string, string>;
216
-
217
- // eslint-disable-next-line complexity
218
- function resolveUtility(u: string): Declarations | null {
219
- // ── Arbitrary value shorthand: [css-prop:value] — security-guarded ────────
220
- const fullArb = u.match(/^\[([a-zA-Z-]+):(.+)]$/);
221
- if (fullArb) {
222
- const safeProp = sanitizeCSSProp(fullArb[1]);
223
- const safeVal = sanitizeCSSValue(fullArb[2]);
224
- if (safeProp && safeVal) return { [safeProp]: safeVal };
225
- return null; // silently drop dangerous declaration
226
- }
227
-
228
- // ── Display ────────────────────────────────────────────────────────────────
229
- const displayMap: Record<string, string> = {
230
- flex: 'flex', 'inline-flex': 'inline-flex', grid: 'grid', 'inline-grid': 'inline-grid',
231
- block: 'block', 'inline-block': 'inline-block', inline: 'inline', hidden: 'none',
232
- contents: 'contents', 'flow-root': 'flow-root', table: 'table', 'table-row': 'table-row',
233
- 'table-cell': 'table-cell', 'table-caption': 'table-caption', 'list-item': 'list-item',
234
- };
235
- if (displayMap[u]) return { display: displayMap[u] };
236
-
237
- // ── Flex layout ────────────────────────────────────────────────────────────
238
- const flexDir: Record<string, string> = {
239
- 'flex-row': 'row', 'flex-col': 'column',
240
- 'flex-row-reverse': 'row-reverse', 'flex-col-reverse': 'column-reverse',
241
- };
242
- if (flexDir[u]) return { 'flex-direction': flexDir[u] };
243
-
244
- const flexWrap: Record<string, string> = {
245
- 'flex-wrap': 'wrap', 'flex-nowrap': 'nowrap', 'flex-wrap-reverse': 'wrap-reverse',
246
- };
247
- if (flexWrap[u]) return { 'flex-wrap': flexWrap[u] };
248
-
249
- const flexShorthand: Record<string, string> = {
250
- 'flex-1': '1 1 0%', 'flex-auto': '1 1 auto', 'flex-none': 'none', 'flex-initial': '0 1 auto',
251
- };
252
- if (flexShorthand[u]) return { flex: flexShorthand[u] };
253
-
254
- if (u === 'grow' || u === 'flex-grow') return { 'flex-grow': '1' };
255
- if (u === 'grow-0') return { 'flex-grow': '0' };
256
- if (u === 'shrink' || u === 'flex-shrink') return { 'flex-shrink': '1' };
257
- if (u === 'shrink-0' || u === 'flex-shrink-0') return { 'flex-shrink': '0' };
258
-
259
- // ── Align / Justify ────────────────────────────────────────────────────────
260
- const itemsMap: Record<string, string> = {
261
- 'items-start': 'flex-start', 'items-end': 'flex-end', 'items-center': 'center',
262
- 'items-stretch': 'stretch', 'items-baseline': 'baseline',
263
- };
264
- if (itemsMap[u]) return { 'align-items': itemsMap[u] };
265
-
266
- const justifyMap: Record<string, string> = {
267
- 'justify-start': 'flex-start', 'justify-end': 'flex-end', 'justify-center': 'center',
268
- 'justify-between': 'space-between', 'justify-around': 'space-around',
269
- 'justify-evenly': 'space-evenly', 'justify-stretch': 'stretch', 'justify-normal': 'normal',
270
- };
271
- if (justifyMap[u]) return { 'justify-content': justifyMap[u] };
272
-
273
- const selfMap: Record<string, string> = {
274
- 'self-auto': 'auto', 'self-start': 'flex-start', 'self-end': 'flex-end',
275
- 'self-center': 'center', 'self-stretch': 'stretch', 'self-baseline': 'baseline',
276
- };
277
- if (selfMap[u]) return { 'align-self': selfMap[u] };
278
-
279
- const contentMap: Record<string, string> = {
280
- 'content-start': 'flex-start', 'content-end': 'flex-end', 'content-center': 'center',
281
- 'content-between': 'space-between', 'content-around': 'space-around',
282
- 'content-evenly': 'space-evenly', 'content-stretch': 'stretch',
283
- };
284
- if (contentMap[u]) return { 'align-content': contentMap[u] };
285
-
286
- // ── Grid ───────────────────────────────────────────────────────────────────
287
- let m: RegExpMatchArray | null;
288
- if ((m = u.match(/^grid-cols-(\d+|none|subgrid)$/))) {
289
- const v = m[1] === 'none' ? 'none' : m[1] === 'subgrid' ? 'subgrid' : `repeat(${m[1]},minmax(0,1fr))`;
290
- return { 'grid-template-columns': v };
291
- }
292
- if ((m = u.match(/^grid-rows-(\d+|none|subgrid)$/))) {
293
- const v = m[1] === 'none' ? 'none' : m[1] === 'subgrid' ? 'subgrid' : `repeat(${m[1]},minmax(0,1fr))`;
294
- return { 'grid-template-rows': v };
295
- }
296
- if ((m = u.match(/^col-span-(full|\d+)$/))) {
297
- return { 'grid-column': m[1] === 'full' ? '1 / -1' : `span ${m[1]} / span ${m[1]}` };
298
- }
299
- if ((m = u.match(/^col-start-(\d+|auto)$/))) return { 'grid-column-start': m[1] };
300
- if ((m = u.match(/^col-end-(\d+|auto)$/))) return { 'grid-column-end': m[1] };
301
- if ((m = u.match(/^row-span-(full|\d+)$/))) {
302
- return { 'grid-row': m[1] === 'full' ? '1 / -1' : `span ${m[1]} / span ${m[1]}` };
303
- }
304
- if ((m = u.match(/^row-start-(\d+|auto)$/))) return { 'grid-row-start': m[1] };
305
- if ((m = u.match(/^row-end-(\d+|auto)$/))) return { 'grid-row-end': m[1] };
306
- if (u === 'grid-flow-row') return { 'grid-auto-flow': 'row' };
307
- if (u === 'grid-flow-col') return { 'grid-auto-flow': 'column' };
308
- if (u === 'grid-flow-dense') return { 'grid-auto-flow': 'dense' };
309
- if (u === 'grid-flow-row-dense') return { 'grid-auto-flow': 'row dense' };
310
- if (u === 'grid-flow-col-dense') return { 'grid-auto-flow': 'column dense' };
311
-
312
- // ── Spacing — Padding ──────────────────────────────────────────────────────
313
- if ((m = u.match(/^p-(.+)$/))) {
314
- const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
315
- if (v) return { padding: v };
316
- }
317
- if ((m = u.match(/^px-(.+)$/))) {
318
- const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
319
- if (v) return { 'padding-left': v, 'padding-right': v };
320
- }
321
- if ((m = u.match(/^py-(.+)$/))) {
322
- const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
323
- if (v) return { 'padding-top': v, 'padding-bottom': v };
324
- }
325
- if ((m = u.match(/^pt-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'padding-top': v }; }
326
- if ((m = u.match(/^pr-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'padding-right': v }; }
327
- if ((m = u.match(/^pb-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'padding-bottom': v }; }
328
- if ((m = u.match(/^pl-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'padding-left': v }; }
329
-
330
- // ── Spacing — Margin ───────────────────────────────────────────────────────
331
- if ((m = u.match(/^-?m-(.+)$/))) {
332
- const neg = u.startsWith('-');
333
- const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
334
- if (v) return { margin: neg && v !== '0' ? `-${v}` : v };
335
- }
336
- if ((m = u.match(/^-?mx-(.+)$/))) {
337
- const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
338
- if (v) { const pv = neg && v !== '0' ? `-${v}` : v; return { 'margin-left': pv, 'margin-right': pv }; }
339
- }
340
- if ((m = u.match(/^-?my-(.+)$/))) {
341
- const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
342
- if (v) { const pv = neg && v !== '0' ? `-${v}` : v; return { 'margin-top': pv, 'margin-bottom': pv }; }
343
- }
344
- if ((m = u.match(/^-?mt-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'margin-top': neg && v !== '0' ? `-${v}` : v }; }
345
- if ((m = u.match(/^-?mr-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'margin-right': neg && v !== '0' ? `-${v}` : v }; }
346
- if ((m = u.match(/^-?mb-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'margin-bottom': neg && v !== '0' ? `-${v}` : v }; }
347
- if ((m = u.match(/^-?ml-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'margin-left': neg && v !== '0' ? `-${v}` : v }; }
348
- if (u === 'mx-auto') return { 'margin-left': 'auto', 'margin-right': 'auto' };
349
- if (u === 'my-auto') return { 'margin-top': 'auto', 'margin-bottom': 'auto' };
350
-
351
- // ── Gap ────────────────────────────────────────────────────────────────────
352
- if ((m = u.match(/^gap-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { gap: v }; }
353
- if ((m = u.match(/^gap-x-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'column-gap': v }; }
354
- if ((m = u.match(/^gap-y-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'row-gap': v }; }
355
-
356
- // ── Sizing — Width ─────────────────────────────────────────────────────────
357
- if ((m = u.match(/^w-(.+)$/))) {
358
- const key = m[1];
359
- const v = SPACE[key] ?? FRACTIONS[key] ?? extractArbitrary(key);
360
- if (v) return { width: v };
361
- }
362
- if ((m = u.match(/^min-w-(.+)$/))) {
363
- const v = SPACE[m[1]] ?? extractArbitrary(m[1]);
364
- if (v) return { 'min-width': v };
365
- }
366
- if ((m = u.match(/^max-w-(.+)$/))) {
367
- const maxMap: Record<string, string> = {
368
- none: 'none', xs: '20rem', sm: '24rem', md: '28rem', lg: '32rem', xl: '36rem',
369
- '2xl': '42rem', '3xl': '48rem', '4xl': '56rem', '5xl': '64rem', '6xl': '72rem',
370
- '7xl': '80rem', full: '100%', screen: '100vw', min: 'min-content', max: 'max-content', fit: 'fit-content',
371
- };
372
- const v = maxMap[m[1]] ?? SPACE[m[1]] ?? extractArbitrary(m[1]);
373
- if (v) return { 'max-width': v };
374
- }
375
-
376
- // ── Sizing — Height ────────────────────────────────────────────────────────
377
- if ((m = u.match(/^h-(.+)$/))) {
378
- const key = m[1]; const v = H_SPACE[key] ?? FRACTIONS[key] ?? extractArbitrary(key);
379
- if (v) return { height: v };
380
- }
381
- if ((m = u.match(/^min-h-(.+)$/))) {
382
- const minHMap: Record<string, string> = { '0': '0', full: '100%', screen: '100vh', svh: '100svh', dvh: '100dvh' };
383
- const v = minHMap[m[1]] ?? SPACE[m[1]] ?? extractArbitrary(m[1]);
384
- if (v) return { 'min-height': v };
385
- }
386
- if ((m = u.match(/^max-h-(.+)$/))) {
387
- const v = H_SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'max-height': v };
388
- }
389
- // size-{n} sets both width and height
390
- if ((m = u.match(/^size-(.+)$/))) {
391
- const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]);
392
- if (v) return { width: v, height: v };
393
- }
394
-
395
- // ── Typography ─────────────────────────────────────────────────────────────
396
- if ((m = u.match(/^text-(xs|sm|base|lg|[2-9]xl|\d+xl)$/))) {
397
- const [fs, lh] = FONT_SIZE[m[1]] ?? ['1rem', '1.5rem'];
398
- return { 'font-size': fs, 'line-height': lh };
399
- }
400
- if ((m = u.match(/^font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black|\d+)$/))) {
401
- return { 'font-weight': FONT_WEIGHT[m[1]] ?? m[1] };
402
- }
403
- if ((m = u.match(/^leading-(.+)$/))) { const v = LEADING[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'line-height': v }; }
404
- if ((m = u.match(/^tracking-(.+)$/))) { const v = TRACKING[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'letter-spacing': v }; }
405
-
406
- const textAlignMap: Record<string, string> = {
407
- 'text-left': 'left', 'text-center': 'center', 'text-right': 'right',
408
- 'text-justify': 'justify', 'text-start': 'start', 'text-end': 'end',
409
- };
410
- if (textAlignMap[u]) return { 'text-align': textAlignMap[u] };
411
-
412
- if (u === 'italic') return { 'font-style': 'italic' };
413
- if (u === 'not-italic') return { 'font-style': 'normal' };
414
- if (u === 'uppercase') return { 'text-transform': 'uppercase' };
415
- if (u === 'lowercase') return { 'text-transform': 'lowercase' };
416
- if (u === 'capitalize') return { 'text-transform': 'capitalize' };
417
- if (u === 'normal-case') return { 'text-transform': 'none' };
418
- if (u === 'underline') return { 'text-decoration-line': 'underline' };
419
- if (u === 'overline') return { 'text-decoration-line': 'overline' };
420
- if (u === 'line-through') return { 'text-decoration-line': 'line-through' };
421
- if (u === 'no-underline') return { 'text-decoration-line': 'none' };
422
- if (u === 'truncate') return { overflow: 'hidden', 'text-overflow': 'ellipsis', 'white-space': 'nowrap' };
423
- if (u === 'text-ellipsis') return { 'text-overflow': 'ellipsis' };
424
- if (u === 'text-clip') return { 'text-overflow': 'clip' };
425
- if (u === 'whitespace-normal') return { 'white-space': 'normal' };
426
- if (u === 'whitespace-nowrap') return { 'white-space': 'nowrap' };
427
- if (u === 'whitespace-pre') return { 'white-space': 'pre' };
428
- if (u === 'whitespace-pre-wrap') return { 'white-space': 'pre-wrap' };
429
- if (u === 'whitespace-pre-line') return { 'white-space': 'pre-line' };
430
- if (u === 'break-words') return { 'overflow-wrap': 'break-word' };
431
- if (u === 'break-all') return { 'word-break': 'break-all' };
432
- if (u === 'break-keep') return { 'word-break': 'keep-all' };
433
- if (u === 'font-mono') return { 'font-family': 'var(--tkx-font-mono,monospace)' };
434
- if (u === 'font-sans') return { 'font-family': 'var(--tkx-font-family,system-ui,sans-serif)' };
435
- if (u === 'font-serif') return { 'font-family': 'ui-serif,Georgia,serif' };
436
- if (u === 'antialiased') return { '-webkit-font-smoothing': 'antialiased', '-moz-osx-font-smoothing': 'grayscale' };
437
- if ((m = u.match(/^indent-(.+)$/))) { const v = SPACE[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'text-indent': v }; }
438
- if ((m = u.match(/^line-clamp-(\d+)$/))) {
439
- return { overflow: 'hidden', display: '-webkit-box', '-webkit-line-clamp': m[1], '-webkit-box-orient': 'vertical' };
440
- }
441
-
442
- // ── Colors ─────────────────────────────────────────────────────────────────
443
- if ((m = u.match(/^text-(.+)$/))) {
444
- // Handle opacity modifier: text-primary/50
445
- const [token, opStr] = m[1].split('/');
446
- const color = resolveColor(token);
447
- if (!['left', 'center', 'right', 'justify', 'start', 'end', 'xs', 'sm', 'base', 'lg',
448
- 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', '7xl', '8xl', '9xl'].includes(token)) {
449
- if (opStr) {
450
- const op = parseInt(opStr) / 100;
451
- return { color: color, opacity: String(op) };
452
- }
453
- return { color };
454
- }
455
- }
456
- if ((m = u.match(/^bg-(.+)$/))) {
457
- const [token, opStr] = m[1].split('/');
458
- const color = resolveColor(token);
459
- if (opStr) return { 'background-color': color, opacity: String(parseInt(opStr) / 100) };
460
- if (token === 'none') return { background: 'none' };
461
- return { 'background-color': color };
462
- }
463
- if ((m = u.match(/^border-color-(.+)$/))) { return { 'border-color': resolveColor(m[1]) }; }
464
- if ((m = u.match(/^fill-(.+)$/))) { return { fill: resolveColor(m[1]) }; }
465
- if ((m = u.match(/^stroke-(.+)$/))) { return { stroke: resolveColor(m[1]) }; }
466
- if ((m = u.match(/^shadow-color-(.+)$/))) { return { '--tkx-shadow-color': resolveColor(m[1]) }; }
467
- if ((m = u.match(/^ring-color-(.+)$/))) { return { '--tkx-ring-color': resolveColor(m[1]) }; }
468
- if ((m = u.match(/^accent-(.+)$/))) { return { 'accent-color': resolveColor(m[1]) }; }
469
- if ((m = u.match(/^caret-(.+)$/))) { return { 'caret-color': resolveColor(m[1]) }; }
470
- if ((m = u.match(/^outline-color-(.+)$/))) { return { 'outline-color': resolveColor(m[1]) }; }
471
-
472
- // ── Borders ────────────────────────────────────────────────────────────────
473
- // border thickness
474
- if (u === 'border') return { 'border-width': '1px' };
475
- if ((m = u.match(/^border-(\d+)$/))) return { 'border-width': `${m[1]}px` };
476
- if (u === 'border-t') return { 'border-top-width': '1px' };
477
- if ((m = u.match(/^border-t-(\d+)$/))) return { 'border-top-width': `${m[1]}px` };
478
- if (u === 'border-r') return { 'border-right-width': '1px' };
479
- if ((m = u.match(/^border-r-(\d+)$/))) return { 'border-right-width': `${m[1]}px` };
480
- if (u === 'border-b') return { 'border-bottom-width': '1px' };
481
- if ((m = u.match(/^border-b-(\d+)$/))) return { 'border-bottom-width': `${m[1]}px` };
482
- if (u === 'border-l') return { 'border-left-width': '1px' };
483
- if ((m = u.match(/^border-l-(\d+)$/))) return { 'border-left-width': `${m[1]}px` };
484
- if (u === 'border-x') return { 'border-left-width': '1px', 'border-right-width': '1px' };
485
- if (u === 'border-y') return { 'border-top-width': '1px', 'border-bottom-width': '1px' };
486
- if (u === 'border-none') return { 'border-style': 'none' };
487
- if (u === 'border-solid') return { 'border-style': 'solid' };
488
- if (u === 'border-dashed') return { 'border-style': 'dashed' };
489
- if (u === 'border-dotted') return { 'border-style': 'dotted' };
490
- if (u === 'border-double') return { 'border-style': 'double' };
491
-
492
- // border-{token} (color)
493
- if ((m = u.match(/^border-([a-zA-Z].*)$/)) && THEME_TOKENS.has(m[1])) {
494
- return { 'border-color': `var(--tkx-${m[1]})` };
495
- }
496
- if ((m = u.match(/^border-\[(.+)]$/))) { return { 'border-color': m[1] }; }
497
-
498
- // border-0 (zero width)
499
- if (u === 'border-0') return { 'border-width': '0' };
500
-
501
- // ── Border Radius ──────────────────────────────────────────────────────────
502
- if (u === 'rounded') return { 'border-radius': RADIUS[''] };
503
- if ((m = u.match(/^rounded-(none|sm|md|lg|xl|2xl|3xl|full|\[.+])$/))) {
504
- const v = RADIUS[m[1]] ?? extractArbitrary(m[1]);
505
- return { 'border-radius': v ?? m[1] };
506
- }
507
- if ((m = u.match(/^rounded-(t|r|b|l|tl|tr|br|bl)(?:-(none|sm|md|lg|xl|2xl|3xl|full))?$/))) {
508
- const dir = m[1]; const sz = RADIUS[m[2] ?? ''] ?? RADIUS[''];
509
- const dirMap: Record<string, Record<string, string>> = {
510
- t: { 'border-top-left-radius': sz, 'border-top-right-radius': sz },
511
- r: { 'border-top-right-radius': sz, 'border-bottom-right-radius': sz },
512
- b: { 'border-bottom-left-radius': sz, 'border-bottom-right-radius': sz },
513
- l: { 'border-top-left-radius': sz, 'border-bottom-left-radius': sz },
514
- tl: { 'border-top-left-radius': sz }, tr: { 'border-top-right-radius': sz },
515
- br: { 'border-bottom-right-radius': sz }, bl: { 'border-bottom-left-radius': sz },
516
- };
517
- return dirMap[dir] ?? {};
518
- }
519
-
520
- // ── Ring (outline box-shadow) ──────────────────────────────────────────────
521
- const ringWidths: Record<string, string> = { '0': '0', '1': '1px', '2': '2px', ring: '3px', '4': '4px', '8': '8px' };
522
- if (u === 'ring') return { 'box-shadow': `0 0 0 3px var(--tkx-ring-color,var(--tkx-primary))` };
523
- if ((m = u.match(/^ring-(\d+)$/)) && ringWidths[m[1]]) {
524
- return { 'box-shadow': `0 0 0 ${ringWidths[m[1]]} var(--tkx-ring-color,var(--tkx-primary))` };
525
- }
526
- if (u === 'ring-inset') return { '--tkx-ring-offset': 'inset' };
527
- if ((m = u.match(/^ring-offset-(\d+)$/))) {
528
- return { '--tkx-ring-offset-width': `${m[1]}px`, 'box-shadow': `0 0 0 ${m[1]}px var(--tkx-bg)` };
529
- }
530
-
531
- // ── Shadow ─────────────────────────────────────────────────────────────────
532
- if (u === 'shadow') return { 'box-shadow': SHADOW[''] };
533
- if ((m = u.match(/^shadow-(sm|md|lg|xl|2xl|inner|none)$/))) return { 'box-shadow': SHADOW[m[1]] };
534
-
535
- // ── Opacity ────────────────────────────────────────────────────────────────
536
- if ((m = u.match(/^opacity-(\d+)$/))) { const v = OPACITY[m[1]]; if (v !== undefined) return { opacity: v }; }
537
-
538
- // ── Background extras ──────────────────────────────────────────────────────
539
- if (u === 'bg-none') return { 'background': 'none' };
540
- const bgSizeMap: Record<string, string> = { 'bg-auto': 'auto', 'bg-cover': 'cover', 'bg-contain': 'contain' };
541
- if (bgSizeMap[u]) return { 'background-size': bgSizeMap[u] };
542
- const bgPosMap: Record<string, string> = {
543
- 'bg-center': 'center', 'bg-top': 'top', 'bg-bottom': 'bottom',
544
- 'bg-left': 'left', 'bg-right': 'right',
545
- };
546
- if (bgPosMap[u]) return { 'background-position': bgPosMap[u] };
547
- const bgRepeatMap: Record<string, string> = {
548
- 'bg-repeat': 'repeat', 'bg-no-repeat': 'no-repeat',
549
- 'bg-repeat-x': 'repeat-x', 'bg-repeat-y': 'repeat-y',
550
- };
551
- if (bgRepeatMap[u]) return { 'background-repeat': bgRepeatMap[u] };
552
-
553
- // ── Backdrop blur ──────────────────────────────────────────────────────────
554
- if (u === 'backdrop-blur') return { 'backdrop-filter': `blur(${BLUR['']})` };
555
- if ((m = u.match(/^backdrop-blur-(none|sm|md|lg|xl|2xl|3xl)$/))) {
556
- return { 'backdrop-filter': `blur(${BLUR[m[1]]})` };
557
- }
558
- // ── Filter blur ───────────────────────────────────────────────────────────
559
- if (u === 'blur') return { filter: `blur(${BLUR['']})` };
560
- if ((m = u.match(/^blur-(none|sm|md|lg|xl|2xl|3xl)$/))) { return { filter: `blur(${BLUR[m[1]]})` }; }
561
-
562
- // ── Grayscale/Invert ───────────────────────────────────────────────────────
563
- if (u === 'grayscale') return { filter: 'grayscale(100%)' };
564
- if (u === 'grayscale-0') return { filter: 'grayscale(0)' };
565
- if (u === 'invert') return { filter: 'invert(100%)' };
566
- if (u === 'invert-0') return { filter: 'invert(0)' };
567
-
568
- // ── Positioning ───────────────────────────────────────────────────────────
569
- const posMap: Record<string, string> = {
570
- static: 'static', relative: 'relative', absolute: 'absolute', fixed: 'fixed', sticky: 'sticky',
571
- };
572
- if (posMap[u]) return { position: posMap[u] };
573
-
574
- if (u === 'inset-0') return { top: '0', right: '0', bottom: '0', left: '0' };
575
- if (u === 'inset-auto') return { top: 'auto', right: 'auto', bottom: 'auto', left: 'auto' };
576
- if (u === 'inset-full') return { top: '100%', right: '100%', bottom: '100%', left: '100%' };
577
- if (u === 'inset-x-0') return { left: '0', right: '0' };
578
- if (u === 'inset-y-0') return { top: '0', bottom: '0' };
579
- if ((m = u.match(/^-?top-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]); if (v) return { top: neg && v !== '0' ? `-${v}` : v }; }
580
- if ((m = u.match(/^-?right-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]); if (v) return { right: neg && v !== '0' ? `-${v}` : v }; }
581
- if ((m = u.match(/^-?bottom-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]); if (v) return { bottom: neg && v !== '0' ? `-${v}` : v }; }
582
- if ((m = u.match(/^-?left-(.+)$/))) { const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]); if (v) return { left: neg && v !== '0' ? `-${v}` : v }; }
583
-
584
- // ── Z-index ────────────────────────────────────────────────────────────────
585
- const zMap: Record<string, string> = { '0': '0', '10': '10', '20': '20', '30': '30', '40': '40', '50': '50', '100': '100', '1000': '1000', '9000': '9000', auto: 'auto' };
586
- if ((m = u.match(/^z-(.+)$/))) { const v = zMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'z-index': v }; }
587
-
588
- // ── Overflow ───────────────────────────────────────────────────────────────
589
- const overflowMap: Record<string, string> = {
590
- 'overflow-auto': 'auto', 'overflow-hidden': 'hidden', 'overflow-visible': 'visible',
591
- 'overflow-scroll': 'scroll', 'overflow-clip': 'clip',
592
- };
593
- if (overflowMap[u]) return { overflow: overflowMap[u] };
594
- if ((m = u.match(/^overflow-(x|y)-(auto|hidden|visible|scroll|clip)$/))) {
595
- return { [`overflow-${m[1]}`]: m[2] };
596
- }
597
- if (u === 'scrollbar-hide') return { '-ms-overflow-style': 'none', 'scrollbar-width': 'none' };
598
-
599
- // ── Visibility ─────────────────────────────────────────────────────────────
600
- if (u === 'visible') return { visibility: 'visible' };
601
- if (u === 'invisible') return { visibility: 'hidden' };
602
- if (u === 'collapse') return { visibility: 'collapse' };
603
-
604
- // ── Cursor ─────────────────────────────────────────────────────────────────
605
- const cursorMap: Record<string, string> = {
606
- 'cursor-auto': 'auto', 'cursor-default': 'default', 'cursor-pointer': 'pointer',
607
- 'cursor-wait': 'wait', 'cursor-text': 'text', 'cursor-move': 'move',
608
- 'cursor-help': 'help', 'cursor-not-allowed': 'not-allowed',
609
- 'cursor-none': 'none', 'cursor-grab': 'grab', 'cursor-grabbing': 'grabbing',
610
- 'cursor-zoom-in': 'zoom-in', 'cursor-zoom-out': 'zoom-out', 'cursor-crosshair': 'crosshair',
611
- };
612
- if (cursorMap[u]) return { cursor: cursorMap[u] };
613
-
614
- // ── User select ───────────────────────────────────────────────────────────
615
- if (u === 'select-none') return { 'user-select': 'none' };
616
- if (u === 'select-text') return { 'user-select': 'text' };
617
- if (u === 'select-all') return { 'user-select': 'all' };
618
- if (u === 'select-auto') return { 'user-select': 'auto' };
619
-
620
- // ── Pointer events ─────────────────────────────────────────────────────────
621
- if (u === 'pointer-events-none') return { 'pointer-events': 'none' };
622
- if (u === 'pointer-events-auto') return { 'pointer-events': 'auto' };
623
-
624
- // ── Transforms ────────────────────────────────────────────────────────────
625
- const scaleMap: Record<string, string> = { '0': '0', '50': '.5', '75': '.75', '90': '.9', '95': '.95', '100': '1', '105': '1.05', '110': '1.1', '125': '1.25', '150': '1.5' };
626
- if ((m = u.match(/^scale-(.+)$/))) { const v = scaleMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { transform: `scale(${v})` }; }
627
- if ((m = u.match(/^scale-x-(.+)$/))) { const v = scaleMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { transform: `scaleX(${v})` }; }
628
- if ((m = u.match(/^scale-y-(.+)$/))) { const v = scaleMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { transform: `scaleY(${v})` }; }
629
- const rotateMap: Record<string, string> = { '0': '0deg', '1': '1deg', '2': '2deg', '3': '3deg', '6': '6deg', '12': '12deg', '45': '45deg', '90': '90deg', '180': '180deg' };
630
- if ((m = u.match(/^-?rotate-(.+)$/))) {
631
- const neg = u.startsWith('-'); const v = rotateMap[m[1]] ?? extractArbitrary(m[1]);
632
- if (v) return { transform: neg ? `rotate(-${v})` : `rotate(${v})` };
633
- }
634
- if ((m = u.match(/^-?translate-x-(.+)$/))) {
635
- const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]);
636
- if (v) return { transform: `translateX(${neg && v !== '0' ? `-${v}` : v})` };
637
- }
638
- if ((m = u.match(/^-?translate-y-(.+)$/))) {
639
- const neg = u.startsWith('-'); const v = SPACE[m[1]] ?? FRACTIONS[m[1]] ?? extractArbitrary(m[1]);
640
- if (v) return { transform: `translateY(${neg && v !== '0' ? `-${v}` : v})` };
641
- }
642
- if ((m = u.match(/^-?skew-x-(.+)$/))) {
643
- const neg = u.startsWith('-'); const v = extractArbitrary(m[1]) ?? `${m[1]}deg`;
644
- return { transform: neg ? `skewX(-${v})` : `skewX(${v})` };
645
- }
646
- if ((m = u.match(/^-?skew-y-(.+)$/))) {
647
- const neg = u.startsWith('-'); const v = extractArbitrary(m[1]) ?? `${m[1]}deg`;
648
- return { transform: neg ? `skewY(-${v})` : `skewY(${v})` };
649
- }
650
- const originMap: Record<string, string> = {
651
- 'origin-center': 'center', 'origin-top': 'top', 'origin-top-right': 'top right',
652
- 'origin-right': 'right', 'origin-bottom-right': 'bottom right', 'origin-bottom': 'bottom',
653
- 'origin-bottom-left': 'bottom left', 'origin-left': 'left', 'origin-top-left': 'top left',
654
- };
655
- if (originMap[u]) return { 'transform-origin': originMap[u] };
656
-
657
- // ── Transitions & Animations ───────────────────────────────────────────────
658
- const transitions: Record<string, string> = {
659
- 'transition': 'color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter',
660
- 'transition-all': 'all', 'transition-colors': 'color,background-color,border-color,text-decoration-color,fill,stroke',
661
- 'transition-opacity': 'opacity', 'transition-shadow': 'box-shadow',
662
- 'transition-transform': 'transform', 'transition-none': 'none',
663
- };
664
- if (transitions[u]) return { 'transition-property': transitions[u], 'transition-timing-function': 'cubic-bezier(0.4,0,0.2,1)', 'transition-duration': '150ms' };
665
-
666
- const durMap: Record<string, string> = { '75': '75ms', '100': '100ms', '150': '150ms', '200': '200ms', '300': '300ms', '500': '500ms', '700': '700ms', '1000': '1000ms' };
667
- if ((m = u.match(/^duration-(.+)$/))) { const v = durMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'transition-duration': v }; }
668
- if ((m = u.match(/^delay-(.+)$/))) { const v = durMap[m[1]] ?? extractArbitrary(m[1]); if (v) return { 'transition-delay': v }; }
669
-
670
- const easeMap: Record<string, string> = {
671
- 'ease-linear': 'linear', 'ease-in': 'cubic-bezier(0.4,0,1,1)',
672
- 'ease-out': 'cubic-bezier(0,0,0.2,1)', 'ease-in-out': 'cubic-bezier(0.4,0,0.2,1)',
673
- };
674
- if (easeMap[u]) return { 'transition-timing-function': easeMap[u] };
675
-
676
- const animMap: Record<string, string> = {
677
- 'animate-none': 'none',
678
- 'animate-spin': 'tkx-spin 1s linear infinite',
679
- 'animate-ping': 'tkx-ping 1s cubic-bezier(0,0,0.2,1) infinite',
680
- 'animate-pulse': 'tkx-pulse 2s cubic-bezier(0.4,0,0.6,1) infinite',
681
- 'animate-bounce': 'tkx-bounce 1s infinite',
682
- 'animate-fade-in': 'tkx-fade-in 200ms ease both',
683
- 'animate-slide-up': 'tkx-slide-up 200ms ease both',
684
- 'animate-shimmer': 'tkx-shimmer 1.5s infinite',
685
- };
686
- if (animMap[u]) return { animation: animMap[u] };
687
-
688
- // ── Object fit/position ────────────────────────────────────────────────────
689
- const objFit: Record<string, string> = {
690
- 'object-contain': 'contain', 'object-cover': 'cover', 'object-fill': 'fill',
691
- 'object-none': 'none', 'object-scale-down': 'scale-down',
692
- };
693
- if (objFit[u]) return { 'object-fit': objFit[u] };
694
-
695
- // ── Aspect ratio ──────────────────────────────────────────────────────────
696
- if (u === 'aspect-square') return { 'aspect-ratio': '1 / 1' };
697
- if (u === 'aspect-video') return { 'aspect-ratio': '16 / 9' };
698
- if (u === 'aspect-auto') return { 'aspect-ratio': 'auto' };
699
- if ((m = u.match(/^aspect-\[(.+)]$/))) { return { 'aspect-ratio': m[1] }; }
700
-
701
- // ── List ─────────────────────────────────────────────────────────────────
702
- if (u === 'list-none') return { 'list-style-type': 'none' };
703
- if (u === 'list-disc') return { 'list-style-type': 'disc' };
704
- if (u === 'list-decimal') return { 'list-style-type': 'decimal' };
705
- if (u === 'list-inside') return { 'list-style-position': 'inside' };
706
- if (u === 'list-outside') return { 'list-style-position': 'outside' };
707
-
708
- // ── Columns ──────────────────────────────────────────────────────────────
709
- if ((m = u.match(/^columns-(\d+)$/))) return { columns: m[1] };
710
-
711
- // ── Resize ───────────────────────────────────────────────────────────────
712
- if (u === 'resize') return { resize: 'both' };
713
- if (u === 'resize-none') return { resize: 'none' };
714
- if (u === 'resize-x') return { resize: 'horizontal' };
715
- if (u === 'resize-y') return { resize: 'vertical' };
716
-
717
- // ── Accessibility ─────────────────────────────────────────────────────────
718
- if (u === 'sr-only') return {
719
- position: 'absolute', width: '1px', height: '1px', padding: '0',
720
- margin: '-1px', overflow: 'hidden', clip: 'rect(0,0,0,0)',
721
- 'white-space': 'nowrap', border: '0',
722
- };
723
- if (u === 'not-sr-only') return {
724
- position: 'static', width: 'auto', height: 'auto', padding: '0', margin: '0',
725
- overflow: 'visible', clip: 'auto', 'white-space': 'normal',
726
- };
727
- if (u === 'focus-ring') return {
728
- outline: '2px solid var(--tkx-primary)',
729
- 'outline-offset': '2px',
730
- 'border-radius': '2px',
731
- };
732
-
733
- // ── Misc ──────────────────────────────────────────────────────────────────
734
- if (u === 'appearance-none') return { appearance: 'none' };
735
- if (u === 'outline-none') return { outline: 'none' };
736
- if (u === 'outline') return { outline: '2px solid currentColor', 'outline-offset': '2px' };
737
- if (u === 'float-left') return { float: 'left' };
738
- if (u === 'float-right') return { float: 'right' };
739
- if (u === 'float-none') return { float: 'none' };
740
- if (u === 'clear-both') return { clear: 'both' };
741
- if (u === 'isolate') return { isolation: 'isolate' };
742
- if (u === 'isolation-auto') return { isolation: 'auto' };
743
- if ((m = u.match(/^will-change-(.+)$/))) { return { 'will-change': m[1] }; }
744
- if (u === 'touch-manipulation') return { 'touch-action': 'manipulation' };
745
- if (u === 'touch-none') return { 'touch-action': 'none' };
746
- if (u === 'touch-pan-x') return { 'touch-action': 'pan-x' };
747
- if (u === 'touch-pan-y') return { 'touch-action': 'pan-y' };
748
- if (u === 'scroll-smooth') return { 'scroll-behavior': 'smooth' };
749
- if (u === 'scroll-auto') return { 'scroll-behavior': 'auto' };
750
-
751
- // ── CSS variable passthrough: [--my-var:value] ────────────────────────────
752
- if ((m = u.match(/^\[(--[a-zA-Z0-9-]+):(.+)]$/))) { return { [m[1]]: m[2] }; }
753
-
754
- // ── Plugin utilities ─────────────────────────────────────────────────────
755
- const pluginResult = resolvePluginUtility(u);
756
- if (pluginResult) return pluginResult;
757
-
758
- return null;
759
- }
760
-
761
- // ── Variant prefix parser ─────────────────────────────────────────────────────
762
-
763
- interface ParsedToken {
764
- variant: string | null; // 'hover', 'focus', '@md', 'motion-safe', etc.
765
- utility: string;
766
- }
767
-
768
- function parseToken(token: string): ParsedToken {
769
- // Variants: @sm, @md, hover, focus, active, disabled, motion-safe, etc.
770
- // Separator is ':' — but we need to NOT split inside [ ] brackets
771
- let depth = 0;
772
- let splitIdx = -1;
773
- for (let i = 0; i < token.length; i++) {
774
- if (token[i] === '[') depth++;
775
- else if (token[i] === ']') depth--;
776
- else if (token[i] === ':' && depth === 0) { splitIdx = i; break; }
777
- }
778
- if (splitIdx === -1) return { variant: null, utility: token };
779
- return { variant: token.slice(0, splitIdx), utility: token.slice(splitIdx + 1) };
780
- }
781
-
782
- // ── CSS block builder ─────────────────────────────────────────────────────────
783
-
784
- interface VariantGroup {
785
- base: Declarations;
786
- variants: Record<string, Declarations>; // key = variant string
787
- }
788
-
789
- function mergeDeclarations(target: Declarations, source: Declarations): void {
790
- for (const [k, v] of Object.entries(source)) {
791
- target[k] = v;
792
- }
793
- }
794
-
795
- function declarationsToCSS(decls: Declarations): string {
796
- return Object.entries(decls).map(([k, v]) => `${k}:${v}`).join(';');
797
- }
798
-
799
- // ── StyleSheet registry (inject once per unique CSS block) ────────────────────
800
-
801
- const registry = new Map<string, string>(); // hash → full CSS block
802
- let styleEl: HTMLStyleElement | null = null;
803
- // Constructable CSSStyleSheet for O(1) rule insertion (Chrome 73+, Firefox 101+, Safari 16.4+)
804
- let adoptedSheet: CSSStyleSheet | null = null;
805
-
806
- function getOrCreateStyleEl(): HTMLStyleElement {
807
- if (!styleEl || !styleEl.isConnected) {
808
- styleEl = document.getElementById('tkx-atomic') as HTMLStyleElement | null;
809
- if (!styleEl) {
810
- styleEl = document.createElement('style');
811
- styleEl.id = 'tkx-atomic';
812
- document.head.appendChild(styleEl);
813
- }
814
- }
815
- return styleEl;
816
- }
817
-
818
- function getAdoptedSheet(): CSSStyleSheet | null {
819
- if (adoptedSheet) return adoptedSheet;
820
- try {
821
- // Constructable Stylesheets API — supported in all evergreen browsers
822
- const sheet = new CSSStyleSheet();
823
- document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
824
- adoptedSheet = sheet;
825
- return sheet;
826
- } catch {
827
- return null;
828
- }
829
- }
830
-
831
- function registerBlock(hash: string, cssBlock: string): void {
832
- if (registry.has(hash)) return;
833
- registry.set(hash, cssBlock);
834
- if (typeof document === 'undefined') return;
835
-
836
- const sheet = getAdoptedSheet();
837
- if (sheet) {
838
- // O(1) per rule — insertRule appends without touching existing text
839
- // Split multi-rule blocks (e.g. base + media query) and insert each one.
840
- // We use a simple regex split on top-level `}` boundaries.
841
- const rules = splitCSSRules(cssBlock);
842
- for (const rule of rules) {
843
- try {
844
- sheet.insertRule(rule, sheet.cssRules.length);
845
- } catch {
846
- // Fallback for any rule the browser rejects (e.g. invalid pseudo)
847
- getOrCreateStyleEl().textContent += rule + '\n';
848
- }
849
- }
850
- } else {
851
- // Fallback for environments that don't support adoptedStyleSheets
852
- getOrCreateStyleEl().textContent += cssBlock + '\n';
853
- }
854
- }
855
-
856
- /**
857
- * Split a CSS string into individual top-level rules.
858
- * Handles nested braces (media queries, @supports, etc.).
859
- */
860
- function splitCSSRules(css: string): string[] {
861
- const rules: string[] = [];
862
- let depth = 0;
863
- let start = 0;
864
- for (let i = 0; i < css.length; i++) {
865
- if (css[i] === '{') depth++;
866
- else if (css[i] === '}') {
867
- depth--;
868
- if (depth === 0) {
869
- const rule = css.slice(start, i + 1).trim();
870
- if (rule) rules.push(rule);
871
- start = i + 1;
872
- }
873
- }
874
- }
875
- return rules;
876
- }
877
-
878
- // ── Main TKX function ─────────────────────────────────────────────────────────
879
-
880
- export type TkxInput = string | false | null | undefined | TkxInput[] | Record<string, boolean>;
881
-
882
- function flattenInputs(inputs: TkxInput[]): string[] {
883
- const tokens: string[] = [];
884
- for (const input of inputs) {
885
- if (!input) continue;
886
- if (typeof input === 'string') {
887
- tokens.push(...input.split(/\s+/).filter(Boolean));
888
- } else if (Array.isArray(input)) {
889
- tokens.push(...flattenInputs(input));
890
- } else if (typeof input === 'object') {
891
- for (const [key, active] of Object.entries(input)) {
892
- if (active) tokens.push(key);
893
- }
894
- }
895
- }
896
- return tokens;
897
- }
898
-
899
- /**
900
- * TKX — The utility class engine.
901
- *
902
- * Better than Tailwind because:
903
- * - TRUE conflict resolution (p-4 p-8 → one class with padding:32px, no cascade hacks)
904
- * - Theme-aware tokens read from CSS variables automatically
905
- * - Single merged class per call — cleaner DOM
906
- * - No config, no plugins, no PostCSS, no purge
907
- * - Works SSR-first
908
- *
909
- * @example
910
- * tkx('flex items-center gap-4 p-4 bg-surface rounded-lg')
911
- * tkx('flex', { 'bg-primary': isActive, 'bg-surface': !isActive }, ['p-4', '@md:p-8'])
912
- * tkx('text-primary hover:text-secondary transition-colors duration-200')
913
- */
914
- export function tkx(...inputs: TkxInput[]): string {
915
- const tokens = flattenInputs(inputs);
916
- if (tokens.length === 0) return '';
917
-
918
- // Group by variant
919
- const groups: VariantGroup = { base: {}, variants: {} };
920
-
921
- for (const token of tokens) {
922
- const { variant, utility } = parseToken(token);
923
- const decls = resolveUtility(utility);
924
- if (!decls) continue;
925
-
926
- if (!variant) {
927
- mergeDeclarations(groups.base, decls);
928
- } else {
929
- if (!groups.variants[variant]) groups.variants[variant] = {};
930
- mergeDeclarations(groups.variants[variant], decls);
931
- }
932
- }
933
-
934
- // Build full CSS block
935
- const parts: string[] = [];
936
- const baseCSS = declarationsToCSS(groups.base);
937
- const fingerprint = [baseCSS, ...Object.entries(groups.variants).map(([v, d]) => `${v}{${declarationsToCSS(d)}}`)].join('|');
938
- const hash = fnv1aHash(fingerprint);
939
- const cls = `tkx-${hash}`;
940
-
941
- if (baseCSS) parts.push(`.${cls}{${baseCSS}}`);
942
-
943
- for (const [variant, decls] of Object.entries(groups.variants)) {
944
- const variantCSS = declarationsToCSS(decls);
945
- if (!variantCSS) continue;
946
-
947
- if (variant.startsWith('@')) {
948
- // Responsive variant: @sm, @md, @lg, @xl, @2xl
949
- const bp = variant.slice(1);
950
- const minWidth = BREAKPOINTS[bp];
951
- if (minWidth) {
952
- parts.push(`@media(min-width:${minWidth}){.${cls}{${variantCSS}}}`);
953
- }
954
- } else if (variant === 'motion-safe') {
955
- parts.push(`@media(prefers-reduced-motion:no-preference){.${cls}{${variantCSS}}}`);
956
- } else if (variant === 'motion-reduce') {
957
- parts.push(`@media(prefers-reduced-motion:reduce){.${cls}{${variantCSS}}}`);
958
- } else if (variant === 'contrast-more') {
959
- parts.push(`@media(prefers-contrast:more){.${cls}{${variantCSS}}}`);
960
- } else if (variant === 'forced-colors') {
961
- parts.push(`@media(forced-colors:active){.${cls}{${variantCSS}}}`);
962
- } else if (variant === 'dark') {
963
- parts.push(`@media(prefers-color-scheme:dark){.${cls}{${variantCSS}}}`);
964
- } else if (variant === 'print') {
965
- parts.push(`@media print{.${cls}{${variantCSS}}}`);
966
- } else if (variant === 'group-hover') {
967
- parts.push(`.group:hover .${cls}{${variantCSS}}`);
968
- } else if (variant === 'group-focus') {
969
- parts.push(`.group:focus-within .${cls}{${variantCSS}}`);
970
- } else if (variant === 'peer-hover') {
971
- parts.push(`.peer:hover~.${cls}{${variantCSS}}`);
972
- } else {
973
- // Pseudo-class variant: hover, focus, active, disabled, etc.
974
- const pseudoMap: Record<string, string> = {
975
- hover: ':hover', focus: ':focus', 'focus-visible': ':focus-visible',
976
- 'focus-within': ':focus-within', active: ':active', disabled: ':disabled',
977
- checked: ':checked', required: ':required', valid: ':valid', invalid: ':invalid',
978
- first: ':first-child', last: ':last-child', odd: ':nth-child(odd)', even: ':nth-child(even)',
979
- 'first-of-type': ':first-of-type', 'last-of-type': ':last-of-type',
980
- 'only-child': ':only-child', 'only-of-type': ':only-of-type',
981
- empty: ':empty', visited: ':visited', target: ':target',
982
- 'placeholder-shown': ':placeholder-shown', 'read-only': ':read-only',
983
- before: '::before', after: '::after', placeholder: '::placeholder',
984
- selection: '::selection', 'file-selector': '::file-selector-button',
985
- marker: '::marker',
986
- };
987
- const pseudo = pseudoMap[variant] ?? `:${variant}`;
988
- parts.push(`.${cls}${pseudo}{${variantCSS}}`);
989
- }
990
- }
991
-
992
- if (parts.length > 0) {
993
- registerBlock(hash, parts.join(''));
994
- }
995
-
996
- return cls;
997
- }
998
-
999
- /** Alias — shorter to type in JSX */
1000
- export const tx = tkx;
1001
-
1002
- // ── SSR Support ───────────────────────────────────────────────────────────────
1003
-
1004
- /** Extract all registered CSS for server-side rendering injection */
1005
- export function extractAtomicCSS(): string {
1006
- return Array.from(registry.values()).join('\n');
1007
- }
1008
-
1009
- /** Reset registry (useful for per-request SSR isolation) */
1010
- export function resetAtomicCSS(): void {
1011
- registry.clear();
1012
- styleEl = null;
1013
- if (adoptedSheet && typeof document !== 'undefined') {
1014
- document.adoptedStyleSheets = document.adoptedStyleSheets.filter(s => s !== adoptedSheet);
1015
- adoptedSheet = null;
1016
- }
1017
- }
1018
-
1019
- // ── cx — className merge helper (like clsx but integrated) ────────────────────
1020
- /**
1021
- * Merge existing class name strings without generating new CSS.
1022
- * Use this to combine a tkx() result with a consumer-provided className prop.
1023
- */
1024
- export function cx(...classes: (string | false | null | undefined)[]): string {
1025
- return classes.filter(Boolean).join(' ');
1026
- }
1027
-
1028
- // ── Plugin System ────────────────────────────────────────────────────────────
1029
- /**
1030
- * TKX Plugin API — extend the utility engine with custom utilities.
1031
- *
1032
- * @example
1033
- * ```tsx
1034
- * import { tkxPlugin, tkx } from '@tekivex/ui';
1035
- *
1036
- * // Register custom utilities
1037
- * tkxPlugin({
1038
- * name: 'brand',
1039
- * utilities: {
1040
- * 'brand-gradient': { background: 'linear-gradient(135deg, #667eea, #764ba2)' },
1041
- * 'brand-text': { color: '#667eea', fontWeight: '700' },
1042
- * 'card-shadow': { boxShadow: '0 8px 32px rgba(102, 126, 234, 0.15)' },
1043
- * 'glass': {
1044
- * background: 'rgba(255, 255, 255, 0.05)',
1045
- * backdropFilter: 'blur(12px)',
1046
- * border: '1px solid rgba(255, 255, 255, 0.1)',
1047
- * },
1048
- * },
1049
- * });
1050
- *
1051
- * // Use them like any built-in utility
1052
- * const cls = tkx('brand-gradient p-6 rounded-xl card-shadow');
1053
- * ```
1054
- */
1055
-
1056
- export interface TkxPluginDef {
1057
- name: string;
1058
- utilities: Record<string, Record<string, string>>;
1059
- }
1060
-
1061
- const pluginRegistry = new Map<string, Record<string, Record<string, string>>>();
1062
-
1063
- export function tkxPlugin(plugin: TkxPluginDef): void {
1064
- pluginRegistry.set(plugin.name, plugin.utilities);
1065
- }
1066
-
1067
- export function tkxRemovePlugin(name: string): void {
1068
- pluginRegistry.delete(name);
1069
- }
1070
-
1071
- export function tkxListPlugins(): string[] {
1072
- return Array.from(pluginRegistry.keys());
1073
- }
1074
-
1075
- /**
1076
- * Resolve a plugin utility to CSS properties.
1077
- * Called internally by the TKX engine — but also exported for inspection.
1078
- */
1079
- export function resolvePluginUtility(name: string): Record<string, string> | null {
1080
- for (const utilities of pluginRegistry.values()) {
1081
- if (utilities[name]) return utilities[name];
1082
- }
1083
- return null;
1084
- }