persian-data-grid 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/OFL.txt +93 -0
  2. package/README.md +179 -22
  3. package/dist/ERPTableGroupRow-J5Z2LRC5.cjs +131 -0
  4. package/dist/ERPTableGroupRow-J5Z2LRC5.cjs.map +1 -0
  5. package/dist/ERPTableGroupRow-PSAPAHGL.js +125 -0
  6. package/dist/ERPTableGroupRow-PSAPAHGL.js.map +1 -0
  7. package/dist/GridPlugin-CJCaYnlw.d.ts +57 -0
  8. package/dist/GridPlugin-oxhq8AsM.d.cts +57 -0
  9. package/dist/GridPresenceService-GEH6535Q.js +3 -0
  10. package/dist/GridPresenceService-GEH6535Q.js.map +1 -0
  11. package/dist/GridPresenceService-RDN5FXHQ.cjs +12 -0
  12. package/dist/GridPresenceService-RDN5FXHQ.cjs.map +1 -0
  13. package/dist/GridSession-B-9lLcoB.d.cts +2492 -0
  14. package/dist/GridSession-Bc7UIawO.d.ts +2492 -0
  15. package/dist/GridSyncService-KTLB4KP3.js +3 -0
  16. package/dist/GridSyncService-KTLB4KP3.js.map +1 -0
  17. package/dist/GridSyncService-TAPAHABV.cjs +12 -0
  18. package/dist/GridSyncService-TAPAHABV.cjs.map +1 -0
  19. package/dist/PdfRenderer-1HFh6UeR.d.ts +22 -0
  20. package/dist/PdfRenderer-CBg7hWNS.d.cts +22 -0
  21. package/dist/RemoteApi-CCQxiSf1.d.cts +28 -0
  22. package/dist/RemoteApi-CCQxiSf1.d.ts +28 -0
  23. package/dist/SelectImpl-NM4O4IGW.js +447 -0
  24. package/dist/SelectImpl-NM4O4IGW.js.map +1 -0
  25. package/dist/SelectImpl-W2EI4T7O.cjs +453 -0
  26. package/dist/SelectImpl-W2EI4T7O.cjs.map +1 -0
  27. package/dist/UITableController-Cuwq481K.d.cts +632 -0
  28. package/dist/UITableController-DU8RopUM.d.ts +632 -0
  29. package/dist/VazirmatnPdfRenderer-BCMpC1zy.d.cts +96 -0
  30. package/dist/VazirmatnPdfRenderer-Dz_G-m3c.d.ts +96 -0
  31. package/dist/adapters/arian-erp.cjs +77 -0
  32. package/dist/adapters/arian-erp.cjs.map +1 -0
  33. package/dist/adapters/arian-erp.d.cts +60 -0
  34. package/dist/adapters/arian-erp.d.ts +60 -0
  35. package/dist/adapters/arian-erp.js +71 -0
  36. package/dist/adapters/arian-erp.js.map +1 -0
  37. package/dist/appendAtEnd-RHIQRG2W.cjs +35 -0
  38. package/dist/appendAtEnd-RHIQRG2W.cjs.map +1 -0
  39. package/dist/appendAtEnd-TJEABLGD.js +33 -0
  40. package/dist/appendAtEnd-TJEABLGD.js.map +1 -0
  41. package/dist/applyImportedRows-BO6yxoAN.d.cts +135 -0
  42. package/dist/applyImportedRows-D4zVY8uD.d.ts +135 -0
  43. package/dist/applyRowVisibilityHandler-KS6TMCBN.js +83 -0
  44. package/dist/applyRowVisibilityHandler-KS6TMCBN.js.map +1 -0
  45. package/dist/applyRowVisibilityHandler-LXCOGESZ.cjs +85 -0
  46. package/dist/applyRowVisibilityHandler-LXCOGESZ.cjs.map +1 -0
  47. package/dist/broadcastChannelTransport-FHUMV76O.cjs +12 -0
  48. package/dist/broadcastChannelTransport-FHUMV76O.cjs.map +1 -0
  49. package/dist/broadcastChannelTransport-MIH53VNZ.js +3 -0
  50. package/dist/broadcastChannelTransport-MIH53VNZ.js.map +1 -0
  51. package/dist/callbackRemoteApi-BlXO5NJz.d.ts +30 -0
  52. package/dist/callbackRemoteApi-DgnXH-i0.d.cts +30 -0
  53. package/dist/cellRenderContext-DB7V_mlu.d.ts +42 -0
  54. package/dist/cellRenderContext-DG5BOlxK.d.cts +42 -0
  55. package/dist/chunk-2BJCRYOS.cjs +936 -0
  56. package/dist/chunk-2BJCRYOS.cjs.map +1 -0
  57. package/dist/chunk-3Y3KKGEC.js +3 -0
  58. package/dist/chunk-3Y3KKGEC.js.map +1 -0
  59. package/dist/chunk-5ALMNLUR.cjs +1408 -0
  60. package/dist/chunk-5ALMNLUR.cjs.map +1 -0
  61. package/dist/chunk-5HKVMPBD.js +937 -0
  62. package/dist/chunk-5HKVMPBD.js.map +1 -0
  63. package/dist/chunk-633KP74Z.js +189 -0
  64. package/dist/chunk-633KP74Z.js.map +1 -0
  65. package/dist/chunk-6XBXZPBW.js +298 -0
  66. package/dist/chunk-6XBXZPBW.js.map +1 -0
  67. package/dist/chunk-77UXAJII.js +112 -0
  68. package/dist/chunk-77UXAJII.js.map +1 -0
  69. package/dist/chunk-ASPTRYRD.cjs +21 -0
  70. package/dist/chunk-ASPTRYRD.cjs.map +1 -0
  71. package/dist/chunk-AU3RDJYQ.js +243 -0
  72. package/dist/chunk-AU3RDJYQ.js.map +1 -0
  73. package/dist/chunk-BHDRUZH5.cjs +33 -0
  74. package/dist/chunk-BHDRUZH5.cjs.map +1 -0
  75. package/dist/chunk-BLYVOV3G.cjs +191 -0
  76. package/dist/chunk-BLYVOV3G.cjs.map +1 -0
  77. package/dist/chunk-CILNIWYW.cjs +100 -0
  78. package/dist/chunk-CILNIWYW.cjs.map +1 -0
  79. package/dist/chunk-DFFP7SJ6.cjs +257 -0
  80. package/dist/chunk-DFFP7SJ6.cjs.map +1 -0
  81. package/dist/chunk-DXRCYW42.cjs +568 -0
  82. package/dist/chunk-DXRCYW42.cjs.map +1 -0
  83. package/dist/chunk-EBV6HGZB.cjs +33 -0
  84. package/dist/chunk-EBV6HGZB.cjs.map +1 -0
  85. package/dist/chunk-EHHHC5JV.js +832 -0
  86. package/dist/chunk-EHHHC5JV.js.map +1 -0
  87. package/dist/chunk-F4PYOYHR.js +112 -0
  88. package/dist/chunk-F4PYOYHR.js.map +1 -0
  89. package/dist/chunk-GQEDLUMB.js +168 -0
  90. package/dist/chunk-GQEDLUMB.js.map +1 -0
  91. package/dist/chunk-H2LESGMX.cjs +319 -0
  92. package/dist/chunk-H2LESGMX.cjs.map +1 -0
  93. package/dist/chunk-HTNJT2QU.js +11674 -0
  94. package/dist/chunk-HTNJT2QU.js.map +1 -0
  95. package/dist/chunk-IIISFUW4.cjs +11786 -0
  96. package/dist/chunk-IIISFUW4.cjs.map +1 -0
  97. package/dist/chunk-IMPCRWYP.cjs +251 -0
  98. package/dist/chunk-IMPCRWYP.cjs.map +1 -0
  99. package/dist/chunk-IPPIXOVQ.js +317 -0
  100. package/dist/chunk-IPPIXOVQ.js.map +1 -0
  101. package/dist/chunk-J4XJ4UBC.js +1404 -0
  102. package/dist/chunk-J4XJ4UBC.js.map +1 -0
  103. package/dist/chunk-J7CPPFXT.cjs +89 -0
  104. package/dist/chunk-J7CPPFXT.cjs.map +1 -0
  105. package/dist/chunk-JOICD47Q.cjs +41 -0
  106. package/dist/chunk-JOICD47Q.cjs.map +1 -0
  107. package/dist/chunk-KHMG6EI2.js +13 -0
  108. package/dist/chunk-KHMG6EI2.js.map +1 -0
  109. package/dist/chunk-KMRURD5J.cjs +15 -0
  110. package/dist/chunk-KMRURD5J.cjs.map +1 -0
  111. package/dist/chunk-KRJG3KMP.cjs +174 -0
  112. package/dist/chunk-KRJG3KMP.cjs.map +1 -0
  113. package/dist/chunk-KUBVDIF7.cjs +653 -0
  114. package/dist/chunk-KUBVDIF7.cjs.map +1 -0
  115. package/dist/chunk-KYAOSBQN.js +31 -0
  116. package/dist/chunk-KYAOSBQN.js.map +1 -0
  117. package/dist/chunk-LJ7LMEXO.js +36 -0
  118. package/dist/chunk-LJ7LMEXO.js.map +1 -0
  119. package/dist/chunk-MT3KLB2Q.cjs +944 -0
  120. package/dist/chunk-MT3KLB2Q.cjs.map +1 -0
  121. package/dist/chunk-MU3RY46O.js +932 -0
  122. package/dist/chunk-MU3RY46O.js.map +1 -0
  123. package/dist/chunk-MUQQKPWR.js +84 -0
  124. package/dist/chunk-MUQQKPWR.js.map +1 -0
  125. package/dist/chunk-N7SJTINL.cjs +4 -0
  126. package/dist/chunk-N7SJTINL.cjs.map +1 -0
  127. package/dist/chunk-NTV2UUAJ.cjs +149 -0
  128. package/dist/chunk-NTV2UUAJ.cjs.map +1 -0
  129. package/dist/chunk-PJQWHF6T.js +31 -0
  130. package/dist/chunk-PJQWHF6T.js.map +1 -0
  131. package/dist/chunk-PQY54EL5.js +248 -0
  132. package/dist/chunk-PQY54EL5.js.map +1 -0
  133. package/dist/chunk-PXCHPZTP.cjs +839 -0
  134. package/dist/chunk-PXCHPZTP.cjs.map +1 -0
  135. package/dist/chunk-Q7TBBUTX.cjs +110 -0
  136. package/dist/chunk-Q7TBBUTX.cjs.map +1 -0
  137. package/dist/chunk-QQMU44KJ.js +612 -0
  138. package/dist/chunk-QQMU44KJ.js.map +1 -0
  139. package/dist/chunk-QZN7R2WP.cjs +114 -0
  140. package/dist/chunk-QZN7R2WP.cjs.map +1 -0
  141. package/dist/chunk-RKVSJU46.js +35 -0
  142. package/dist/chunk-RKVSJU46.js.map +1 -0
  143. package/dist/chunk-RM6ZWNT3.js +561 -0
  144. package/dist/chunk-RM6ZWNT3.js.map +1 -0
  145. package/dist/chunk-SX4VQXAA.cjs +114 -0
  146. package/dist/chunk-SX4VQXAA.cjs.map +1 -0
  147. package/dist/chunk-SZ7BLAY3.js +92 -0
  148. package/dist/chunk-SZ7BLAY3.js.map +1 -0
  149. package/dist/chunk-TN4MG6FY.js +112 -0
  150. package/dist/chunk-TN4MG6FY.js.map +1 -0
  151. package/dist/chunk-UC7PHDM6.cjs +331 -0
  152. package/dist/chunk-UC7PHDM6.cjs.map +1 -0
  153. package/dist/chunk-UXVLYUUW.js +108 -0
  154. package/dist/chunk-UXVLYUUW.js.map +1 -0
  155. package/dist/chunk-VVGYRZ7S.cjs +38 -0
  156. package/dist/chunk-VVGYRZ7S.cjs.map +1 -0
  157. package/dist/chunk-W5256BJ4.js +56 -0
  158. package/dist/chunk-W5256BJ4.js.map +1 -0
  159. package/dist/chunk-WUMOSOEK.cjs +62 -0
  160. package/dist/chunk-WUMOSOEK.cjs.map +1 -0
  161. package/dist/chunk-XLRE2J25.js +140 -0
  162. package/dist/chunk-XLRE2J25.js.map +1 -0
  163. package/dist/chunk-Y6W5V2CI.js +19 -0
  164. package/dist/chunk-Y6W5V2CI.js.map +1 -0
  165. package/dist/chunk-Z4QPZ3Z3.cjs +114 -0
  166. package/dist/chunk-Z4QPZ3Z3.cjs.map +1 -0
  167. package/dist/createEngineGridQuery-Dmq3i5v3.d.cts +884 -0
  168. package/dist/createEngineGridQuery-Mt1hc33m.d.ts +884 -0
  169. package/dist/date-picker-jalali.cjs +263 -0
  170. package/dist/date-picker-jalali.cjs.map +1 -0
  171. package/dist/date-picker-jalali.d.cts +62 -0
  172. package/dist/date-picker-jalali.d.ts +62 -0
  173. package/dist/date-picker-jalali.js +256 -0
  174. package/dist/date-picker-jalali.js.map +1 -0
  175. package/dist/finance.cjs +205 -0
  176. package/dist/finance.cjs.map +1 -0
  177. package/dist/finance.d.cts +90 -0
  178. package/dist/finance.d.ts +90 -0
  179. package/dist/finance.js +157 -0
  180. package/dist/finance.js.map +1 -0
  181. package/dist/foldedColumn-IHDT4ARZ.cjs +66 -0
  182. package/dist/foldedColumn-IHDT4ARZ.cjs.map +1 -0
  183. package/dist/foldedColumn-TFURUKFG.js +64 -0
  184. package/dist/foldedColumn-TFURUKFG.js.map +1 -0
  185. package/dist/headless.cjs +729 -0
  186. package/dist/headless.cjs.map +1 -0
  187. package/dist/headless.d.cts +504 -0
  188. package/dist/headless.d.ts +504 -0
  189. package/dist/headless.js +226 -0
  190. package/dist/headless.js.map +1 -0
  191. package/dist/index-DN8M8Jkq.d.cts +14 -0
  192. package/dist/index-DmzL-F_o.d.ts +14 -0
  193. package/dist/index.cjs +8002 -11409
  194. package/dist/index.cjs.map +1 -1
  195. package/dist/index.d.cts +437 -2305
  196. package/dist/index.d.ts +437 -2305
  197. package/dist/index.js +7244 -11083
  198. package/dist/index.js.map +1 -1
  199. package/dist/locales/ar.cjs +12 -0
  200. package/dist/locales/ar.cjs.map +1 -0
  201. package/dist/locales/ar.d.cts +6 -0
  202. package/dist/locales/ar.d.ts +6 -0
  203. package/dist/locales/ar.js +3 -0
  204. package/dist/locales/ar.js.map +1 -0
  205. package/dist/locales/en.cjs +12 -0
  206. package/dist/locales/en.cjs.map +1 -0
  207. package/dist/locales/en.d.cts +6 -0
  208. package/dist/locales/en.d.ts +6 -0
  209. package/dist/locales/en.js +3 -0
  210. package/dist/locales/en.js.map +1 -0
  211. package/dist/locales/fa.cjs +12 -0
  212. package/dist/locales/fa.cjs.map +1 -0
  213. package/dist/locales/fa.d.cts +6 -0
  214. package/dist/locales/fa.d.ts +6 -0
  215. package/dist/locales/fa.js +3 -0
  216. package/dist/locales/fa.js.map +1 -0
  217. package/dist/locales/index.cjs +51 -0
  218. package/dist/locales/index.cjs.map +1 -0
  219. package/dist/locales/index.d.cts +5 -0
  220. package/dist/locales/index.d.ts +5 -0
  221. package/dist/locales/index.js +6 -0
  222. package/dist/locales/index.js.map +1 -0
  223. package/dist/memoryRecords-AWDKUJ2F.cjs +50 -0
  224. package/dist/memoryRecords-AWDKUJ2F.cjs.map +1 -0
  225. package/dist/memoryRecords-OJTGXLRH.js +47 -0
  226. package/dist/memoryRecords-OJTGXLRH.js.map +1 -0
  227. package/dist/pagedFooterTotals-DXCGDO6F.cjs +27 -0
  228. package/dist/pagedFooterTotals-DXCGDO6F.cjs.map +1 -0
  229. package/dist/pagedFooterTotals-ORWKUNE7.js +25 -0
  230. package/dist/pagedFooterTotals-ORWKUNE7.js.map +1 -0
  231. package/dist/pagedKit-MFGAJFSK.cjs +134 -0
  232. package/dist/pagedKit-MFGAJFSK.cjs.map +1 -0
  233. package/dist/pagedKit-WYWY4LRV.js +127 -0
  234. package/dist/pagedKit-WYWY4LRV.js.map +1 -0
  235. package/dist/pagedSearch-HCPJW7VM.js +38 -0
  236. package/dist/pagedSearch-HCPJW7VM.js.map +1 -0
  237. package/dist/pagedSearch-U3WCG4GN.cjs +42 -0
  238. package/dist/pagedSearch-U3WCG4GN.cjs.map +1 -0
  239. package/dist/plugins/csv.cjs +124 -0
  240. package/dist/plugins/csv.cjs.map +1 -0
  241. package/dist/plugins/csv.d.cts +44 -0
  242. package/dist/plugins/csv.d.ts +44 -0
  243. package/dist/plugins/csv.js +120 -0
  244. package/dist/plugins/csv.js.map +1 -0
  245. package/dist/plugins/excel.cjs +52 -0
  246. package/dist/plugins/excel.cjs.map +1 -0
  247. package/dist/plugins/excel.d.cts +14 -0
  248. package/dist/plugins/excel.d.ts +14 -0
  249. package/dist/plugins/excel.js +7 -0
  250. package/dist/plugins/excel.js.map +1 -0
  251. package/dist/plugins/pdf/fonts/vazirmatn.cjs +50 -0
  252. package/dist/plugins/pdf/fonts/vazirmatn.cjs.map +1 -0
  253. package/dist/plugins/pdf/fonts/vazirmatn.d.cts +24 -0
  254. package/dist/plugins/pdf/fonts/vazirmatn.d.ts +24 -0
  255. package/dist/plugins/pdf/fonts/vazirmatn.js +39 -0
  256. package/dist/plugins/pdf/fonts/vazirmatn.js.map +1 -0
  257. package/dist/plugins/pdf.cjs +24 -0
  258. package/dist/plugins/pdf.cjs.map +1 -0
  259. package/dist/plugins/pdf.d.cts +21 -0
  260. package/dist/plugins/pdf.d.ts +21 -0
  261. package/dist/plugins/pdf.js +7 -0
  262. package/dist/plugins/pdf.js.map +1 -0
  263. package/dist/presence.cjs +56 -0
  264. package/dist/presence.cjs.map +1 -0
  265. package/dist/presence.d.cts +17 -0
  266. package/dist/presence.d.ts +17 -0
  267. package/dist/presence.js +54 -0
  268. package/dist/presence.js.map +1 -0
  269. package/dist/rebuildRowVisibility-66EAZ356.cjs +21 -0
  270. package/dist/rebuildRowVisibility-66EAZ356.cjs.map +1 -0
  271. package/dist/rebuildRowVisibility-6TYM5BP2.js +19 -0
  272. package/dist/rebuildRowVisibility-6TYM5BP2.js.map +1 -0
  273. package/dist/styles.css +1440 -0
  274. package/dist/sync.cjs +148 -0
  275. package/dist/sync.cjs.map +1 -0
  276. package/dist/sync.d.cts +17 -0
  277. package/dist/sync.d.ts +17 -0
  278. package/dist/sync.js +146 -0
  279. package/dist/sync.js.map +1 -0
  280. package/dist/types-D__47BKv.d.cts +23 -0
  281. package/dist/types-D__47BKv.d.ts +23 -0
  282. package/package.json +184 -28
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../ui/locales/types.ts","../ui/locales/index.ts"],"names":["faMessages","enMessages","arMessages"],"mappings":"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","file":"chunk-CILNIWYW.cjs","sourcesContent":["/** Locale pack types (PR-127). */\r\n\r\nexport type ERPTableLocale = 'fa' | 'en' | 'ar';\r\n\r\nexport type ERPTableMessages = Record<string, string>;\r\n\r\n/** Unicode numbering systems for Intl (PR-127). */\r\nexport type NumberingSystem = 'latn' | 'arab' | 'arabext';\r\n\r\nexport type LocaleMeta = {\r\n locale: ERPTableLocale;\r\n /** Default writing direction; host may override. */\r\n dir: 'rtl' | 'ltr';\r\n /** BCP 47 tag for Intl. */\r\n intlLocale: string;\r\n /** Default digit system. */\r\n numberingSystem: NumberingSystem;\r\n /** Default calendar for date display (PR-128 may replace with DateAdapter). */\r\n calendar: 'persian' | 'gregory' | 'islamic';\r\n};\r\n\r\nexport const LOCALE_META: Record<ERPTableLocale, LocaleMeta> = {\r\n fa: {\r\n locale: 'fa',\r\n dir: 'rtl',\r\n intlLocale: 'fa-IR',\r\n numberingSystem: 'arabext',\r\n calendar: 'persian',\r\n },\r\n en: {\r\n locale: 'en',\r\n dir: 'ltr',\r\n intlLocale: 'en-US',\r\n numberingSystem: 'latn',\r\n calendar: 'gregory',\r\n },\r\n ar: {\r\n locale: 'ar',\r\n dir: 'rtl',\r\n intlLocale: 'ar-SA',\r\n numberingSystem: 'arab',\r\n calendar: 'gregory',\r\n },\r\n};\r\n\r\nexport function resolveLocaleMeta(\r\n locale: ERPTableLocale,\r\n overrides?: {\r\n numberingSystem?: NumberingSystem;\r\n },\r\n): LocaleMeta {\r\n const base = LOCALE_META[locale] ?? LOCALE_META.fa;\r\n if (!overrides?.numberingSystem) return base;\r\n return { ...base, numberingSystem: overrides.numberingSystem };\r\n}\r\n\r\nexport function resolveDirection(\r\n locale: ERPTableLocale,\r\n override?: 'rtl' | 'ltr',\r\n): 'rtl' | 'ltr' {\r\n if (override === 'rtl' || override === 'ltr') return override;\r\n return (LOCALE_META[locale] ?? LOCALE_META.fa).dir;\r\n}\r\n","import { arMessages } from './ar';\r\nimport { enMessages } from './en';\r\nimport { faMessages } from './fa';\r\nimport {\r\n LOCALE_META,\r\n resolveDirection,\r\n resolveLocaleMeta,\r\n type ERPTableLocale,\r\n type ERPTableMessages,\r\n type LocaleMeta,\r\n type NumberingSystem,\r\n} from './types';\r\n\r\nexport type {\r\n ERPTableLocale,\r\n ERPTableMessages,\r\n LocaleMeta,\r\n NumberingSystem,\r\n} from './types';\r\nexport {\r\n LOCALE_META,\r\n resolveDirection,\r\n resolveLocaleMeta,\r\n} from './types';\r\nexport { faMessages } from './fa';\r\nexport { enMessages } from './en';\r\nexport { arMessages } from './ar';\r\n\r\nexport const LOCALE_PACKS: Record<ERPTableLocale, ERPTableMessages> = {\r\n fa: faMessages,\r\n en: enMessages,\r\n ar: arMessages,\r\n};\r\n\r\nexport function getLocalePack(locale: ERPTableLocale): ERPTableMessages {\r\n return LOCALE_PACKS[locale] ?? faMessages;\r\n}\r\n\r\nexport type FormatOptions = {\r\n locale?: ERPTableLocale;\r\n numberingSystem?: NumberingSystem;\r\n};\r\n\r\nfunction metaFor(options?: FormatOptions): LocaleMeta {\r\n const locale = options?.locale ?? 'fa';\r\n return resolveLocaleMeta(locale, {\r\n numberingSystem: options?.numberingSystem,\r\n });\r\n}\r\n\r\n/** Intl number formatting with configurable numberingSystem (PR-127). */\r\nexport function formatLocaleNumber(\r\n value: unknown,\r\n options?: FormatOptions & Intl.NumberFormatOptions,\r\n): string {\r\n if (value == null || value === '') return '';\r\n const n = typeof value === 'number' ? value : Number(value);\r\n if (!Number.isFinite(n)) return String(value);\r\n const meta = metaFor(options);\r\n const {\r\n locale: _l,\r\n numberingSystem: ns,\r\n ...intlOpts\r\n } = options ?? {};\r\n return new Intl.NumberFormat(meta.intlLocale, {\r\n numberingSystem: ns ?? meta.numberingSystem,\r\n ...intlOpts,\r\n }).format(n);\r\n}\r\n\r\n/** Intl date formatting; calendar follows locale meta until DateAdapter (PR-128). */\r\nexport function formatLocaleDate(\r\n value: unknown,\r\n options?: FormatOptions & Intl.DateTimeFormatOptions,\r\n): string | null {\r\n if (value == null || value === '') return null;\r\n const date =\r\n typeof value === 'number' ? new Date(value) : new Date(String(value));\r\n if (Number.isNaN(date.getTime())) return null;\r\n const meta = metaFor(options);\r\n const {\r\n locale: _l,\r\n numberingSystem: ns,\r\n ...intlOpts\r\n } = options ?? {};\r\n const calendar =\r\n meta.calendar === 'persian'\r\n ? 'persian'\r\n : meta.calendar === 'islamic'\r\n ? 'islamic'\r\n : 'gregory';\r\n return new Intl.DateTimeFormat(meta.intlLocale, {\r\n calendar,\r\n numberingSystem: ns ?? meta.numberingSystem,\r\n year: 'numeric',\r\n month: '2-digit',\r\n day: '2-digit',\r\n ...intlOpts,\r\n }).format(date);\r\n}\r\n"]}
@@ -0,0 +1,257 @@
1
+ 'use strict';
2
+
3
+ // engine/dataOps/sortModel.ts
4
+ var INDEX_COL_ID = "index";
5
+ var FA_COLLATOR = new Intl.Collator("fa", {
6
+ numeric: true,
7
+ sensitivity: "base"
8
+ });
9
+ var EASTERN_DIGITS = /[۰-۹٠-٩]/g;
10
+ var EASTERN_DIGIT_MAP = {
11
+ "\u06F0": "0",
12
+ "\u06F1": "1",
13
+ "\u06F2": "2",
14
+ "\u06F3": "3",
15
+ "\u06F4": "4",
16
+ "\u06F5": "5",
17
+ "\u06F6": "6",
18
+ "\u06F7": "7",
19
+ "\u06F8": "8",
20
+ "\u06F9": "9",
21
+ "\u0660": "0",
22
+ "\u0661": "1",
23
+ "\u0662": "2",
24
+ "\u0663": "3",
25
+ "\u0664": "4",
26
+ "\u0665": "5",
27
+ "\u0666": "6",
28
+ "\u0667": "7",
29
+ "\u0668": "8",
30
+ "\u0669": "9"
31
+ };
32
+ function normalizeDigits(value) {
33
+ return value.replace(EASTERN_DIGITS, (ch) => EASTERN_DIGIT_MAP[ch] ?? ch);
34
+ }
35
+ function isBlankSortValue(value) {
36
+ if (value == null) return true;
37
+ if (typeof value === "number" && Number.isNaN(value)) return true;
38
+ if (typeof value === "string" && value.trim() === "") return true;
39
+ return false;
40
+ }
41
+ function toNumber(value) {
42
+ if (typeof value === "number") {
43
+ return Number.isFinite(value) ? value : null;
44
+ }
45
+ if (typeof value === "boolean") return value ? 1 : 0;
46
+ if (typeof value === "string") {
47
+ const n = Number(normalizeDigits(value).replace(/,/g, "").trim());
48
+ return Number.isFinite(n) ? n : null;
49
+ }
50
+ return null;
51
+ }
52
+ function toDateKey(value) {
53
+ if (value instanceof Date) {
54
+ const t = value.getTime();
55
+ return Number.isNaN(t) ? null : t;
56
+ }
57
+ if (typeof value === "number" && Number.isFinite(value)) return value;
58
+ if (typeof value === "string") {
59
+ const text = normalizeDigits(value).trim();
60
+ if (!text) return null;
61
+ const parsed = Date.parse(text);
62
+ if (!Number.isNaN(parsed)) return parsed;
63
+ const digits = text.replace(/\D/g, "");
64
+ if (digits.length >= 8) return Number(digits.slice(0, 8));
65
+ }
66
+ return null;
67
+ }
68
+ function toBoolean(value) {
69
+ if (typeof value === "boolean") return value;
70
+ if (value === 1 || value === "1" || value === "true") return true;
71
+ if (value === 0 || value === "0" || value === "false") return false;
72
+ return null;
73
+ }
74
+ function compareText(a, b) {
75
+ return FA_COLLATOR.compare(String(a), String(b));
76
+ }
77
+ function compareFinite(a, b) {
78
+ return a < b ? -1 : a > b ? 1 : 0;
79
+ }
80
+ function compareTypedValues(a, b, fieldType) {
81
+ switch (fieldType) {
82
+ case "number":
83
+ case "price":
84
+ case "index": {
85
+ const na = toNumber(a);
86
+ const nb = toNumber(b);
87
+ if (na == null && nb == null) return compareText(a, b);
88
+ if (na == null) return 1;
89
+ if (nb == null) return -1;
90
+ return compareFinite(na, nb);
91
+ }
92
+ case "date": {
93
+ const da = toDateKey(a);
94
+ const db = toDateKey(b);
95
+ if (da == null && db == null) return compareText(a, b);
96
+ if (da == null) return 1;
97
+ if (db == null) return -1;
98
+ return compareFinite(da, db);
99
+ }
100
+ case "checkbox": {
101
+ const ba = toBoolean(a);
102
+ const bb = toBoolean(b);
103
+ if (ba == null && bb == null) return compareText(a, b);
104
+ if (ba == null) return 1;
105
+ if (bb == null) return -1;
106
+ return Number(ba) - Number(bb);
107
+ }
108
+ default:
109
+ return compareText(a, b);
110
+ }
111
+ }
112
+ function compareSortValues(a, b, fieldType, comparator) {
113
+ if (comparator) return comparator(a, b);
114
+ return compareTypedValues(a, b, fieldType);
115
+ }
116
+ function isSortDirection(value) {
117
+ return value === "asc" || value === "desc";
118
+ }
119
+ function resolveKeys(sortModel) {
120
+ const keys = [];
121
+ const seen = /* @__PURE__ */ new Set();
122
+ for (const item of sortModel) {
123
+ if (!item || typeof item.colId !== "string" || item.colId.length === 0) {
124
+ continue;
125
+ }
126
+ if (!isSortDirection(item.sort) || seen.has(item.colId)) continue;
127
+ seen.add(item.colId);
128
+ keys.push({ colId: item.colId, sort: item.sort });
129
+ }
130
+ if (!seen.has(INDEX_COL_ID)) {
131
+ keys.push({ colId: INDEX_COL_ID, sort: "asc" });
132
+ }
133
+ return keys;
134
+ }
135
+ function applySort(rowIds, sortModel, accessor) {
136
+ const keys = resolveKeys(sortModel);
137
+ const decorated = rowIds.map((rowId, originalIndex) => ({
138
+ rowId,
139
+ originalIndex
140
+ }));
141
+ decorated.sort((left, right) => {
142
+ for (const key of keys) {
143
+ const a = accessor.getValue(left.rowId, key.colId);
144
+ const b = accessor.getValue(right.rowId, key.colId);
145
+ const aBlank = isBlankSortValue(a);
146
+ const bBlank = isBlankSortValue(b);
147
+ if (aBlank || bBlank) {
148
+ if (aBlank && bBlank) continue;
149
+ return aBlank ? 1 : -1;
150
+ }
151
+ const fieldType = accessor.getFieldType?.(key.colId) ?? (key.colId === INDEX_COL_ID ? "index" : void 0);
152
+ const cmp = compareSortValues(
153
+ a,
154
+ b,
155
+ fieldType,
156
+ accessor.getComparator?.(key.colId)
157
+ );
158
+ if (cmp !== 0) return key.sort === "desc" ? -cmp : cmp;
159
+ }
160
+ return left.originalIndex - right.originalIndex;
161
+ });
162
+ return decorated.map((row) => row.rowId);
163
+ }
164
+ function compareRowIdsForSort(leftId, rightId, sortModel, accessor) {
165
+ const keys = resolveKeys(sortModel);
166
+ for (const key of keys) {
167
+ const a = accessor.getValue(leftId, key.colId);
168
+ const b = accessor.getValue(rightId, key.colId);
169
+ const aBlank = isBlankSortValue(a);
170
+ const bBlank = isBlankSortValue(b);
171
+ if (aBlank || bBlank) {
172
+ if (aBlank && bBlank) continue;
173
+ return aBlank ? 1 : -1;
174
+ }
175
+ const fieldType = accessor.getFieldType?.(key.colId) ?? (key.colId === INDEX_COL_ID ? "index" : void 0);
176
+ const cmp = compareSortValues(
177
+ a,
178
+ b,
179
+ fieldType,
180
+ accessor.getComparator?.(key.colId)
181
+ );
182
+ if (cmp !== 0) return key.sort === "desc" ? -cmp : cmp;
183
+ }
184
+ return leftId - rightId;
185
+ }
186
+ function findSortedInsertIndex(orderedIds, rowId, sortModel, accessor) {
187
+ let lo = 0;
188
+ let hi = orderedIds.length;
189
+ while (lo < hi) {
190
+ const mid = lo + hi >> 1;
191
+ const midId = orderedIds[mid];
192
+ if (compareRowIdsForSort(midId, rowId, sortModel, accessor) <= 0) {
193
+ lo = mid + 1;
194
+ } else {
195
+ hi = mid;
196
+ }
197
+ }
198
+ return lo;
199
+ }
200
+ var HEADER_SORT_CLICK_MAX_MOVE_PX = 5;
201
+ function shouldCommitHeaderSortClick(movedPx) {
202
+ return Number.isFinite(movedPx) && movedPx < HEADER_SORT_CLICK_MAX_MOVE_PX;
203
+ }
204
+ function cycleSortModel(current, colId, options = {}) {
205
+ if (typeof colId !== "string" || colId.length === 0) {
206
+ return current.slice();
207
+ }
208
+ if (colId === INDEX_COL_ID) return current.slice();
209
+ const multi = Boolean(options.multi);
210
+ const existing = current.findIndex((item2) => item2.colId === colId);
211
+ if (!multi) {
212
+ const only = current.length === 1 && current[0]?.colId === colId ? current[0] : null;
213
+ if (!only) return [{ colId, sort: "asc" }];
214
+ if (only.sort === "asc") return [{ colId, sort: "desc" }];
215
+ return [];
216
+ }
217
+ if (existing === -1) {
218
+ return [...current, { colId, sort: "asc" }];
219
+ }
220
+ const item = current[existing];
221
+ if (item?.sort === "asc") {
222
+ return current.map(
223
+ (entry, index) => index === existing ? { colId, sort: "desc" } : entry
224
+ );
225
+ }
226
+ return current.filter((_, index) => index !== existing);
227
+ }
228
+ function ariaSortForColumn(sortModel, colId) {
229
+ const item = sortModel.find((entry) => entry.colId === colId);
230
+ if (!item) return "none";
231
+ return item.sort === "asc" ? "ascending" : "descending";
232
+ }
233
+ function sortPriorityForColumn(sortModel, colId) {
234
+ const index = sortModel.findIndex((entry) => entry.colId === colId);
235
+ return index >= 0 ? index + 1 : void 0;
236
+ }
237
+ function isHeaderColumnSortable(col) {
238
+ if (col.fieldName === INDEX_COL_ID || col.fieldType === "index") return false;
239
+ if (col.columnDef?.sortable === false) return false;
240
+ return true;
241
+ }
242
+
243
+ exports.HEADER_SORT_CLICK_MAX_MOVE_PX = HEADER_SORT_CLICK_MAX_MOVE_PX;
244
+ exports.INDEX_COL_ID = INDEX_COL_ID;
245
+ exports.applySort = applySort;
246
+ exports.ariaSortForColumn = ariaSortForColumn;
247
+ exports.compareSortValues = compareSortValues;
248
+ exports.compareTypedValues = compareTypedValues;
249
+ exports.cycleSortModel = cycleSortModel;
250
+ exports.findSortedInsertIndex = findSortedInsertIndex;
251
+ exports.isBlankSortValue = isBlankSortValue;
252
+ exports.isHeaderColumnSortable = isHeaderColumnSortable;
253
+ exports.normalizeDigits = normalizeDigits;
254
+ exports.shouldCommitHeaderSortClick = shouldCommitHeaderSortClick;
255
+ exports.sortPriorityForColumn = sortPriorityForColumn;
256
+ //# sourceMappingURL=chunk-DFFP7SJ6.cjs.map
257
+ //# sourceMappingURL=chunk-DFFP7SJ6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../engine/dataOps/sortModel.ts"],"names":["item"],"mappings":"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","file":"chunk-DFFP7SJ6.cjs","sourcesContent":["import type { FieldType } from '../../domain/types/ColumnSchema';\r\n\r\n/** Document-order column used as the final tie-breaker (PR-89). */\r\nexport const INDEX_COL_ID = 'index';\r\n\r\nexport type SortDirection = 'asc' | 'desc';\r\n\r\nexport type SortModelItem = {\r\n colId: string;\r\n sort: SortDirection;\r\n};\r\n\r\nexport type SortModel = readonly SortModelItem[];\r\n\r\nexport type SortValueComparator = (a: unknown, b: unknown) => number;\r\n\r\nexport type SortAccessor = {\r\n getValue: (rowId: number, colId: string) => unknown;\r\n getFieldType?: (colId: string) => FieldType | undefined;\r\n getComparator?: (colId: string) => SortValueComparator | undefined;\r\n};\r\n\r\nconst FA_COLLATOR = new Intl.Collator('fa', {\r\n numeric: true,\r\n sensitivity: 'base',\r\n});\r\n\r\nconst EASTERN_DIGITS = /[۰-۹٠-٩]/g;\r\nconst EASTERN_DIGIT_MAP: Record<string, string> = {\r\n '۰': '0',\r\n '۱': '1',\r\n '۲': '2',\r\n '۳': '3',\r\n '۴': '4',\r\n '۵': '5',\r\n '۶': '6',\r\n '۷': '7',\r\n '۸': '8',\r\n '۹': '9',\r\n '٠': '0',\r\n '١': '1',\r\n '٢': '2',\r\n '٣': '3',\r\n '٤': '4',\r\n '٥': '5',\r\n '٦': '6',\r\n '٧': '7',\r\n '٨': '8',\r\n '٩': '9',\r\n};\r\n\r\nexport function normalizeDigits(value: string): string {\r\n return value.replace(EASTERN_DIGITS, (ch) => EASTERN_DIGIT_MAP[ch] ?? ch);\r\n}\r\n\r\nexport function isBlankSortValue(value: unknown): boolean {\r\n if (value == null) return true;\r\n if (typeof value === 'number' && Number.isNaN(value)) return true;\r\n if (typeof value === 'string' && value.trim() === '') return true;\r\n return false;\r\n}\r\n\r\nfunction toNumber(value: unknown): number | null {\r\n if (typeof value === 'number') {\r\n return Number.isFinite(value) ? value : null;\r\n }\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n if (typeof value === 'string') {\r\n const n = Number(normalizeDigits(value).replace(/,/g, '').trim());\r\n return Number.isFinite(n) ? n : null;\r\n }\r\n return null;\r\n}\r\n\r\nfunction toDateKey(value: unknown): number | null {\r\n if (value instanceof Date) {\r\n const t = value.getTime();\r\n return Number.isNaN(t) ? null : t;\r\n }\r\n if (typeof value === 'number' && Number.isFinite(value)) return value;\r\n if (typeof value === 'string') {\r\n const text = normalizeDigits(value).trim();\r\n if (!text) return null;\r\n const parsed = Date.parse(text);\r\n if (!Number.isNaN(parsed)) return parsed;\r\n const digits = text.replace(/\\D/g, '');\r\n if (digits.length >= 8) return Number(digits.slice(0, 8));\r\n }\r\n return null;\r\n}\r\n\r\nfunction toBoolean(value: unknown): boolean | null {\r\n if (typeof value === 'boolean') return value;\r\n if (value === 1 || value === '1' || value === 'true') return true;\r\n if (value === 0 || value === '0' || value === 'false') return false;\r\n return null;\r\n}\r\n\r\nfunction compareText(a: unknown, b: unknown): number {\r\n return FA_COLLATOR.compare(String(a), String(b));\r\n}\r\n\r\nfunction compareFinite(a: number, b: number): number {\r\n return a < b ? -1 : a > b ? 1 : 0;\r\n}\r\n\r\n/**\r\n * Ascending compare for a FieldType. Blank handling is done by `compareSortValues`.\r\n */\r\nexport function compareTypedValues(\r\n a: unknown,\r\n b: unknown,\r\n fieldType: FieldType | undefined,\r\n): number {\r\n switch (fieldType) {\r\n case 'number':\r\n case 'price':\r\n case 'index': {\r\n const na = toNumber(a);\r\n const nb = toNumber(b);\r\n if (na == null && nb == null) return compareText(a, b);\r\n if (na == null) return 1;\r\n if (nb == null) return -1;\r\n return compareFinite(na, nb);\r\n }\r\n case 'date': {\r\n const da = toDateKey(a);\r\n const db = toDateKey(b);\r\n if (da == null && db == null) return compareText(a, b);\r\n if (da == null) return 1;\r\n if (db == null) return -1;\r\n return compareFinite(da, db);\r\n }\r\n case 'checkbox': {\r\n const ba = toBoolean(a);\r\n const bb = toBoolean(b);\r\n if (ba == null && bb == null) return compareText(a, b);\r\n if (ba == null) return 1;\r\n if (bb == null) return -1;\r\n return Number(ba) - Number(bb);\r\n }\r\n default:\r\n return compareText(a, b);\r\n }\r\n}\r\n\r\nexport function compareSortValues(\r\n a: unknown,\r\n b: unknown,\r\n fieldType: FieldType | undefined,\r\n comparator: SortValueComparator | undefined,\r\n): number {\r\n if (comparator) return comparator(a, b);\r\n return compareTypedValues(a, b, fieldType);\r\n}\r\n\r\nfunction isSortDirection(value: string): value is SortDirection {\r\n return value === 'asc' || value === 'desc';\r\n}\r\n\r\nfunction resolveKeys(sortModel: SortModel): SortModelItem[] {\r\n const keys: SortModelItem[] = [];\r\n const seen = new Set<string>();\r\n for (const item of sortModel) {\r\n if (!item || typeof item.colId !== 'string' || item.colId.length === 0) {\r\n continue;\r\n }\r\n if (!isSortDirection(item.sort) || seen.has(item.colId)) continue;\r\n seen.add(item.colId);\r\n keys.push({ colId: item.colId, sort: item.sort });\r\n }\r\n if (!seen.has(INDEX_COL_ID)) {\r\n keys.push({ colId: INDEX_COL_ID, sort: 'asc' });\r\n }\r\n return keys;\r\n}\r\n\r\n/**\r\n * Pure multi-sort (PR-89). Does not mutate `rowIds`.\r\n * Null/blank values sort last in both directions. `index` is the last\r\n * tie-breaker so document order is preserved when sort keys match.\r\n */\r\nexport function applySort(\r\n rowIds: readonly number[],\r\n sortModel: SortModel,\r\n accessor: SortAccessor,\r\n): number[] {\r\n const keys = resolveKeys(sortModel);\r\n const decorated = rowIds.map((rowId, originalIndex) => ({\r\n rowId,\r\n originalIndex,\r\n }));\r\n\r\n decorated.sort((left, right) => {\r\n for (const key of keys) {\r\n const a = accessor.getValue(left.rowId, key.colId);\r\n const b = accessor.getValue(right.rowId, key.colId);\r\n const aBlank = isBlankSortValue(a);\r\n const bBlank = isBlankSortValue(b);\r\n if (aBlank || bBlank) {\r\n if (aBlank && bBlank) continue;\r\n return aBlank ? 1 : -1;\r\n }\r\n const fieldType =\r\n accessor.getFieldType?.(key.colId) ??\r\n (key.colId === INDEX_COL_ID ? 'index' : undefined);\r\n const cmp = compareSortValues(\r\n a,\r\n b,\r\n fieldType,\r\n accessor.getComparator?.(key.colId),\r\n );\r\n if (cmp !== 0) return key.sort === 'desc' ? -cmp : cmp;\r\n }\r\n return left.originalIndex - right.originalIndex;\r\n });\r\n\r\n return decorated.map((row) => row.rowId);\r\n}\r\n\r\n/**\r\n * Compare two row ids under the same rules as {@link applySort}\r\n * (without original-index stability — uses id as final tie-break).\r\n * Used for O(log n) binary insert into an already-sorted UI index (PR-99).\r\n */\r\nexport function compareRowIdsForSort(\r\n leftId: number,\r\n rightId: number,\r\n sortModel: SortModel,\r\n accessor: SortAccessor,\r\n): number {\r\n const keys = resolveKeys(sortModel);\r\n for (const key of keys) {\r\n const a = accessor.getValue(leftId, key.colId);\r\n const b = accessor.getValue(rightId, key.colId);\r\n const aBlank = isBlankSortValue(a);\r\n const bBlank = isBlankSortValue(b);\r\n if (aBlank || bBlank) {\r\n if (aBlank && bBlank) continue;\r\n return aBlank ? 1 : -1;\r\n }\r\n const fieldType =\r\n accessor.getFieldType?.(key.colId) ??\r\n (key.colId === INDEX_COL_ID ? 'index' : undefined);\r\n const cmp = compareSortValues(\r\n a,\r\n b,\r\n fieldType,\r\n accessor.getComparator?.(key.colId),\r\n );\r\n if (cmp !== 0) return key.sort === 'desc' ? -cmp : cmp;\r\n }\r\n return leftId - rightId;\r\n}\r\n\r\n/** Binary-search insert position for `rowId` into an already-sorted id list. */\r\nexport function findSortedInsertIndex(\r\n orderedIds: readonly number[],\r\n rowId: number,\r\n sortModel: SortModel,\r\n accessor: SortAccessor,\r\n): number {\r\n let lo = 0;\r\n let hi = orderedIds.length;\r\n while (lo < hi) {\r\n const mid = (lo + hi) >> 1;\r\n const midId = orderedIds[mid]!;\r\n if (compareRowIdsForSort(midId, rowId, sortModel, accessor) <= 0) {\r\n lo = mid + 1;\r\n } else {\r\n hi = mid;\r\n }\r\n }\r\n return lo;\r\n}\r\n\r\n/** Max pointer movement (px) that still counts as a header sort click (PR-91). */\r\nexport const HEADER_SORT_CLICK_MAX_MOVE_PX = 5;\r\n\r\n/**\r\n * True when pointer travel is below the drag threshold so a header click\r\n * should change sort (not a column reorder gesture).\r\n */\r\nexport function shouldCommitHeaderSortClick(movedPx: number): boolean {\r\n return Number.isFinite(movedPx) && movedPx < HEADER_SORT_CLICK_MAX_MOVE_PX;\r\n}\r\n\r\nexport type CycleSortModelOptions = {\r\n /** Shift+Click: keep other columns; otherwise replace with this column. */\r\n multi?: boolean;\r\n};\r\n\r\n/**\r\n * Header click cycle (PR-91): none → asc → desc → none.\r\n * Without `multi`, the model becomes a single column (or empty).\r\n * With `multi`, the column is appended / toggled / removed in place.\r\n */\r\nexport function cycleSortModel(\r\n current: SortModel,\r\n colId: string,\r\n options: CycleSortModelOptions = {},\r\n): SortModel {\r\n if (typeof colId !== 'string' || colId.length === 0) {\r\n return current.slice();\r\n }\r\n if (colId === INDEX_COL_ID) return current.slice();\r\n\r\n const multi = Boolean(options.multi);\r\n const existing = current.findIndex((item) => item.colId === colId);\r\n\r\n if (!multi) {\r\n const only =\r\n current.length === 1 && current[0]?.colId === colId ? current[0] : null;\r\n if (!only) return [{ colId, sort: 'asc' }];\r\n if (only.sort === 'asc') return [{ colId, sort: 'desc' }];\r\n return [];\r\n }\r\n\r\n if (existing === -1) {\r\n return [...current, { colId, sort: 'asc' }];\r\n }\r\n const item = current[existing];\r\n if (item?.sort === 'asc') {\r\n return current.map((entry, index) =>\r\n index === existing ? { colId, sort: 'desc' } : entry,\r\n );\r\n }\r\n return current.filter((_, index) => index !== existing);\r\n}\r\n\r\nexport type AriaSortValue = 'ascending' | 'descending' | 'none';\r\n\r\nexport function ariaSortForColumn(\r\n sortModel: SortModel,\r\n colId: string,\r\n): AriaSortValue {\r\n const item = sortModel.find((entry) => entry.colId === colId);\r\n if (!item) return 'none';\r\n return item.sort === 'asc' ? 'ascending' : 'descending';\r\n}\r\n\r\n/** 1-based priority for multi-sort badge; undefined when column is unsorted. */\r\nexport function sortPriorityForColumn(\r\n sortModel: SortModel,\r\n colId: string,\r\n): number | undefined {\r\n const index = sortModel.findIndex((entry) => entry.colId === colId);\r\n return index >= 0 ? index + 1 : undefined;\r\n}\r\n\r\n/** Index column and `sortable: false` are never header-sortable. */\r\nexport function isHeaderColumnSortable(col: {\r\n fieldName: string;\r\n fieldType?: string;\r\n columnDef?: { sortable?: boolean } | null;\r\n}): boolean {\r\n if (col.fieldName === INDEX_COL_ID || col.fieldType === 'index') return false;\r\n if (col.columnDef?.sortable === false) return false;\r\n return true;\r\n}\r\n"]}