@customafk/lunas-ui 0.2.80 → 0.2.82

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 (137) hide show
  1. package/dist/{analysis-panel-Bg0lCfWv.cjs → analysis-panel-BoKjkPYz.cjs} +2 -2
  2. package/dist/{analysis-panel-Bg0lCfWv.cjs.map → analysis-panel-BoKjkPYz.cjs.map} +1 -1
  3. package/dist/{analysis-panel-Cop-l4lx.mjs → analysis-panel-CZ8g9AAO.mjs} +2 -2
  4. package/dist/{analysis-panel-Cop-l4lx.mjs.map → analysis-panel-CZ8g9AAO.mjs.map} +1 -1
  5. package/dist/{badge-display-B0BKsU9T.mjs → badge-display-B5m09_Hs.mjs} +2 -2
  6. package/dist/{badge-display-B0BKsU9T.mjs.map → badge-display-B5m09_Hs.mjs.map} +1 -1
  7. package/dist/{badge-display-Dv2UTvzp.cjs → badge-display-DHbCN998.cjs} +2 -2
  8. package/dist/{badge-display-Dv2UTvzp.cjs.map → badge-display-DHbCN998.cjs.map} +1 -1
  9. package/dist/{boolean-display-CMX5AupA.mjs → boolean-display-CzHHDfHW.mjs} +2 -2
  10. package/dist/{boolean-display-CMX5AupA.mjs.map → boolean-display-CzHHDfHW.mjs.map} +1 -1
  11. package/dist/{boolean-display-CPX7H39m.cjs → boolean-display-D2wjQhNX.cjs} +2 -2
  12. package/dist/{boolean-display-CPX7H39m.cjs.map → boolean-display-D2wjQhNX.cjs.map} +1 -1
  13. package/dist/currency-display-7w-ZjVUw.mjs +2 -0
  14. package/dist/currency-display-7w-ZjVUw.mjs.map +1 -0
  15. package/dist/currency-display-B06kc2IG.cjs +2 -0
  16. package/dist/currency-display-B06kc2IG.cjs.map +1 -0
  17. package/dist/{date-display-YE8NIIrl.mjs → date-display-BO7OY_AC.mjs} +2 -2
  18. package/dist/{date-display-YE8NIIrl.mjs.map → date-display-BO7OY_AC.mjs.map} +1 -1
  19. package/dist/{date-display-DMPhFq8v.cjs → date-display-DHnZr_yf.cjs} +2 -2
  20. package/dist/{date-display-DMPhFq8v.cjs.map → date-display-DHnZr_yf.cjs.map} +1 -1
  21. package/dist/{description-display-B4KoH6ql.mjs → description-display-CBfoP3Y2.mjs} +2 -2
  22. package/dist/{description-display-B4KoH6ql.mjs.map → description-display-CBfoP3Y2.mjs.map} +1 -1
  23. package/dist/{description-display-jmAaeMBD.cjs → description-display-Cckihd1s.cjs} +2 -2
  24. package/dist/{description-display-jmAaeMBD.cjs.map → description-display-Cckihd1s.cjs.map} +1 -1
  25. package/dist/dialogs/side-panel.cjs +2 -0
  26. package/dist/dialogs/side-panel.cjs.map +1 -0
  27. package/dist/dialogs/side-panel.d.cts +2 -0
  28. package/dist/dialogs/side-panel.d.mts +2 -0
  29. package/dist/dialogs/side-panel.mjs +2 -0
  30. package/dist/dialogs/side-panel.mjs.map +1 -0
  31. package/dist/{email-display-D_k7AUmp.mjs → email-display-Bk_furIx.mjs} +2 -2
  32. package/dist/{email-display-D_k7AUmp.mjs.map → email-display-Bk_furIx.mjs.map} +1 -1
  33. package/dist/{email-display-CzvqQMhG.cjs → email-display-w-hRYIeL.cjs} +2 -2
  34. package/dist/{email-display-CzvqQMhG.cjs.map → email-display-w-hRYIeL.cjs.map} +1 -1
  35. package/dist/features/tables/index.cjs +1 -1
  36. package/dist/features/tables/index.d.cts +1 -1
  37. package/dist/features/tables/index.d.mts +1 -1
  38. package/dist/features/tables/index.mjs +1 -1
  39. package/dist/filter-BO7ISTIR.mjs +2 -0
  40. package/dist/{filter-BCNjqiBx.mjs.map → filter-BO7ISTIR.mjs.map} +1 -1
  41. package/dist/filter-CQ9BD0MV.cjs +2 -0
  42. package/dist/{filter-B5EnnL9I.cjs.map → filter-CQ9BD0MV.cjs.map} +1 -1
  43. package/dist/{flex-CIzZIICK.d.cts → flex-CrxTaAXE.d.cts} +2 -2
  44. package/dist/{flex-CIzZIICK.d.mts → flex-CrxTaAXE.d.mts} +2 -2
  45. package/dist/{index-DiloQ0Ev.d.mts → index-BPo-Lg3p.d.mts} +7 -3
  46. package/dist/{index-DmrQBf4E.d.cts → index-DaLpXe5l.d.cts} +7 -3
  47. package/dist/index.cjs +1 -1
  48. package/dist/index.d.cts +6 -4
  49. package/dist/index.d.mts +6 -4
  50. package/dist/index.mjs +1 -1
  51. package/dist/layouts/flex.d.cts +1 -1
  52. package/dist/layouts/flex.d.mts +1 -1
  53. package/dist/layouts/ui-grid.cjs +2 -0
  54. package/dist/layouts/ui-grid.cjs.map +1 -0
  55. package/dist/layouts/ui-grid.d.cts +2 -0
  56. package/dist/layouts/ui-grid.d.mts +2 -0
  57. package/dist/layouts/ui-grid.mjs +2 -0
  58. package/dist/layouts/ui-grid.mjs.map +1 -0
  59. package/dist/{list-display-DPxZ_Jbf.cjs → list-display-DDeJoneW.cjs} +2 -2
  60. package/dist/{list-display-DPxZ_Jbf.cjs.map → list-display-DDeJoneW.cjs.map} +1 -1
  61. package/dist/{list-display-M43N3kle.mjs → list-display-DLsm8uAh.mjs} +2 -2
  62. package/dist/{list-display-M43N3kle.mjs.map → list-display-DLsm8uAh.mjs.map} +1 -1
  63. package/dist/{name-display-BJ1wPUnS.cjs → name-display-CKnyugrP.cjs} +2 -2
  64. package/dist/{name-display-BJ1wPUnS.cjs.map → name-display-CKnyugrP.cjs.map} +1 -1
  65. package/dist/{name-display-pWhLLS05.mjs → name-display-H5HFH1fU.mjs} +2 -2
  66. package/dist/{name-display-pWhLLS05.mjs.map → name-display-H5HFH1fU.mjs.map} +1 -1
  67. package/dist/{permalink-BaMvnKIz.mjs → permalink-CaCx9fi6.mjs} +2 -2
  68. package/dist/{permalink-BaMvnKIz.mjs.map → permalink-CaCx9fi6.mjs.map} +1 -1
  69. package/dist/{permalink-CMcI__V4.cjs → permalink-azuGQg2b.cjs} +2 -2
  70. package/dist/{permalink-CMcI__V4.cjs.map → permalink-azuGQg2b.cjs.map} +1 -1
  71. package/dist/{phone-number-ao2oCmrO.mjs → phone-number-Ba-f4s1Y.mjs} +2 -2
  72. package/dist/{phone-number-ao2oCmrO.mjs.map → phone-number-Ba-f4s1Y.mjs.map} +1 -1
  73. package/dist/{phone-number-F9I9sNLK.cjs → phone-number-BqRhKQdr.cjs} +2 -2
  74. package/dist/{phone-number-F9I9sNLK.cjs.map → phone-number-BqRhKQdr.cjs.map} +1 -1
  75. package/dist/{progress-display-atwRFD6e.mjs → progress-display-0UsBzt_r.mjs} +2 -2
  76. package/dist/{progress-display-atwRFD6e.mjs.map → progress-display-0UsBzt_r.mjs.map} +1 -1
  77. package/dist/{progress-display-F8xXJ3T1.cjs → progress-display-CiYWPOnq.cjs} +2 -2
  78. package/dist/{progress-display-F8xXJ3T1.cjs.map → progress-display-CiYWPOnq.cjs.map} +1 -1
  79. package/dist/{resizable-CWmitx5U.d.mts → resizable-C3uADYIg.d.cts} +2 -2
  80. package/dist/{resizable-CWmitx5U.d.cts → resizable-C3uADYIg.d.mts} +2 -2
  81. package/dist/side-panel-DPrM5ygG.d.cts +86 -0
  82. package/dist/side-panel-DPrM5ygG.d.mts +86 -0
  83. package/dist/statistic-639yMA2d.mjs +2 -0
  84. package/dist/statistic-639yMA2d.mjs.map +1 -0
  85. package/dist/statistic-CE_Jg8SN.cjs +2 -0
  86. package/dist/statistic-CE_Jg8SN.cjs.map +1 -0
  87. package/dist/{status-display-DInGGgiP.mjs → status-display-BCYpNJmd.mjs} +2 -2
  88. package/dist/{status-display-DInGGgiP.mjs.map → status-display-BCYpNJmd.mjs.map} +1 -1
  89. package/dist/{status-display-DpKsYvZJ.cjs → status-display-xcCCGpGS.cjs} +2 -2
  90. package/dist/{status-display-DpKsYvZJ.cjs.map → status-display-xcCCGpGS.cjs.map} +1 -1
  91. package/dist/{summary-bar-DKZh-VSB.cjs → summary-bar-C08g8bb1.cjs} +2 -2
  92. package/dist/{summary-bar-DKZh-VSB.cjs.map → summary-bar-C08g8bb1.cjs.map} +1 -1
  93. package/dist/{summary-bar-DX_sOiuL.mjs → summary-bar-C3NAnI3V.mjs} +2 -2
  94. package/dist/{summary-bar-DX_sOiuL.mjs.map → summary-bar-C3NAnI3V.mjs.map} +1 -1
  95. package/dist/tables-BqZ4Zs6e.cjs +2 -0
  96. package/dist/tables-BqZ4Zs6e.cjs.map +1 -0
  97. package/dist/tables-Dg3KMBKA.mjs +2 -0
  98. package/dist/tables-Dg3KMBKA.mjs.map +1 -0
  99. package/dist/tooltip-BVzKgxrZ.cjs +4 -0
  100. package/dist/tooltip-BVzKgxrZ.cjs.map +1 -0
  101. package/dist/tooltip-D7U_Nl5c.mjs +4 -0
  102. package/dist/tooltip-D7U_Nl5c.mjs.map +1 -0
  103. package/dist/ui/alert-dialog.cjs +1 -1
  104. package/dist/ui/alert-dialog.cjs.map +1 -1
  105. package/dist/ui/alert-dialog.mjs +1 -1
  106. package/dist/ui/alert-dialog.mjs.map +1 -1
  107. package/dist/ui/dialog.cjs +1 -1
  108. package/dist/ui/dialog.cjs.map +1 -1
  109. package/dist/ui/dialog.mjs +1 -1
  110. package/dist/ui/dialog.mjs.map +1 -1
  111. package/dist/ui/resizable.d.cts +1 -1
  112. package/dist/ui/resizable.d.mts +1 -1
  113. package/dist/ui/sheet.cjs +1 -1
  114. package/dist/ui/sheet.cjs.map +1 -1
  115. package/dist/ui/sheet.mjs +1 -1
  116. package/dist/ui/sheet.mjs.map +1 -1
  117. package/dist/ui-grid-CzL5J7cm.d.cts +128 -0
  118. package/dist/ui-grid-CzL5J7cm.d.mts +128 -0
  119. package/package.json +9 -1
  120. package/dist/currency-display-CanjOswc.mjs +0 -2
  121. package/dist/currency-display-CanjOswc.mjs.map +0 -1
  122. package/dist/currency-display-xxK62yo4.cjs +0 -2
  123. package/dist/currency-display-xxK62yo4.cjs.map +0 -1
  124. package/dist/filter-B5EnnL9I.cjs +0 -2
  125. package/dist/filter-BCNjqiBx.mjs +0 -2
  126. package/dist/statistic-B9OqfhOl.cjs +0 -2
  127. package/dist/statistic-B9OqfhOl.cjs.map +0 -1
  128. package/dist/statistic-CJVc9sNs.mjs +0 -2
  129. package/dist/statistic-CJVc9sNs.mjs.map +0 -1
  130. package/dist/tables-7_KgoyS-.mjs +0 -2
  131. package/dist/tables-7_KgoyS-.mjs.map +0 -1
  132. package/dist/tables-CS3NhgTc.cjs +0 -2
  133. package/dist/tables-CS3NhgTc.cjs.map +0 -1
  134. package/dist/tooltip-BcQG6Zw9.cjs +0 -4
  135. package/dist/tooltip-BcQG6Zw9.cjs.map +0 -1
  136. package/dist/tooltip-C6flMQgc.mjs +0 -4
  137. package/dist/tooltip-C6flMQgc.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"list-display-M43N3kle.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/list-display.tsx"],"sourcesContent":["'use client';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableListDisplay} component. */\ntype Props = {\n /** Array of strings or numbers to render as inline pills. */\n items: (string | number)[] | null | undefined;\n /**\n * Maximum number of pills shown before a `+N more` overflow badge appears\n * (default: `3`).\n */\n maxVisible?: number;\n};\n\n/**\n * Renders an array of values as compact inline pills in a table cell. When the\n * list exceeds `maxVisible`, a `+N more` badge is shown; hovering it reveals all\n * remaining items in a tooltip. Renders {@link UITableEmpty} for empty or absent\n * arrays.\n *\n * @example\n * import { UITableListDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableListDisplay items={['React', 'TypeScript', 'TailwindCSS', 'Vite']} maxVisible={3} />\n */\nexport const UITableListDisplay: React.FC<Props> = ({ items, maxVisible = 3 }) => {\n if (!items || items.length === 0) return <UITableEmpty />;\n\n const visible = items.slice(0, maxVisible);\n const overflow = items.slice(maxVisible);\n\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((item, i) => (\n <span\n key={`item-${i.toString()}`}\n className=\"weak inline-flex items-center rounded border border-border bg-white px-2 py-0.5 text-text-positive text-xs\"\n >\n {item}\n </span>\n ))}\n\n {overflow.length > 0 && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex cursor-default items-center rounded-full bg-primary-bg-subtle px-2 py-0.5 text-primary-intense text-xs\">\n +{overflow.length} more\n </span>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"flex max-w-64 flex-wrap gap-1 p-2\">\n {overflow.map((item, i) => (\n <span\n key={`item-${i.toString()}`}\n className=\"inline-flex items-center rounded-full border border-border px-2 py-0.5 text-text-negative text-xs\"\n >\n {item}\n </span>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n};\n"],"mappings":"oMA4BA,MAAa,GAAuC,CAAE,QAAO,aAAa,KAAQ,CAChF,GAAI,CAAC,GAAS,EAAM,SAAW,EAAG,OAAO,EAAC,EAAD,CAAe,CAAA,EAExD,IAAM,EAAU,EAAM,MAAM,EAAG,CAAU,EACnC,EAAW,EAAM,MAAM,CAAU,EAEvC,OACE,EAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,CACG,EAAQ,KAAK,EAAM,IAClB,EAAC,OAAD,CAEE,UAAU,6GAET,SAAA,CACG,EAJC,QAAQ,EAAE,SAAS,GAIpB,CACP,EAEA,EAAS,OAAS,GACjB,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,OAAD,CAAM,UAAU,qHAAhB,SAAA,CAAqI,IACjI,EAAS,OAAO,OACd,GACQ,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QAAQ,UAAU,oCACrC,SAAA,EAAS,KAAK,EAAM,IACnB,EAAC,OAAD,CAEE,UAAU,oGAET,SAAA,CACG,EAJC,QAAQ,EAAE,SAAS,GAIpB,CACP,CACa,CAAA,CACT,CAAA,CAAA,CACM,CAAA,CAEhB,GAET"}
1
+ {"version":3,"file":"list-display-DLsm8uAh.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/list-display.tsx"],"sourcesContent":["'use client';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableListDisplay} component. */\ntype Props = {\n /** Array of strings or numbers to render as inline pills. */\n items: (string | number)[] | null | undefined;\n /**\n * Maximum number of pills shown before a `+N more` overflow badge appears\n * (default: `3`).\n */\n maxVisible?: number;\n};\n\n/**\n * Renders an array of values as compact inline pills in a table cell. When the\n * list exceeds `maxVisible`, a `+N more` badge is shown; hovering it reveals all\n * remaining items in a tooltip. Renders {@link UITableEmpty} for empty or absent\n * arrays.\n *\n * @example\n * import { UITableListDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableListDisplay items={['React', 'TypeScript', 'TailwindCSS', 'Vite']} maxVisible={3} />\n */\nexport const UITableListDisplay: React.FC<Props> = ({ items, maxVisible = 3 }) => {\n if (!items || items.length === 0) return <UITableEmpty />;\n\n const visible = items.slice(0, maxVisible);\n const overflow = items.slice(maxVisible);\n\n return (\n <div className=\"flex flex-wrap gap-1\">\n {visible.map((item, i) => (\n <span\n key={`item-${i.toString()}`}\n className=\"weak inline-flex items-center rounded border border-border bg-white px-2 py-0.5 text-text-positive text-xs\"\n >\n {item}\n </span>\n ))}\n\n {overflow.length > 0 && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex cursor-default items-center rounded-full bg-primary-bg-subtle px-2 py-0.5 text-primary-intense text-xs\">\n +{overflow.length} more\n </span>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"flex max-w-64 flex-wrap gap-1 p-2\">\n {overflow.map((item, i) => (\n <span\n key={`item-${i.toString()}`}\n className=\"inline-flex items-center rounded-full border border-border px-2 py-0.5 text-text-negative text-xs\"\n >\n {item}\n </span>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n );\n};\n"],"mappings":"oMA4BA,MAAa,GAAuC,CAAE,QAAO,aAAa,KAAQ,CAChF,GAAI,CAAC,GAAS,EAAM,SAAW,EAAG,OAAO,EAAC,EAAD,CAAe,CAAA,EAExD,IAAM,EAAU,EAAM,MAAM,EAAG,CAAU,EACnC,EAAW,EAAM,MAAM,CAAU,EAEvC,OACE,EAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,CACG,EAAQ,KAAK,EAAM,IAClB,EAAC,OAAD,CAEE,UAAU,6GAET,SAAA,CACG,EAJC,QAAQ,EAAE,SAAS,GAIpB,CACP,EAEA,EAAS,OAAS,GACjB,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,OAAD,CAAM,UAAU,qHAAhB,SAAA,CAAqI,IACjI,EAAS,OAAO,OACd,GACQ,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QAAQ,UAAU,oCACrC,SAAA,EAAS,KAAK,EAAM,IACnB,EAAC,OAAD,CAEE,UAAU,oGAET,SAAA,CACG,EAJC,QAAQ,EAAE,SAAS,GAIpB,CACP,CACa,CAAA,CACT,CAAA,CAAA,CACM,CAAA,CAEhB,GAET"}
@@ -1,2 +1,2 @@
1
- const e=require("./typography/paragraph.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-CS3NhgTc.cjs");let r=require("react/jsx-runtime");const i=({name:i})=>i?(0,r.jsxs)(t.Tooltip,{children:[(0,r.jsx)(t.TooltipTrigger,{children:(0,r.jsx)(e.Paragraph,{variant:`sm`,className:`line-clamp-2 w-full truncate text-wrap pb-px text-start`,children:i})}),(0,r.jsx)(t.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,r.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,r.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:i}),(0,r.jsxs)(`p`,{className:`w-full text-end`,children:[i.length,` chars`]})]})})]}):(0,r.jsx)(n.Q,{});exports.UITableNameDisplay=i;
2
- //# sourceMappingURL=name-display-BJ1wPUnS.cjs.map
1
+ const e=require("./typography/paragraph.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-BqZ4Zs6e.cjs");let r=require("react/jsx-runtime");const i=({name:i})=>i?(0,r.jsxs)(t.Tooltip,{children:[(0,r.jsx)(t.TooltipTrigger,{children:(0,r.jsx)(e.Paragraph,{variant:`sm`,className:`line-clamp-2 w-full truncate text-wrap pb-px text-start`,children:i})}),(0,r.jsx)(t.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,r.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,r.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:i}),(0,r.jsxs)(`p`,{className:`w-full text-end`,children:[i.length,` chars`]})]})})]}):(0,r.jsx)(n.Q,{});exports.UITableNameDisplay=i;
2
+ //# sourceMappingURL=name-display-CKnyugrP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"name-display-BJ1wPUnS.cjs","names":["UITableEmpty","Tooltip","TooltipTrigger","Paragraph","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/name-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Paragraph } from '@/components/typography/paragraph';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableNameDisplay} component. */\ntype NameDisplayProps = {\n /** The name string to display; renders an empty placeholder when falsy. */\n name?: string | null | undefined;\n};\n\n/**\n * Renders a clamped, truncated name string inside a tooltip that shows the full\n * text and character count on hover; falls back to {@link UITableEmpty} when the\n * value is absent.\n *\n * @example\n * import { UITableNameDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableNameDisplay name=\"John Doe\" />\n */\nexport const UITableNameDisplay: React.FC<NameDisplayProps> = ({ name }) => {\n if (!name) return <UITableEmpty />;\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 w-full truncate text-wrap pb-px text-start\">\n {name}\n </Paragraph>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"h-fit min-w-48 max-w-80 pt-4\">\n <div className=\"flex flex-col gap-y-2\">\n <p className=\"whitespace-pre-line text-wrap break-keep\">{name}</p>\n <p className=\"w-full text-end\">{name.length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"kJAqBA,MAAa,GAAkD,CAAE,UAC1D,GAEH,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,QAAQ,KAAK,UAAU,0DAC/B,SAAA,CACQ,CAAA,CACG,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,MAAM,QAAQ,UAAU,+BACtC,UAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wBAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,2CAA4C,SAAA,CAAQ,CAAA,GACjE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAK,OAAO,QAAS,CAClD,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA,GAdO,EAAA,EAAA,IAAA,CAACJ,EAAAA,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"name-display-CKnyugrP.cjs","names":["UITableEmpty","Tooltip","TooltipTrigger","Paragraph","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/name-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Paragraph } from '@/components/typography/paragraph';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableNameDisplay} component. */\ntype NameDisplayProps = {\n /** The name string to display; renders an empty placeholder when falsy. */\n name?: string | null | undefined;\n};\n\n/**\n * Renders a clamped, truncated name string inside a tooltip that shows the full\n * text and character count on hover; falls back to {@link UITableEmpty} when the\n * value is absent.\n *\n * @example\n * import { UITableNameDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableNameDisplay name=\"John Doe\" />\n */\nexport const UITableNameDisplay: React.FC<NameDisplayProps> = ({ name }) => {\n if (!name) return <UITableEmpty />;\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 w-full truncate text-wrap pb-px text-start\">\n {name}\n </Paragraph>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"h-fit min-w-48 max-w-80 pt-4\">\n <div className=\"flex flex-col gap-y-2\">\n <p className=\"whitespace-pre-line text-wrap break-keep\">{name}</p>\n <p className=\"w-full text-end\">{name.length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"kJAqBA,MAAa,GAAkD,CAAE,UAC1D,GAEH,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAA,UACE,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,QAAQ,KAAK,UAAU,0DAC/B,SAAA,CACQ,CAAA,CACG,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,MAAM,QAAQ,UAAU,+BACtC,UAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wBAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,2CAA4C,SAAA,CAAQ,CAAA,GACjE,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAK,OAAO,QAAS,CAClD,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA,GAdO,EAAA,EAAA,IAAA,CAACJ,EAAAA,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- import{Paragraph as e}from"./typography/paragraph.mjs";import{Tooltip as t,TooltipContent as n,TooltipTrigger as r}from"./ui/tooltip.mjs";import{Q as i}from"./tables-7_KgoyS-.mjs";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=({name:s})=>s?o(t,{children:[a(r,{children:a(e,{variant:`sm`,className:`line-clamp-2 w-full truncate text-wrap pb-px text-start`,children:s})}),a(n,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:o(`div`,{className:`flex flex-col gap-y-2`,children:[a(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:s}),o(`p`,{className:`w-full text-end`,children:[s.length,` chars`]})]})})]}):a(i,{});export{s as UITableNameDisplay};
2
- //# sourceMappingURL=name-display-pWhLLS05.mjs.map
1
+ import{Paragraph as e}from"./typography/paragraph.mjs";import{Tooltip as t,TooltipContent as n,TooltipTrigger as r}from"./ui/tooltip.mjs";import{Q as i}from"./tables-Dg3KMBKA.mjs";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=({name:s})=>s?o(t,{children:[a(r,{children:a(e,{variant:`sm`,className:`line-clamp-2 w-full truncate text-wrap pb-px text-start`,children:s})}),a(n,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:o(`div`,{className:`flex flex-col gap-y-2`,children:[a(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:s}),o(`p`,{className:`w-full text-end`,children:[s.length,` chars`]})]})})]}):a(i,{});export{s as UITableNameDisplay};
2
+ //# sourceMappingURL=name-display-H5HFH1fU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"name-display-pWhLLS05.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/name-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Paragraph } from '@/components/typography/paragraph';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableNameDisplay} component. */\ntype NameDisplayProps = {\n /** The name string to display; renders an empty placeholder when falsy. */\n name?: string | null | undefined;\n};\n\n/**\n * Renders a clamped, truncated name string inside a tooltip that shows the full\n * text and character count on hover; falls back to {@link UITableEmpty} when the\n * value is absent.\n *\n * @example\n * import { UITableNameDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableNameDisplay name=\"John Doe\" />\n */\nexport const UITableNameDisplay: React.FC<NameDisplayProps> = ({ name }) => {\n if (!name) return <UITableEmpty />;\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 w-full truncate text-wrap pb-px text-start\">\n {name}\n </Paragraph>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"h-fit min-w-48 max-w-80 pt-4\">\n <div className=\"flex flex-col gap-y-2\">\n <p className=\"whitespace-pre-line text-wrap break-keep\">{name}</p>\n <p className=\"w-full text-end\">{name.length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"sOAqBA,MAAa,GAAkD,CAAE,UAC1D,EAEH,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAW,QAAQ,KAAK,UAAU,0DAC/B,SAAA,CACQ,CAAA,CACG,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QAAQ,UAAU,+BACtC,SAAA,EAAC,MAAD,CAAK,UAAU,wBAAf,SAAA,CACE,EAAC,IAAD,CAAG,UAAU,2CAA4C,SAAA,CAAQ,CAAA,EACjE,EAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAK,OAAO,QAAS,CAClD,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA,EAdO,EAAC,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"name-display-H5HFH1fU.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/name-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Paragraph } from '@/components/typography/paragraph';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableNameDisplay} component. */\ntype NameDisplayProps = {\n /** The name string to display; renders an empty placeholder when falsy. */\n name?: string | null | undefined;\n};\n\n/**\n * Renders a clamped, truncated name string inside a tooltip that shows the full\n * text and character count on hover; falls back to {@link UITableEmpty} when the\n * value is absent.\n *\n * @example\n * import { UITableNameDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableNameDisplay name=\"John Doe\" />\n */\nexport const UITableNameDisplay: React.FC<NameDisplayProps> = ({ name }) => {\n if (!name) return <UITableEmpty />;\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 w-full truncate text-wrap pb-px text-start\">\n {name}\n </Paragraph>\n </TooltipTrigger>\n <TooltipContent align=\"start\" className=\"h-fit min-w-48 max-w-80 pt-4\">\n <div className=\"flex flex-col gap-y-2\">\n <p className=\"whitespace-pre-line text-wrap break-keep\">{name}</p>\n <p className=\"w-full text-end\">{name.length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"sOAqBA,MAAa,GAAkD,CAAE,UAC1D,EAEH,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAW,QAAQ,KAAK,UAAU,0DAC/B,SAAA,CACQ,CAAA,CACG,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QAAQ,UAAU,+BACtC,SAAA,EAAC,MAAD,CAAK,UAAU,wBAAf,SAAA,CACE,EAAC,IAAD,CAAG,UAAU,2CAA4C,SAAA,CAAQ,CAAA,EACjE,EAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAK,OAAO,QAAS,CAClD,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA,EAdO,EAAC,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- import{Q as e}from"./tables-7_KgoyS-.mjs";import{ExternalLinkIcon as t}from"lucide-react";import{jsx as n,jsxs as r}from"react/jsx-runtime";const i=({href:i,label:a})=>i?r(`a`,{href:i,target:`_blank`,className:`inline-flex items-center gap-1 truncate text-primary text-sm underline`,rel:`noopener noreferrer`,children:[n(`span`,{children:a||i}),n(t,{size:14})]}):n(e,{});export{i as UITablePermalink};
2
- //# sourceMappingURL=permalink-BaMvnKIz.mjs.map
1
+ import{Q as e}from"./tables-Dg3KMBKA.mjs";import{ExternalLinkIcon as t}from"lucide-react";import{jsx as n,jsxs as r}from"react/jsx-runtime";const i=({href:i,label:a})=>i?r(`a`,{href:i,target:`_blank`,className:`inline-flex items-center gap-1 truncate text-primary text-sm underline`,rel:`noopener noreferrer`,children:[n(`span`,{children:a||i}),n(t,{size:14})]}):n(e,{});export{i as UITablePermalink};
2
+ //# sourceMappingURL=permalink-CaCx9fi6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"permalink-BaMvnKIz.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/permalink.tsx"],"sourcesContent":["import { ExternalLinkIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders an external-link anchor with an icon for use in table cells, opening\n * the target URL in a new tab with safe `rel` attributes. Renders\n * {@link UITableEmpty} when `href` is absent.\n *\n * @example\n * import { UITablePermalink } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePermalink href=\"https://example.com/records/42\" label=\"View record\" />\n */\nexport const UITablePermalink: React.FC<{\n /** The destination URL the anchor navigates to; `null`/`undefined`/empty renders an empty state. */\n href: string | null | undefined;\n /** Optional display text; falls back to the raw `href` when omitted. */\n label?: string;\n}> = ({ href, label }) => {\n if (!href) return <UITableEmpty />;\n\n return (\n <a href={href} target=\"_blank\" className=\"inline-flex items-center gap-1 truncate text-primary text-sm underline\" rel=\"noopener noreferrer\">\n <span>{label || href}</span>\n <ExternalLinkIcon size={14} />\n </a>\n );\n};\n"],"mappings":"4IAcA,MAAa,GAKP,CAAE,OAAM,WACP,EAGH,EAAC,IAAD,CAAS,OAAM,OAAO,SAAS,UAAU,yEAAyE,IAAI,sBAAtH,SAAA,CACE,EAAC,OAAD,CAAA,SAAO,GAAS,CAAW,CAAA,EAC3B,EAAC,EAAD,CAAkB,KAAM,EAAK,CAAA,CAC5B,IANa,EAAC,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"permalink-CaCx9fi6.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/permalink.tsx"],"sourcesContent":["import { ExternalLinkIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders an external-link anchor with an icon for use in table cells, opening\n * the target URL in a new tab with safe `rel` attributes. Renders\n * {@link UITableEmpty} when `href` is absent.\n *\n * @example\n * import { UITablePermalink } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePermalink href=\"https://example.com/records/42\" label=\"View record\" />\n */\nexport const UITablePermalink: React.FC<{\n /** The destination URL the anchor navigates to; `null`/`undefined`/empty renders an empty state. */\n href: string | null | undefined;\n /** Optional display text; falls back to the raw `href` when omitted. */\n label?: string;\n}> = ({ href, label }) => {\n if (!href) return <UITableEmpty />;\n\n return (\n <a href={href} target=\"_blank\" className=\"inline-flex items-center gap-1 truncate text-primary text-sm underline\" rel=\"noopener noreferrer\">\n <span>{label || href}</span>\n <ExternalLinkIcon size={14} />\n </a>\n );\n};\n"],"mappings":"4IAcA,MAAa,GAKP,CAAE,OAAM,WACP,EAGH,EAAC,IAAD,CAAS,OAAM,OAAO,SAAS,UAAU,yEAAyE,IAAI,sBAAtH,SAAA,CACE,EAAC,OAAD,CAAA,SAAO,GAAS,CAAW,CAAA,EAC3B,EAAC,EAAD,CAAkB,KAAM,EAAK,CAAA,CAC5B,IANa,EAAC,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require("./tables-CS3NhgTc.cjs");let t=require("lucide-react"),n=require("react/jsx-runtime");const r=({href:r,label:i})=>r?(0,n.jsxs)(`a`,{href:r,target:`_blank`,className:`inline-flex items-center gap-1 truncate text-primary text-sm underline`,rel:`noopener noreferrer`,children:[(0,n.jsx)(`span`,{children:i||r}),(0,n.jsx)(t.ExternalLinkIcon,{size:14})]}):(0,n.jsx)(e.Q,{});exports.UITablePermalink=r;
2
- //# sourceMappingURL=permalink-CMcI__V4.cjs.map
1
+ const e=require("./tables-BqZ4Zs6e.cjs");let t=require("lucide-react"),n=require("react/jsx-runtime");const r=({href:r,label:i})=>r?(0,n.jsxs)(`a`,{href:r,target:`_blank`,className:`inline-flex items-center gap-1 truncate text-primary text-sm underline`,rel:`noopener noreferrer`,children:[(0,n.jsx)(`span`,{children:i||r}),(0,n.jsx)(t.ExternalLinkIcon,{size:14})]}):(0,n.jsx)(e.Q,{});exports.UITablePermalink=r;
2
+ //# sourceMappingURL=permalink-azuGQg2b.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"permalink-CMcI__V4.cjs","names":["UITableEmpty","ExternalLinkIcon"],"sources":["../packages/components/features/tables/components/atoms/permalink.tsx"],"sourcesContent":["import { ExternalLinkIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders an external-link anchor with an icon for use in table cells, opening\n * the target URL in a new tab with safe `rel` attributes. Renders\n * {@link UITableEmpty} when `href` is absent.\n *\n * @example\n * import { UITablePermalink } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePermalink href=\"https://example.com/records/42\" label=\"View record\" />\n */\nexport const UITablePermalink: React.FC<{\n /** The destination URL the anchor navigates to; `null`/`undefined`/empty renders an empty state. */\n href: string | null | undefined;\n /** Optional display text; falls back to the raw `href` when omitted. */\n label?: string;\n}> = ({ href, label }) => {\n if (!href) return <UITableEmpty />;\n\n return (\n <a href={href} target=\"_blank\" className=\"inline-flex items-center gap-1 truncate text-primary text-sm underline\" rel=\"noopener noreferrer\">\n <span>{label || href}</span>\n <ExternalLinkIcon size={14} />\n </a>\n );\n};\n"],"mappings":"sGAcA,MAAa,GAKP,CAAE,OAAM,WACP,GAGH,EAAA,EAAA,KAAA,CAAC,IAAD,CAAS,OAAM,OAAO,SAAS,UAAU,yEAAyE,IAAI,sBAAtH,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,GAAS,CAAW,CAAA,GAC3B,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAkB,KAAM,EAAK,CAAA,CAC5B,KANa,EAAA,EAAA,IAAA,CAACD,EAAAA,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"permalink-azuGQg2b.cjs","names":["UITableEmpty","ExternalLinkIcon"],"sources":["../packages/components/features/tables/components/atoms/permalink.tsx"],"sourcesContent":["import { ExternalLinkIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders an external-link anchor with an icon for use in table cells, opening\n * the target URL in a new tab with safe `rel` attributes. Renders\n * {@link UITableEmpty} when `href` is absent.\n *\n * @example\n * import { UITablePermalink } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePermalink href=\"https://example.com/records/42\" label=\"View record\" />\n */\nexport const UITablePermalink: React.FC<{\n /** The destination URL the anchor navigates to; `null`/`undefined`/empty renders an empty state. */\n href: string | null | undefined;\n /** Optional display text; falls back to the raw `href` when omitted. */\n label?: string;\n}> = ({ href, label }) => {\n if (!href) return <UITableEmpty />;\n\n return (\n <a href={href} target=\"_blank\" className=\"inline-flex items-center gap-1 truncate text-primary text-sm underline\" rel=\"noopener noreferrer\">\n <span>{label || href}</span>\n <ExternalLinkIcon size={14} />\n </a>\n );\n};\n"],"mappings":"sGAcA,MAAa,GAKP,CAAE,OAAM,WACP,GAGH,EAAA,EAAA,KAAA,CAAC,IAAD,CAAS,OAAM,OAAO,SAAS,UAAU,yEAAyE,IAAI,sBAAtH,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,GAAS,CAAW,CAAA,GAC3B,EAAA,EAAA,IAAA,CAACC,EAAAA,iBAAD,CAAkB,KAAM,EAAK,CAAA,CAC5B,KANa,EAAA,EAAA,IAAA,CAACD,EAAAA,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- import{Tooltip as e,TooltipContent as t,TooltipTrigger as n}from"./ui/tooltip.mjs";import{Q as r}from"./tables-7_KgoyS-.mjs";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=({value:o})=>o?a(e,{children:[i(n,{asChild:!0,children:i(`p`,{className:`font-number text-text-positive text-sm tabular-nums`,children:o.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),i(t,{align:`start`,children:i(`p`,{className:`tabular-nums`,children:o.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`+84 $1 $2 $3`)})})]}):i(r,{});export{o as UITablePhoneNumberDisplay};
2
- //# sourceMappingURL=phone-number-ao2oCmrO.mjs.map
1
+ import{Tooltip as e,TooltipContent as t,TooltipTrigger as n}from"./ui/tooltip.mjs";import{Q as r}from"./tables-Dg3KMBKA.mjs";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=({value:o})=>o?a(e,{children:[i(n,{asChild:!0,children:i(`p`,{className:`font-number text-text-positive text-sm tabular-nums`,children:o.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),i(t,{align:`start`,children:i(`p`,{className:`tabular-nums`,children:o.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`+84 $1 $2 $3`)})})]}):i(r,{});export{o as UITablePhoneNumberDisplay};
2
+ //# sourceMappingURL=phone-number-Ba-f4s1Y.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"phone-number-ao2oCmrO.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/phone-number.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Formats and displays a phone number string in a table cell using the\n * `(NXX) NXX-XXXX` pattern, with a tooltip that shows the full international\n * dialling representation. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITablePhoneNumberDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePhoneNumberDisplay value=\"0843456789\" />\n */\nexport const UITablePhoneNumberDisplay: React.FC<{\n /** The raw phone number string to format and display; `null`/`undefined`/empty renders an empty state. */\n value: string | null | undefined;\n}> = ({ value }) => {\n if (!value) return <UITableEmpty />;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"font-number text-text-positive text-sm tabular-nums\">{value.replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3')}</p>\n </TooltipTrigger>\n <TooltipContent align=\"start\">\n <p className=\"tabular-nums\">{value.slice(1).replace(/(\\d{2})(\\d{3})(\\d{4})/, '+84 $1 $2 $3')}</p>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"+KAcA,MAAa,GAGP,CAAE,WACD,EAGH,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,IAAD,CAAG,UAAU,sDAAuD,SAAA,EAAM,QAAQ,wBAAyB,YAAY,CAAK,CAAA,CAC9G,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QACpB,SAAA,EAAC,IAAD,CAAG,UAAU,eAAgB,SAAA,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,wBAAyB,cAAc,CAAK,CAAA,CAClF,CAAA,CACT,CAAA,CAAA,EAVQ,EAAC,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"phone-number-Ba-f4s1Y.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/phone-number.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Formats and displays a phone number string in a table cell using the\n * `(NXX) NXX-XXXX` pattern, with a tooltip that shows the full international\n * dialling representation. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITablePhoneNumberDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePhoneNumberDisplay value=\"0843456789\" />\n */\nexport const UITablePhoneNumberDisplay: React.FC<{\n /** The raw phone number string to format and display; `null`/`undefined`/empty renders an empty state. */\n value: string | null | undefined;\n}> = ({ value }) => {\n if (!value) return <UITableEmpty />;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"font-number text-text-positive text-sm tabular-nums\">{value.replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3')}</p>\n </TooltipTrigger>\n <TooltipContent align=\"start\">\n <p className=\"tabular-nums\">{value.slice(1).replace(/(\\d{2})(\\d{3})(\\d{4})/, '+84 $1 $2 $3')}</p>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"+KAcA,MAAa,GAGP,CAAE,WACD,EAGH,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,IAAD,CAAG,UAAU,sDAAuD,SAAA,EAAM,QAAQ,wBAAyB,YAAY,CAAK,CAAA,CAC9G,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QACpB,SAAA,EAAC,IAAD,CAAG,UAAU,eAAgB,SAAA,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,wBAAyB,cAAc,CAAK,CAAA,CAClF,CAAA,CACT,CAAA,CAAA,EAVQ,EAAC,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require("./ui/tooltip.cjs"),t=require("./tables-CS3NhgTc.cjs");let n=require("react/jsx-runtime");const r=({value:r})=>r?(0,n.jsxs)(e.Tooltip,{children:[(0,n.jsx)(e.TooltipTrigger,{asChild:!0,children:(0,n.jsx)(`p`,{className:`font-number text-text-positive text-sm tabular-nums`,children:r.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),(0,n.jsx)(e.TooltipContent,{align:`start`,children:(0,n.jsx)(`p`,{className:`tabular-nums`,children:r.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`+84 $1 $2 $3`)})})]}):(0,n.jsx)(t.Q,{});exports.UITablePhoneNumberDisplay=r;
2
- //# sourceMappingURL=phone-number-F9I9sNLK.cjs.map
1
+ const e=require("./ui/tooltip.cjs"),t=require("./tables-BqZ4Zs6e.cjs");let n=require("react/jsx-runtime");const r=({value:r})=>r?(0,n.jsxs)(e.Tooltip,{children:[(0,n.jsx)(e.TooltipTrigger,{asChild:!0,children:(0,n.jsx)(`p`,{className:`font-number text-text-positive text-sm tabular-nums`,children:r.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),(0,n.jsx)(e.TooltipContent,{align:`start`,children:(0,n.jsx)(`p`,{className:`tabular-nums`,children:r.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`+84 $1 $2 $3`)})})]}):(0,n.jsx)(t.Q,{});exports.UITablePhoneNumberDisplay=r;
2
+ //# sourceMappingURL=phone-number-BqRhKQdr.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"phone-number-F9I9sNLK.cjs","names":["UITableEmpty","Tooltip","TooltipTrigger","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/phone-number.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Formats and displays a phone number string in a table cell using the\n * `(NXX) NXX-XXXX` pattern, with a tooltip that shows the full international\n * dialling representation. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITablePhoneNumberDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePhoneNumberDisplay value=\"0843456789\" />\n */\nexport const UITablePhoneNumberDisplay: React.FC<{\n /** The raw phone number string to format and display; `null`/`undefined`/empty renders an empty state. */\n value: string | null | undefined;\n}> = ({ value }) => {\n if (!value) return <UITableEmpty />;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"font-number text-text-positive text-sm tabular-nums\">{value.replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3')}</p>\n </TooltipTrigger>\n <TooltipContent align=\"start\">\n <p className=\"tabular-nums\">{value.slice(1).replace(/(\\d{2})(\\d{3})(\\d{4})/, '+84 $1 $2 $3')}</p>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"0GAcA,MAAa,GAGP,CAAE,WACD,GAGH,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GACd,UAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,sDAAuD,SAAA,EAAM,QAAQ,wBAAyB,YAAY,CAAK,CAAA,CAC9G,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,MAAM,QACpB,UAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,eAAgB,SAAA,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,wBAAyB,cAAc,CAAK,CAAA,CAClF,CAAA,CACT,CAAA,CAAA,GAVQ,EAAA,EAAA,IAAA,CAACH,EAAAA,EAAD,CAAe,CAAA"}
1
+ {"version":3,"file":"phone-number-BqRhKQdr.cjs","names":["UITableEmpty","Tooltip","TooltipTrigger","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/phone-number.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Formats and displays a phone number string in a table cell using the\n * `(NXX) NXX-XXXX` pattern, with a tooltip that shows the full international\n * dialling representation. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITablePhoneNumberDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITablePhoneNumberDisplay value=\"0843456789\" />\n */\nexport const UITablePhoneNumberDisplay: React.FC<{\n /** The raw phone number string to format and display; `null`/`undefined`/empty renders an empty state. */\n value: string | null | undefined;\n}> = ({ value }) => {\n if (!value) return <UITableEmpty />;\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <p className=\"font-number text-text-positive text-sm tabular-nums\">{value.replace(/(\\d{3})(\\d{3})(\\d{4})/, '($1) $2-$3')}</p>\n </TooltipTrigger>\n <TooltipContent align=\"start\">\n <p className=\"tabular-nums\">{value.slice(1).replace(/(\\d{2})(\\d{3})(\\d{4})/, '+84 $1 $2 $3')}</p>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"0GAcA,MAAa,GAGP,CAAE,WACD,GAGH,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GACd,UAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,sDAAuD,SAAA,EAAM,QAAQ,wBAAyB,YAAY,CAAK,CAAA,CAC9G,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,MAAM,QACpB,UAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,eAAgB,SAAA,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,wBAAyB,cAAc,CAAK,CAAA,CAClF,CAAA,CACT,CAAA,CAAA,GAVQ,EAAA,EAAA,IAAA,CAACH,EAAAA,EAAD,CAAe,CAAA"}
@@ -1,2 +1,2 @@
1
- import{Q as e}from"./tables-7_KgoyS-.mjs";import{Progress as t}from"./ui/progress.mjs";import{memo as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=n(({value:n,showLabel:o=!0,successThreshold:s=70,warningThreshold:c=40})=>{if(n==null)return i(e,{});let l=Math.min(100,Math.max(0,n));return a(`div`,{className:`flex w-full min-w-24 items-center gap-x-2`,children:[i(t,{value:l,className:r(`flex-1`,l>=s?`[&>[data-slot=progress-indicator]]:bg-success`:l>=c?`[&>[data-slot=progress-indicator]]:bg-warning`:`[&>[data-slot=progress-indicator]]:bg-danger`)}),o&&a(`span`,{className:`w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums`,children:[l,`%`]})]})});o.displayName=`UITableProgressDisplay`;export{o as UITableProgressDisplay};
2
- //# sourceMappingURL=progress-display-atwRFD6e.mjs.map
1
+ import{Q as e}from"./tables-Dg3KMBKA.mjs";import{Progress as t}from"./ui/progress.mjs";import{memo as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i,jsxs as a}from"react/jsx-runtime";const o=n(({value:n,showLabel:o=!0,successThreshold:s=70,warningThreshold:c=40})=>{if(n==null)return i(e,{});let l=Math.min(100,Math.max(0,n));return a(`div`,{className:`flex w-full min-w-24 items-center gap-x-2`,children:[i(t,{value:l,className:r(`flex-1`,l>=s?`[&>[data-slot=progress-indicator]]:bg-success`:l>=c?`[&>[data-slot=progress-indicator]]:bg-warning`:`[&>[data-slot=progress-indicator]]:bg-danger`)}),o&&a(`span`,{className:`w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums`,children:[l,`%`]})]})});o.displayName=`UITableProgressDisplay`;export{o as UITableProgressDisplay};
2
+ //# sourceMappingURL=progress-display-0UsBzt_r.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-display-atwRFD6e.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/progress-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Progress } from '@/components/ui/progress';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableProgressDisplay} component. */\ntype Props = {\n /** Percentage value between 0 and 100; `null`/`undefined` renders an empty state. */\n value: number | null | undefined;\n /** When `true`, shows the numeric percentage next to the bar (default: `true`). */\n showLabel?: boolean;\n /**\n * Color thresholds applied to the progress indicator.\n * - `≥ successThreshold` → green\n * - `≥ warningThreshold` → yellow\n * - otherwise → red\n *\n * Defaults: `successThreshold = 70`, `warningThreshold = 40`.\n */\n successThreshold?: number;\n warningThreshold?: number;\n};\n\n/**\n * Renders a horizontal progress bar with an optional percentage label for a\n * table cell. The bar color shifts from red → yellow → green based on\n * configurable thresholds. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITableProgressDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableProgressDisplay value={75} />\n */\nexport const UITableProgressDisplay = memo(({ value, showLabel = true, successThreshold = 70, warningThreshold = 40 }: Props) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n\n const clamped = Math.min(100, Math.max(0, value));\n\n const indicatorClass =\n clamped >= successThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-success'\n : clamped >= warningThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-warning'\n : '[&>[data-slot=progress-indicator]]:bg-danger';\n\n return (\n <div className=\"flex w-full min-w-24 items-center gap-x-2\">\n <Progress value={clamped} className={cn('flex-1', indicatorClass)} />\n {showLabel && <span className=\"w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums\">{clamped}%</span>}\n </div>\n );\n});\nUITableProgressDisplay.displayName = 'UITableProgressDisplay';\n"],"mappings":"0NAqCA,MAAa,EAAyB,GAAM,CAAE,QAAO,YAAY,GAAM,mBAAmB,GAAI,mBAAmB,MAAgB,CAC/H,GAAI,GAAU,KAA6B,OAAO,EAAC,EAAD,CAAe,CAAA,EAEjE,IAAM,EAAU,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,CAAK,CAAC,EAShD,OACE,EAAC,MAAD,CAAK,UAAU,4CAAf,SAAA,CACE,EAAC,EAAD,CAAU,MAAO,EAAS,UAAW,EAAG,SAR1C,GAAW,EACP,gDACA,GAAW,EACT,gDACA,8CAI4D,CAAI,CAAA,EACnE,GAAa,EAAC,OAAD,CAAM,UAAU,mFAAhB,SAAA,CAAoG,EAAQ,GAAO,CAC9H,CAAA,CAAA,GAET,CAAC,EACD,EAAuB,YAAc"}
1
+ {"version":3,"file":"progress-display-0UsBzt_r.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/progress-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Progress } from '@/components/ui/progress';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableProgressDisplay} component. */\ntype Props = {\n /** Percentage value between 0 and 100; `null`/`undefined` renders an empty state. */\n value: number | null | undefined;\n /** When `true`, shows the numeric percentage next to the bar (default: `true`). */\n showLabel?: boolean;\n /**\n * Color thresholds applied to the progress indicator.\n * - `≥ successThreshold` → green\n * - `≥ warningThreshold` → yellow\n * - otherwise → red\n *\n * Defaults: `successThreshold = 70`, `warningThreshold = 40`.\n */\n successThreshold?: number;\n warningThreshold?: number;\n};\n\n/**\n * Renders a horizontal progress bar with an optional percentage label for a\n * table cell. The bar color shifts from red → yellow → green based on\n * configurable thresholds. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITableProgressDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableProgressDisplay value={75} />\n */\nexport const UITableProgressDisplay = memo(({ value, showLabel = true, successThreshold = 70, warningThreshold = 40 }: Props) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n\n const clamped = Math.min(100, Math.max(0, value));\n\n const indicatorClass =\n clamped >= successThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-success'\n : clamped >= warningThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-warning'\n : '[&>[data-slot=progress-indicator]]:bg-danger';\n\n return (\n <div className=\"flex w-full min-w-24 items-center gap-x-2\">\n <Progress value={clamped} className={cn('flex-1', indicatorClass)} />\n {showLabel && <span className=\"w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums\">{clamped}%</span>}\n </div>\n );\n});\nUITableProgressDisplay.displayName = 'UITableProgressDisplay';\n"],"mappings":"0NAqCA,MAAa,EAAyB,GAAM,CAAE,QAAO,YAAY,GAAM,mBAAmB,GAAI,mBAAmB,MAAgB,CAC/H,GAAI,GAAU,KAA6B,OAAO,EAAC,EAAD,CAAe,CAAA,EAEjE,IAAM,EAAU,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,CAAK,CAAC,EAShD,OACE,EAAC,MAAD,CAAK,UAAU,4CAAf,SAAA,CACE,EAAC,EAAD,CAAU,MAAO,EAAS,UAAW,EAAG,SAR1C,GAAW,EACP,gDACA,GAAW,EACT,gDACA,8CAI4D,CAAI,CAAA,EACnE,GAAa,EAAC,OAAD,CAAM,UAAU,mFAAhB,SAAA,CAAoG,EAAQ,GAAO,CAC9H,CAAA,CAAA,GAET,CAAC,EACD,EAAuB,YAAc"}
@@ -1,2 +1,2 @@
1
- const e=require("./tables-CS3NhgTc.cjs"),t=require("./ui/progress.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a=(0,n.memo)(({value:n,showLabel:a=!0,successThreshold:o=70,warningThreshold:s=40})=>{if(n==null)return(0,i.jsx)(e.Q,{});let c=Math.min(100,Math.max(0,n));return(0,i.jsxs)(`div`,{className:`flex w-full min-w-24 items-center gap-x-2`,children:[(0,i.jsx)(t.Progress,{value:c,className:(0,r.cn)(`flex-1`,c>=o?`[&>[data-slot=progress-indicator]]:bg-success`:c>=s?`[&>[data-slot=progress-indicator]]:bg-warning`:`[&>[data-slot=progress-indicator]]:bg-danger`)}),a&&(0,i.jsxs)(`span`,{className:`w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums`,children:[c,`%`]})]})});a.displayName=`UITableProgressDisplay`,exports.UITableProgressDisplay=a;
2
- //# sourceMappingURL=progress-display-F8xXJ3T1.cjs.map
1
+ const e=require("./tables-BqZ4Zs6e.cjs"),t=require("./ui/progress.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a=(0,n.memo)(({value:n,showLabel:a=!0,successThreshold:o=70,warningThreshold:s=40})=>{if(n==null)return(0,i.jsx)(e.Q,{});let c=Math.min(100,Math.max(0,n));return(0,i.jsxs)(`div`,{className:`flex w-full min-w-24 items-center gap-x-2`,children:[(0,i.jsx)(t.Progress,{value:c,className:(0,r.cn)(`flex-1`,c>=o?`[&>[data-slot=progress-indicator]]:bg-success`:c>=s?`[&>[data-slot=progress-indicator]]:bg-warning`:`[&>[data-slot=progress-indicator]]:bg-danger`)}),a&&(0,i.jsxs)(`span`,{className:`w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums`,children:[c,`%`]})]})});a.displayName=`UITableProgressDisplay`,exports.UITableProgressDisplay=a;
2
+ //# sourceMappingURL=progress-display-CiYWPOnq.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"progress-display-F8xXJ3T1.cjs","names":["UITableEmpty","Progress"],"sources":["../packages/components/features/tables/components/atoms/progress-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Progress } from '@/components/ui/progress';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableProgressDisplay} component. */\ntype Props = {\n /** Percentage value between 0 and 100; `null`/`undefined` renders an empty state. */\n value: number | null | undefined;\n /** When `true`, shows the numeric percentage next to the bar (default: `true`). */\n showLabel?: boolean;\n /**\n * Color thresholds applied to the progress indicator.\n * - `≥ successThreshold` → green\n * - `≥ warningThreshold` → yellow\n * - otherwise → red\n *\n * Defaults: `successThreshold = 70`, `warningThreshold = 40`.\n */\n successThreshold?: number;\n warningThreshold?: number;\n};\n\n/**\n * Renders a horizontal progress bar with an optional percentage label for a\n * table cell. The bar color shifts from red → yellow → green based on\n * configurable thresholds. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITableProgressDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableProgressDisplay value={75} />\n */\nexport const UITableProgressDisplay = memo(({ value, showLabel = true, successThreshold = 70, warningThreshold = 40 }: Props) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n\n const clamped = Math.min(100, Math.max(0, value));\n\n const indicatorClass =\n clamped >= successThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-success'\n : clamped >= warningThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-warning'\n : '[&>[data-slot=progress-indicator]]:bg-danger';\n\n return (\n <div className=\"flex w-full min-w-24 items-center gap-x-2\">\n <Progress value={clamped} className={cn('flex-1', indicatorClass)} />\n {showLabel && <span className=\"w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums\">{clamped}%</span>}\n </div>\n );\n});\nUITableProgressDisplay.displayName = 'UITableProgressDisplay';\n"],"mappings":"0KAqCA,MAAa,GAAA,EAAA,EAAA,KAAA,EAA+B,CAAE,QAAO,YAAY,GAAM,mBAAmB,GAAI,mBAAmB,MAAgB,CAC/H,GAAI,GAAU,KAA6B,OAAO,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,EAEjE,IAAM,EAAU,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,CAAK,CAAC,EAShD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,4CAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,MAAO,EAAS,WAAA,EAAA,EAAA,GAAA,CAAc,SAR1C,GAAW,EACP,gDACA,GAAW,EACT,gDACA,8CAI4D,CAAI,CAAA,EACnE,IAAa,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,mFAAhB,SAAA,CAAoG,EAAQ,GAAO,CAC9H,CAAA,CAAA,GAET,CAAC,EACD,EAAuB,YAAc"}
1
+ {"version":3,"file":"progress-display-CiYWPOnq.cjs","names":["UITableEmpty","Progress"],"sources":["../packages/components/features/tables/components/atoms/progress-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Progress } from '@/components/ui/progress';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableProgressDisplay} component. */\ntype Props = {\n /** Percentage value between 0 and 100; `null`/`undefined` renders an empty state. */\n value: number | null | undefined;\n /** When `true`, shows the numeric percentage next to the bar (default: `true`). */\n showLabel?: boolean;\n /**\n * Color thresholds applied to the progress indicator.\n * - `≥ successThreshold` → green\n * - `≥ warningThreshold` → yellow\n * - otherwise → red\n *\n * Defaults: `successThreshold = 70`, `warningThreshold = 40`.\n */\n successThreshold?: number;\n warningThreshold?: number;\n};\n\n/**\n * Renders a horizontal progress bar with an optional percentage label for a\n * table cell. The bar color shifts from red → yellow → green based on\n * configurable thresholds. Renders {@link UITableEmpty} when `value` is absent.\n *\n * @example\n * import { UITableProgressDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableProgressDisplay value={75} />\n */\nexport const UITableProgressDisplay = memo(({ value, showLabel = true, successThreshold = 70, warningThreshold = 40 }: Props) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n\n const clamped = Math.min(100, Math.max(0, value));\n\n const indicatorClass =\n clamped >= successThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-success'\n : clamped >= warningThreshold\n ? '[&>[data-slot=progress-indicator]]:bg-warning'\n : '[&>[data-slot=progress-indicator]]:bg-danger';\n\n return (\n <div className=\"flex w-full min-w-24 items-center gap-x-2\">\n <Progress value={clamped} className={cn('flex-1', indicatorClass)} />\n {showLabel && <span className=\"w-9 shrink-0 text-right font-number text-text-positive-weak text-xs tabular-nums\">{clamped}%</span>}\n </div>\n );\n});\nUITableProgressDisplay.displayName = 'UITableProgressDisplay';\n"],"mappings":"0KAqCA,MAAa,GAAA,EAAA,EAAA,KAAA,EAA+B,CAAE,QAAO,YAAY,GAAM,mBAAmB,GAAI,mBAAmB,MAAgB,CAC/H,GAAI,GAAU,KAA6B,OAAO,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,EAEjE,IAAM,EAAU,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,CAAK,CAAC,EAShD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,4CAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,MAAO,EAAS,WAAA,EAAA,EAAA,GAAA,CAAc,SAR1C,GAAW,EACP,gDACA,GAAW,EACT,gDACA,8CAI4D,CAAI,CAAA,EACnE,IAAa,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,mFAAhB,SAAA,CAAoG,EAAQ,GAAO,CAC9H,CAAA,CAAA,GAET,CAAC,EACD,EAAuB,YAAc"}
@@ -35,7 +35,7 @@ declare const ResizablePanelGroup: import("react").NamedExoticComponent<Omit<imp
35
35
  children?: import("react").ReactNode | undefined;
36
36
  } & import("react").RefAttributes<ResizablePrimitive.ImperativePanelGroupHandle>>;
37
37
  /** An individual resizable panel within a ResizablePanelGroup. */
38
- declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("react").HTMLAttributes<HTMLInputElement | HTMLElement | HTMLParagraphElement | HTMLButtonElement | HTMLDivElement | HTMLFieldSetElement | HTMLLegendElement | HTMLLabelElement | HTMLObjectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLIElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
38
+ declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("react").HTMLAttributes<HTMLInputElement | HTMLElement | HTMLParagraphElement | HTMLDivElement | HTMLButtonElement | HTMLFieldSetElement | HTMLLegendElement | HTMLLabelElement | HTMLObjectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLIElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
39
39
  className?: string;
40
40
  collapsedSize?: number | undefined;
41
41
  collapsible?: boolean | undefined;
@@ -60,4 +60,4 @@ declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("
60
60
  declare const ResizableHandle: import("react").NamedExoticComponent<TResizableHandle>;
61
61
  //#endregion
62
62
  export { ResizablePanel as n, ResizablePanelGroup as r, ResizableHandle as t };
63
- //# sourceMappingURL=resizable-CWmitx5U.d.mts.map
63
+ //# sourceMappingURL=resizable-C3uADYIg.d.cts.map
@@ -35,7 +35,7 @@ declare const ResizablePanelGroup: import("react").NamedExoticComponent<Omit<imp
35
35
  children?: import("react").ReactNode | undefined;
36
36
  } & import("react").RefAttributes<ResizablePrimitive.ImperativePanelGroupHandle>>;
37
37
  /** An individual resizable panel within a ResizablePanelGroup. */
38
- declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("react").HTMLAttributes<HTMLInputElement | HTMLElement | HTMLParagraphElement | HTMLButtonElement | HTMLDivElement | HTMLFieldSetElement | HTMLLegendElement | HTMLLabelElement | HTMLObjectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLIElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
38
+ declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("react").HTMLAttributes<HTMLInputElement | HTMLElement | HTMLParagraphElement | HTMLDivElement | HTMLButtonElement | HTMLFieldSetElement | HTMLLegendElement | HTMLLabelElement | HTMLObjectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLIElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
39
39
  className?: string;
40
40
  collapsedSize?: number | undefined;
41
41
  collapsible?: boolean | undefined;
@@ -60,4 +60,4 @@ declare const ResizablePanel: import("react").NamedExoticComponent<Omit<import("
60
60
  declare const ResizableHandle: import("react").NamedExoticComponent<TResizableHandle>;
61
61
  //#endregion
62
62
  export { ResizablePanel as n, ResizablePanelGroup as r, ResizableHandle as t };
63
- //# sourceMappingURL=resizable-CWmitx5U.d.cts.map
63
+ //# sourceMappingURL=resizable-C3uADYIg.d.mts.map
@@ -0,0 +1,86 @@
1
+ //#region packages/components/dialogs/side-panel.d.ts
2
+ /**
3
+ * Props for the {@link SidePanel} component.
4
+ */
5
+ type SidePanelProps = {
6
+ /**
7
+ * Controls whether the panel is currently open.
8
+ * This is a **controlled** prop — pair it with `onOpenChange` to manage state.
9
+ */
10
+ open?: boolean;
11
+ /**
12
+ * Callback fired when the open state changes (e.g. backdrop click, close button, `Escape`).
13
+ *
14
+ * @param open - `true` when opening, `false` when closing.
15
+ */
16
+ onOpenChange?: (open: boolean) => void;
17
+ /** Heading rendered at the top of the panel. */
18
+ title?: React.ReactNode;
19
+ /** Supporting text rendered below the title. */
20
+ description?: React.ReactNode;
21
+ /** Content rendered pinned to the bottom of the panel, typically action buttons. */
22
+ footer?: React.ReactNode;
23
+ /**
24
+ * When `true` (default), renders a `CloseButton` in the top-right corner of the panel.
25
+ *
26
+ * @default true
27
+ */
28
+ showCloseButton?: boolean;
29
+ /** Main scrollable body content of the panel. */
30
+ children?: React.ReactNode;
31
+ /**
32
+ * Tailwind width classes applied to the panel from the `sm` breakpoint up (below `sm` the
33
+ * panel always fills the available inset area). Override to make the panel narrower, wider,
34
+ * or a fixed size, e.g. `'sm:w-96'` or `'sm:w-full sm:max-w-3xl'`.
35
+ *
36
+ * @default 'sm:w-1/2 sm:max-w-2xl'
37
+ */
38
+ width?: string;
39
+ /**
40
+ * When `false`, the panel becomes non-modal: no dimmed overlay is rendered, background content
41
+ * stays fully visible and interactive, and the panel can only be closed via its close button
42
+ * (`Escape` and outside clicks are disabled). `showCloseButton` is forced to `true` in this mode
43
+ * regardless of what's passed, since it becomes the only way to close the panel.
44
+ *
45
+ * @default true
46
+ */
47
+ modal?: boolean;
48
+ /** Additional class names applied to the panel itself. */
49
+ className?: string;
50
+ };
51
+ /**
52
+ * A controlled dialog panel anchored to the right half of the screen, inset from the viewport
53
+ * edges on both axes. Always lays out as a fixed header, a scrollable body, and a fixed footer.
54
+ *
55
+ * **Import:** `import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel'`
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * import { useState } from 'react';
60
+ * import { Button } from '@customafk/lunas-ui/ui/button';
61
+ * import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel';
62
+ *
63
+ * export function OrderDetailPanel({ order }: { order: Order }) {
64
+ * const [open, setOpen] = useState(false);
65
+ *
66
+ * return (
67
+ * <>
68
+ * <Button onClick={() => setOpen(true)}>Xem chi tiết</Button>
69
+ * <SidePanel
70
+ * open={open}
71
+ * onOpenChange={setOpen}
72
+ * title="Chi tiết đơn hàng"
73
+ * description="Xem và cập nhật thông tin đơn hàng."
74
+ * footer={<Button onClick={() => setOpen(false)}>Lưu thay đổi</Button>}
75
+ * >
76
+ * <p>Nội dung có thể cuộn ở đây.</p>
77
+ * </SidePanel>
78
+ * </>
79
+ * );
80
+ * }
81
+ * ```
82
+ */
83
+ declare const SidePanel: React.FC<SidePanelProps>;
84
+ //#endregion
85
+ export { SidePanelProps as n, SidePanel as t };
86
+ //# sourceMappingURL=side-panel-DPrM5ygG.d.cts.map
@@ -0,0 +1,86 @@
1
+ //#region packages/components/dialogs/side-panel.d.ts
2
+ /**
3
+ * Props for the {@link SidePanel} component.
4
+ */
5
+ type SidePanelProps = {
6
+ /**
7
+ * Controls whether the panel is currently open.
8
+ * This is a **controlled** prop — pair it with `onOpenChange` to manage state.
9
+ */
10
+ open?: boolean;
11
+ /**
12
+ * Callback fired when the open state changes (e.g. backdrop click, close button, `Escape`).
13
+ *
14
+ * @param open - `true` when opening, `false` when closing.
15
+ */
16
+ onOpenChange?: (open: boolean) => void;
17
+ /** Heading rendered at the top of the panel. */
18
+ title?: React.ReactNode;
19
+ /** Supporting text rendered below the title. */
20
+ description?: React.ReactNode;
21
+ /** Content rendered pinned to the bottom of the panel, typically action buttons. */
22
+ footer?: React.ReactNode;
23
+ /**
24
+ * When `true` (default), renders a `CloseButton` in the top-right corner of the panel.
25
+ *
26
+ * @default true
27
+ */
28
+ showCloseButton?: boolean;
29
+ /** Main scrollable body content of the panel. */
30
+ children?: React.ReactNode;
31
+ /**
32
+ * Tailwind width classes applied to the panel from the `sm` breakpoint up (below `sm` the
33
+ * panel always fills the available inset area). Override to make the panel narrower, wider,
34
+ * or a fixed size, e.g. `'sm:w-96'` or `'sm:w-full sm:max-w-3xl'`.
35
+ *
36
+ * @default 'sm:w-1/2 sm:max-w-2xl'
37
+ */
38
+ width?: string;
39
+ /**
40
+ * When `false`, the panel becomes non-modal: no dimmed overlay is rendered, background content
41
+ * stays fully visible and interactive, and the panel can only be closed via its close button
42
+ * (`Escape` and outside clicks are disabled). `showCloseButton` is forced to `true` in this mode
43
+ * regardless of what's passed, since it becomes the only way to close the panel.
44
+ *
45
+ * @default true
46
+ */
47
+ modal?: boolean;
48
+ /** Additional class names applied to the panel itself. */
49
+ className?: string;
50
+ };
51
+ /**
52
+ * A controlled dialog panel anchored to the right half of the screen, inset from the viewport
53
+ * edges on both axes. Always lays out as a fixed header, a scrollable body, and a fixed footer.
54
+ *
55
+ * **Import:** `import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel'`
56
+ *
57
+ * @example
58
+ * ```tsx
59
+ * import { useState } from 'react';
60
+ * import { Button } from '@customafk/lunas-ui/ui/button';
61
+ * import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel';
62
+ *
63
+ * export function OrderDetailPanel({ order }: { order: Order }) {
64
+ * const [open, setOpen] = useState(false);
65
+ *
66
+ * return (
67
+ * <>
68
+ * <Button onClick={() => setOpen(true)}>Xem chi tiết</Button>
69
+ * <SidePanel
70
+ * open={open}
71
+ * onOpenChange={setOpen}
72
+ * title="Chi tiết đơn hàng"
73
+ * description="Xem và cập nhật thông tin đơn hàng."
74
+ * footer={<Button onClick={() => setOpen(false)}>Lưu thay đổi</Button>}
75
+ * >
76
+ * <p>Nội dung có thể cuộn ở đây.</p>
77
+ * </SidePanel>
78
+ * </>
79
+ * );
80
+ * }
81
+ * ```
82
+ */
83
+ declare const SidePanel: React.FC<SidePanelProps>;
84
+ //#endregion
85
+ export { SidePanelProps as n, SidePanel as t };
86
+ //# sourceMappingURL=side-panel-DPrM5ygG.d.mts.map
@@ -0,0 +1,2 @@
1
+ import{Flex as e}from"./layouts/flex.mjs";import{Q as t}from"./tables-Dg3KMBKA.mjs";import{memo as n,useCallback as r,useMemo as i}from"react";import{cn as a}from"@customafk/react-toolkit/utils";import{jsx as o,jsxs as s}from"react/jsx-runtime";const c=(e,t,n)=>{let r=10**t;switch(n){case`floor`:return Math.floor(e*r)/r;case`ceil`:return Math.ceil(e*r)/r;default:return Math.round(e*r)/r}},l=n(({decimalSeparator:n=`.`,groupSeparator:l=`,`,prefix:u,suffix:d,precision:f,roundingMode:p=`round`,showTrailingZeros:m=!1,size:h=`lg`,value:g=0,colorize:_=!1,trend:v})=>{let y=i(()=>{let e={};return typeof f==`number`&&f>=0&&m&&(e.minimumFractionDigits=f),e.maximumFractionDigits=f,e},[f,m]),b=r(e=>{let t=e;return typeof f==`number`&&f>=0&&(t=c(e,f,p)),t.toLocaleString(`vi-VN`,y)},[p,y,f]),x=i(()=>{if(typeof g==`number`)return Number.isNaN(g)||!Number.isFinite(g)?`N/A`:b(g);if(typeof g==`string`){let e=g.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:b(t)}return`N/A`},[g,b]),S=i(()=>n===`.`&&l===`,`?x:x.replace(/,/g,l).replace(/\./g,n),[x,n,l]),C=i(()=>{if(v)return v;if(!_)return;let e=typeof g==`string`?Number(g.trim()):g;if(!(typeof e!=`number`||Number.isNaN(e)))return e<0?`down`:e>0?`up`:`neutral`},[v,_,g]);return S===`0`||S===`N/A`||!S?o(t,{}):s(e,{padding:`none`,className:a(`font-number tabular-nums`,h===`xs`&&`text-xs`,h===`sm`&&`text-sm`,h===`md`&&`text-base`,h===`lg`&&`text-lg`,h===`xl`&&`text-xl`,!C&&`text-text-positive`,C===`down`&&`text-danger`,C===`up`&&`text-success`,C===`neutral`&&`text-text-positive-strong`),children:[u,o(`p`,{children:S}),d]})});l.displayName=`UITableStatisticDisplay`;export{l as UITableStatisticDisplay};
2
+ //# sourceMappingURL=statistic-639yMA2d.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistic-639yMA2d.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/statistic.tsx"],"sourcesContent":["'use client';\nimport { memo, useCallback, useMemo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Flex } from '@/components/layouts/flex';\nimport { UITableEmpty } from './empty';\n\n/**\n * Applies the specified rounding mode to `num` at the given decimal precision.\n *\n * @param num - The number to round.\n * @param precisionValue - Number of decimal places to keep.\n * @param roundingMode - Rounding strategy: `'round'` (default), `'floor'`, or `'ceil'`.\n * @returns The rounded number.\n */\nconst applyRounding = (num: number, precisionValue: number, roundingMode?: 'round' | 'floor' | 'ceil') => {\n const multiplier = 10 ** precisionValue;\n\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n};\n\n/** Props for the {@link UITableStatisticDisplay} component. */\ntype Props = {\n /** Character used to separate the integer and fractional parts (default: `'.'`). */\n decimalSeparator?: string;\n /** Character used to separate thousands groups (default: `','`). */\n groupSeparator?: string;\n /** Optional node rendered before the formatted number (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the formatted number (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display. */\n precision?: number;\n /** Rounding strategy applied before formatting (default: `'round'`). */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the fractional part with trailing zeros up to `precision` digits. */\n showTrailingZeros?: boolean;\n /** Font-size variant for the displayed number (default: `'lg'`). */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** The numeric or string value to format; falsy / invalid values render an empty state. */\n value: number | string | null | undefined;\n /** When `true` and `trend` is not set, auto-derives color from the value's sign (negative → red, positive → green, zero → neutral). */\n colorize?: boolean;\n /**\n * Explicit color override, independent of the value's numeric sign — e.g. a large\n * positive figure can still be marked `'down'` (red) to flag it as significant.\n * Takes precedence over `colorize`'s sign-based auto-detection.\n */\n trend?: 'up' | 'down' | 'neutral';\n};\n\n/**\n * A memoized table-cell component that formats a numeric value with configurable\n * separators, precision, rounding, and size; renders {@link UITableEmpty} when\n * the value is zero, invalid, or absent.\n *\n * @example\n * import { UITableStatisticDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatisticDisplay value={1234567.89} precision={2} prefix=\"$\" size=\"md\" />\n * <UITableStatisticDisplay value={1234567.89} precision={2} prefix=\"$\" trend=\"down\" />\n */\nexport const UITableStatisticDisplay = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n value = 0,\n colorize = false,\n trend,\n }: Props) => {\n // Memoize number formatting options\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n\n if (typeof precision === 'number' && precision >= 0 && showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n\n // Áp dụng làm tròn nếu có precision\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision, roundingMode);\n }\n\n return processedNum.toLocaleString('vi-VN', formatOptions);\n },\n [roundingMode, formatOptions, precision]\n );\n\n // Memoize value processing\n const processedValue = useMemo((): string => {\n // Xử lý giá trị number\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) {\n return 'N/A';\n }\n return formatNumber(value);\n }\n\n // Xử lý giá trị string\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n\n // Nếu là chuỗi rỗng\n if (!trimmedValue) {\n return 'N/A';\n }\n\n // Thử convert sang number\n const numValue = Number(trimmedValue);\n\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) {\n // Nếu không phải số, trả về string gốc\n return 'N/A';\n }\n\n return formatNumber(numValue);\n }\n\n return 'N/A';\n }, [value, formatNumber]);\n\n // Memoize separator replacement\n const finalFormattedValue = useMemo((): string => {\n // Chỉ thay thế separators nếu khác mặc định\n if (decimalSeparator === '.' && groupSeparator === ',') {\n return processedValue;\n }\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n const effectiveTrend = useMemo(() => {\n if (trend) return trend;\n if (!colorize) return undefined;\n\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n if (typeof num !== 'number' || Number.isNaN(num)) return undefined;\n if (num < 0) return 'down';\n if (num > 0) return 'up';\n return 'neutral';\n }, [trend, colorize, value]);\n\n if (finalFormattedValue === '0' || finalFormattedValue === 'N/A' || !finalFormattedValue) {\n return <UITableEmpty />;\n }\n\n return (\n <Flex\n padding=\"none\"\n className={cn(\n 'font-number tabular-nums',\n size === 'xs' && 'text-xs',\n size === 'sm' && 'text-sm',\n size === 'md' && 'text-base',\n size === 'lg' && 'text-lg',\n size === 'xl' && 'text-xl',\n !effectiveTrend && 'text-text-positive',\n effectiveTrend === 'down' && 'text-danger',\n effectiveTrend === 'up' && 'text-success',\n effectiveTrend === 'neutral' && 'text-text-positive-strong'\n )}\n >\n {Prefix}\n <p>{finalFormattedValue}</p>\n {Suffix}\n </Flex>\n );\n }\n);\nUITableStatisticDisplay.displayName = 'UITableStatisticDisplay';\n"],"mappings":"qPAgBA,MAAM,GAAiB,EAAa,EAAwB,IAA8C,CACxG,IAAM,EAAa,IAAM,EAEzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EA2Ca,EAA0B,GACpC,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,EACR,WAAW,GACX,WACW,CAEX,IAAM,EAAgB,MAAwC,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OAPI,OAAO,GAAc,UAAY,GAAa,GAAK,IACrD,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,EAG3B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,EAAe,EAClB,GAAwB,CACvB,IAAI,EAAe,EAOnB,OAJI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,EAAW,CAAY,GAGpD,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAc,EAAe,CAAS,CACzC,EAGM,EAAiB,MAAsB,CAE3C,GAAI,OAAO,GAAU,SAInB,OAHI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EACxC,MAEF,EAAa,CAAK,EAI3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAGhC,GAAI,CAAC,EACH,MAAO,MAIT,IAAM,EAAW,OAAO,CAAY,EAOpC,OALI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAE9C,MAGF,EAAa,CAAQ,CAC9B,CAEA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAGlB,EAAsB,MAEtB,IAAqB,KAAO,IAAmB,IAC1C,EAEF,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAE/C,EAAiB,MAAc,CACnC,GAAI,EAAO,OAAO,EAClB,GAAI,CAAC,EAAU,OAEf,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC3D,YAAO,GAAQ,UAAY,OAAO,MAAM,CAAG,GAG/C,OAFI,EAAM,EAAU,OAChB,EAAM,EAAU,KACb,SACT,EAAG,CAAC,EAAO,EAAU,CAAK,CAAC,EAM3B,OAJI,IAAwB,KAAO,IAAwB,OAAS,CAAC,EAC5D,EAAC,EAAD,CAAe,CAAA,EAItB,EAAC,EAAD,CACE,QAAQ,OACR,UAAW,EACT,2BACA,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,YACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,CAAC,GAAkB,qBACnB,IAAmB,QAAU,cAC7B,IAAmB,MAAQ,eAC3B,IAAmB,WAAa,2BAClC,EAbF,SAAA,CAeG,EACD,EAAC,IAAD,CAAA,SAAI,CAAuB,CAAA,EAC1B,CACG,GAEV,CACF,EACA,EAAwB,YAAc"}
@@ -0,0 +1,2 @@
1
+ const e=require("./layouts/flex.cjs"),t=require("./tables-BqZ4Zs6e.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a=(e,t,n)=>{let r=10**t;switch(n){case`floor`:return Math.floor(e*r)/r;case`ceil`:return Math.ceil(e*r)/r;default:return Math.round(e*r)/r}},o=(0,n.memo)(({decimalSeparator:o=`.`,groupSeparator:s=`,`,prefix:c,suffix:l,precision:u,roundingMode:d=`round`,showTrailingZeros:f=!1,size:p=`lg`,value:m=0,colorize:h=!1,trend:g})=>{let _=(0,n.useMemo)(()=>{let e={};return typeof u==`number`&&u>=0&&f&&(e.minimumFractionDigits=u),e.maximumFractionDigits=u,e},[u,f]),v=(0,n.useCallback)(e=>{let t=e;return typeof u==`number`&&u>=0&&(t=a(e,u,d)),t.toLocaleString(`vi-VN`,_)},[d,_,u]),y=(0,n.useMemo)(()=>{if(typeof m==`number`)return Number.isNaN(m)||!Number.isFinite(m)?`N/A`:v(m);if(typeof m==`string`){let e=m.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:v(t)}return`N/A`},[m,v]),b=(0,n.useMemo)(()=>o===`.`&&s===`,`?y:y.replace(/,/g,s).replace(/\./g,o),[y,o,s]),x=(0,n.useMemo)(()=>{if(g)return g;if(!h)return;let e=typeof m==`string`?Number(m.trim()):m;if(!(typeof e!=`number`||Number.isNaN(e)))return e<0?`down`:e>0?`up`:`neutral`},[g,h,m]);return b===`0`||b===`N/A`||!b?(0,i.jsx)(t.Q,{}):(0,i.jsxs)(e.Flex,{padding:`none`,className:(0,r.cn)(`font-number tabular-nums`,p===`xs`&&`text-xs`,p===`sm`&&`text-sm`,p===`md`&&`text-base`,p===`lg`&&`text-lg`,p===`xl`&&`text-xl`,!x&&`text-text-positive`,x===`down`&&`text-danger`,x===`up`&&`text-success`,x===`neutral`&&`text-text-positive-strong`),children:[c,(0,i.jsx)(`p`,{children:b}),l]})});o.displayName=`UITableStatisticDisplay`,exports.UITableStatisticDisplay=o;
2
+ //# sourceMappingURL=statistic-CE_Jg8SN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statistic-CE_Jg8SN.cjs","names":["UITableEmpty","Flex"],"sources":["../packages/components/features/tables/components/atoms/statistic.tsx"],"sourcesContent":["'use client';\nimport { memo, useCallback, useMemo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Flex } from '@/components/layouts/flex';\nimport { UITableEmpty } from './empty';\n\n/**\n * Applies the specified rounding mode to `num` at the given decimal precision.\n *\n * @param num - The number to round.\n * @param precisionValue - Number of decimal places to keep.\n * @param roundingMode - Rounding strategy: `'round'` (default), `'floor'`, or `'ceil'`.\n * @returns The rounded number.\n */\nconst applyRounding = (num: number, precisionValue: number, roundingMode?: 'round' | 'floor' | 'ceil') => {\n const multiplier = 10 ** precisionValue;\n\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n};\n\n/** Props for the {@link UITableStatisticDisplay} component. */\ntype Props = {\n /** Character used to separate the integer and fractional parts (default: `'.'`). */\n decimalSeparator?: string;\n /** Character used to separate thousands groups (default: `','`). */\n groupSeparator?: string;\n /** Optional node rendered before the formatted number (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the formatted number (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display. */\n precision?: number;\n /** Rounding strategy applied before formatting (default: `'round'`). */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the fractional part with trailing zeros up to `precision` digits. */\n showTrailingZeros?: boolean;\n /** Font-size variant for the displayed number (default: `'lg'`). */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n /** The numeric or string value to format; falsy / invalid values render an empty state. */\n value: number | string | null | undefined;\n /** When `true` and `trend` is not set, auto-derives color from the value's sign (negative → red, positive → green, zero → neutral). */\n colorize?: boolean;\n /**\n * Explicit color override, independent of the value's numeric sign — e.g. a large\n * positive figure can still be marked `'down'` (red) to flag it as significant.\n * Takes precedence over `colorize`'s sign-based auto-detection.\n */\n trend?: 'up' | 'down' | 'neutral';\n};\n\n/**\n * A memoized table-cell component that formats a numeric value with configurable\n * separators, precision, rounding, and size; renders {@link UITableEmpty} when\n * the value is zero, invalid, or absent.\n *\n * @example\n * import { UITableStatisticDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatisticDisplay value={1234567.89} precision={2} prefix=\"$\" size=\"md\" />\n * <UITableStatisticDisplay value={1234567.89} precision={2} prefix=\"$\" trend=\"down\" />\n */\nexport const UITableStatisticDisplay = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n value = 0,\n colorize = false,\n trend,\n }: Props) => {\n // Memoize number formatting options\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n\n if (typeof precision === 'number' && precision >= 0 && showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n\n // Áp dụng làm tròn nếu có precision\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision, roundingMode);\n }\n\n return processedNum.toLocaleString('vi-VN', formatOptions);\n },\n [roundingMode, formatOptions, precision]\n );\n\n // Memoize value processing\n const processedValue = useMemo((): string => {\n // Xử lý giá trị number\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) {\n return 'N/A';\n }\n return formatNumber(value);\n }\n\n // Xử lý giá trị string\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n\n // Nếu là chuỗi rỗng\n if (!trimmedValue) {\n return 'N/A';\n }\n\n // Thử convert sang number\n const numValue = Number(trimmedValue);\n\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) {\n // Nếu không phải số, trả về string gốc\n return 'N/A';\n }\n\n return formatNumber(numValue);\n }\n\n return 'N/A';\n }, [value, formatNumber]);\n\n // Memoize separator replacement\n const finalFormattedValue = useMemo((): string => {\n // Chỉ thay thế separators nếu khác mặc định\n if (decimalSeparator === '.' && groupSeparator === ',') {\n return processedValue;\n }\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n const effectiveTrend = useMemo(() => {\n if (trend) return trend;\n if (!colorize) return undefined;\n\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n if (typeof num !== 'number' || Number.isNaN(num)) return undefined;\n if (num < 0) return 'down';\n if (num > 0) return 'up';\n return 'neutral';\n }, [trend, colorize, value]);\n\n if (finalFormattedValue === '0' || finalFormattedValue === 'N/A' || !finalFormattedValue) {\n return <UITableEmpty />;\n }\n\n return (\n <Flex\n padding=\"none\"\n className={cn(\n 'font-number tabular-nums',\n size === 'xs' && 'text-xs',\n size === 'sm' && 'text-sm',\n size === 'md' && 'text-base',\n size === 'lg' && 'text-lg',\n size === 'xl' && 'text-xl',\n !effectiveTrend && 'text-text-positive',\n effectiveTrend === 'down' && 'text-danger',\n effectiveTrend === 'up' && 'text-success',\n effectiveTrend === 'neutral' && 'text-text-positive-strong'\n )}\n >\n {Prefix}\n <p>{finalFormattedValue}</p>\n {Suffix}\n </Flex>\n );\n }\n);\nUITableStatisticDisplay.displayName = 'UITableStatisticDisplay';\n"],"mappings":"2KAgBA,MAAM,GAAiB,EAAa,EAAwB,IAA8C,CACxG,IAAM,EAAa,IAAM,EAEzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EA2Ca,GAAA,EAAA,EAAA,KAAA,EACV,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,EACR,WAAW,GACX,WACW,CAEX,IAAM,GAAA,EAAA,EAAA,QAAA,KAAwD,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OAPI,OAAO,GAAc,UAAY,GAAa,GAAK,IACrD,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,EAG3B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,GAAA,EAAA,EAAA,YAAA,CACH,GAAwB,CACvB,IAAI,EAAe,EAOnB,OAJI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,EAAW,CAAY,GAGpD,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAc,EAAe,CAAS,CACzC,EAGM,GAAA,EAAA,EAAA,QAAA,KAAuC,CAE3C,GAAI,OAAO,GAAU,SAInB,OAHI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EACxC,MAEF,EAAa,CAAK,EAI3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAGhC,GAAI,CAAC,EACH,MAAO,MAIT,IAAM,EAAW,OAAO,CAAY,EAOpC,OALI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAE9C,MAGF,EAAa,CAAQ,CAC9B,CAEA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAGlB,GAAA,EAAA,EAAA,QAAA,KAEA,IAAqB,KAAO,IAAmB,IAC1C,EAEF,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAE/C,GAAA,EAAA,EAAA,QAAA,KAA+B,CACnC,GAAI,EAAO,OAAO,EAClB,GAAI,CAAC,EAAU,OAEf,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC3D,YAAO,GAAQ,UAAY,OAAO,MAAM,CAAG,GAG/C,OAFI,EAAM,EAAU,OAChB,EAAM,EAAU,KACb,SACT,EAAG,CAAC,EAAO,EAAU,CAAK,CAAC,EAM3B,OAJI,IAAwB,KAAO,IAAwB,OAAS,CAAC,GAC5D,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,GAItB,EAAA,EAAA,KAAA,CAACC,EAAAA,KAAD,CACE,QAAQ,OACR,WAAA,EAAA,EAAA,GAAA,CACE,2BACA,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,YACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,CAAC,GAAkB,qBACnB,IAAmB,QAAU,cAC7B,IAAmB,MAAQ,eAC3B,IAAmB,WAAa,2BAClC,EAbF,SAAA,CAeG,GACD,EAAA,EAAA,IAAA,CAAC,IAAD,CAAA,SAAI,CAAuB,CAAA,EAC1B,CACG,GAEV,CACF,EACA,EAAwB,YAAc"}
@@ -1,2 +1,2 @@
1
- import{Badge as e}from"./ui/badge.mjs";import{Q as t}from"./tables-7_KgoyS-.mjs";import{jsx as n}from"react/jsx-runtime";const r=({value:r,colorMap:i,defaultColor:a=`muted`,variant:o=`soft`})=>r==null||r===``?n(t,{}):n(e,{variant:o,color:(i&&i[r])??a,size:`sm`,className:`min-w-16 justify-center capitalize`,children:r.charAt(0).toUpperCase()+r.slice(1).replace(/_/g,` `)});export{r as UITableStatusDisplay};
2
- //# sourceMappingURL=status-display-DInGGgiP.mjs.map
1
+ import{Badge as e}from"./ui/badge.mjs";import{Q as t}from"./tables-Dg3KMBKA.mjs";import{jsx as n}from"react/jsx-runtime";const r=({value:r,colorMap:i,defaultColor:a=`muted`,variant:o=`soft`})=>r==null||r===``?n(t,{}):n(e,{variant:o,color:(i&&i[r])??a,size:`sm`,className:`min-w-16 justify-center capitalize`,children:r.charAt(0).toUpperCase()+r.slice(1).replace(/_/g,` `)});export{r as UITableStatusDisplay};
2
+ //# sourceMappingURL=status-display-BCYpNJmd.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-display-DInGGgiP.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/status-display.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@/components/ui/badge';\nimport { UITableEmpty } from './empty';\n\ntype BadgeColor = 'primary' | 'secondary' | 'muted' | 'accent' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Props for the {@link UITableStatusDisplay} component. */\ntype Props = {\n /** The status string to display; `null`/`undefined` renders an empty state. */\n value: string | null | undefined;\n /**\n * Maps each status string to a badge color. Any key not present in the map\n * falls back to `defaultColor`.\n */\n colorMap?: Record<string, BadgeColor>;\n /** Color used when `value` is not found in `colorMap` (default: `'muted'`). */\n defaultColor?: BadgeColor;\n /** Badge variant forwarded to the underlying {@link Badge} (default: `'soft'`). */\n variant?: 'solid' | 'soft' | 'outline';\n};\n\n/**\n * Renders a color-coded status badge for a table cell. The mapping from status\n * string to badge color is fully configurable via `colorMap`; unknown statuses\n * fall back to `defaultColor`.\n *\n * @example\n * import { UITableStatusDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatusDisplay\n * value=\"active\"\n * colorMap={{ active: 'success', inactive: 'danger', pending: 'warning' }}\n * />\n */\nexport const UITableStatusDisplay: React.FC<Props> = ({ value, colorMap, defaultColor = 'muted', variant = 'soft' }) => {\n if (value === null || value === undefined || value === '') return <UITableEmpty />;\n\n const color: BadgeColor = (colorMap && colorMap[value]) ?? defaultColor;\n const label = value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n\n return (\n <Badge variant={variant} color={color} size=\"sm\" className=\"min-w-16 justify-center capitalize\">\n {label}\n </Badge>\n );\n};\n"],"mappings":"yHAmCA,MAAa,GAAyC,CAAE,QAAO,WAAU,eAAe,QAAS,UAAU,UACrG,GAAU,MAA+B,IAAU,GAAW,EAAC,EAAD,CAAe,CAAA,EAM/E,EAAC,EAAD,CAAgB,UAAS,OAJA,GAAY,EAAS,KAAW,EAIlB,KAAK,KAAK,UAAU,qCAH/C,SAAA,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAM,GAAG,CAKrE,CAAA"}
1
+ {"version":3,"file":"status-display-BCYpNJmd.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/status-display.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@/components/ui/badge';\nimport { UITableEmpty } from './empty';\n\ntype BadgeColor = 'primary' | 'secondary' | 'muted' | 'accent' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Props for the {@link UITableStatusDisplay} component. */\ntype Props = {\n /** The status string to display; `null`/`undefined` renders an empty state. */\n value: string | null | undefined;\n /**\n * Maps each status string to a badge color. Any key not present in the map\n * falls back to `defaultColor`.\n */\n colorMap?: Record<string, BadgeColor>;\n /** Color used when `value` is not found in `colorMap` (default: `'muted'`). */\n defaultColor?: BadgeColor;\n /** Badge variant forwarded to the underlying {@link Badge} (default: `'soft'`). */\n variant?: 'solid' | 'soft' | 'outline';\n};\n\n/**\n * Renders a color-coded status badge for a table cell. The mapping from status\n * string to badge color is fully configurable via `colorMap`; unknown statuses\n * fall back to `defaultColor`.\n *\n * @example\n * import { UITableStatusDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatusDisplay\n * value=\"active\"\n * colorMap={{ active: 'success', inactive: 'danger', pending: 'warning' }}\n * />\n */\nexport const UITableStatusDisplay: React.FC<Props> = ({ value, colorMap, defaultColor = 'muted', variant = 'soft' }) => {\n if (value === null || value === undefined || value === '') return <UITableEmpty />;\n\n const color: BadgeColor = (colorMap && colorMap[value]) ?? defaultColor;\n const label = value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n\n return (\n <Badge variant={variant} color={color} size=\"sm\" className=\"min-w-16 justify-center capitalize\">\n {label}\n </Badge>\n );\n};\n"],"mappings":"yHAmCA,MAAa,GAAyC,CAAE,QAAO,WAAU,eAAe,QAAS,UAAU,UACrG,GAAU,MAA+B,IAAU,GAAW,EAAC,EAAD,CAAe,CAAA,EAM/E,EAAC,EAAD,CAAgB,UAAS,OAJA,GAAY,EAAS,KAAW,EAIlB,KAAK,KAAK,UAAU,qCAH/C,SAAA,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAM,GAAG,CAKrE,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require("./ui/badge.cjs"),t=require("./tables-CS3NhgTc.cjs");let n=require("react/jsx-runtime");const r=({value:r,colorMap:i,defaultColor:a=`muted`,variant:o=`soft`})=>r==null||r===``?(0,n.jsx)(t.Q,{}):(0,n.jsx)(e.Badge,{variant:o,color:(i&&i[r])??a,size:`sm`,className:`min-w-16 justify-center capitalize`,children:r.charAt(0).toUpperCase()+r.slice(1).replace(/_/g,` `)});exports.UITableStatusDisplay=r;
2
- //# sourceMappingURL=status-display-DpKsYvZJ.cjs.map
1
+ const e=require("./ui/badge.cjs"),t=require("./tables-BqZ4Zs6e.cjs");let n=require("react/jsx-runtime");const r=({value:r,colorMap:i,defaultColor:a=`muted`,variant:o=`soft`})=>r==null||r===``?(0,n.jsx)(t.Q,{}):(0,n.jsx)(e.Badge,{variant:o,color:(i&&i[r])??a,size:`sm`,className:`min-w-16 justify-center capitalize`,children:r.charAt(0).toUpperCase()+r.slice(1).replace(/_/g,` `)});exports.UITableStatusDisplay=r;
2
+ //# sourceMappingURL=status-display-xcCCGpGS.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-display-DpKsYvZJ.cjs","names":["UITableEmpty","Badge"],"sources":["../packages/components/features/tables/components/atoms/status-display.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@/components/ui/badge';\nimport { UITableEmpty } from './empty';\n\ntype BadgeColor = 'primary' | 'secondary' | 'muted' | 'accent' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Props for the {@link UITableStatusDisplay} component. */\ntype Props = {\n /** The status string to display; `null`/`undefined` renders an empty state. */\n value: string | null | undefined;\n /**\n * Maps each status string to a badge color. Any key not present in the map\n * falls back to `defaultColor`.\n */\n colorMap?: Record<string, BadgeColor>;\n /** Color used when `value` is not found in `colorMap` (default: `'muted'`). */\n defaultColor?: BadgeColor;\n /** Badge variant forwarded to the underlying {@link Badge} (default: `'soft'`). */\n variant?: 'solid' | 'soft' | 'outline';\n};\n\n/**\n * Renders a color-coded status badge for a table cell. The mapping from status\n * string to badge color is fully configurable via `colorMap`; unknown statuses\n * fall back to `defaultColor`.\n *\n * @example\n * import { UITableStatusDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatusDisplay\n * value=\"active\"\n * colorMap={{ active: 'success', inactive: 'danger', pending: 'warning' }}\n * />\n */\nexport const UITableStatusDisplay: React.FC<Props> = ({ value, colorMap, defaultColor = 'muted', variant = 'soft' }) => {\n if (value === null || value === undefined || value === '') return <UITableEmpty />;\n\n const color: BadgeColor = (colorMap && colorMap[value]) ?? defaultColor;\n const label = value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n\n return (\n <Badge variant={variant} color={color} size=\"sm\" className=\"min-w-16 justify-center capitalize\">\n {label}\n </Badge>\n );\n};\n"],"mappings":"wGAmCA,MAAa,GAAyC,CAAE,QAAO,WAAU,eAAe,QAAS,UAAU,UACrG,GAAU,MAA+B,IAAU,IAAW,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,GAM/E,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAgB,UAAS,OAJA,GAAY,EAAS,KAAW,EAIlB,KAAK,KAAK,UAAU,qCAH/C,SAAA,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAM,GAAG,CAKrE,CAAA"}
1
+ {"version":3,"file":"status-display-xcCCGpGS.cjs","names":["UITableEmpty","Badge"],"sources":["../packages/components/features/tables/components/atoms/status-display.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@/components/ui/badge';\nimport { UITableEmpty } from './empty';\n\ntype BadgeColor = 'primary' | 'secondary' | 'muted' | 'accent' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Props for the {@link UITableStatusDisplay} component. */\ntype Props = {\n /** The status string to display; `null`/`undefined` renders an empty state. */\n value: string | null | undefined;\n /**\n * Maps each status string to a badge color. Any key not present in the map\n * falls back to `defaultColor`.\n */\n colorMap?: Record<string, BadgeColor>;\n /** Color used when `value` is not found in `colorMap` (default: `'muted'`). */\n defaultColor?: BadgeColor;\n /** Badge variant forwarded to the underlying {@link Badge} (default: `'soft'`). */\n variant?: 'solid' | 'soft' | 'outline';\n};\n\n/**\n * Renders a color-coded status badge for a table cell. The mapping from status\n * string to badge color is fully configurable via `colorMap`; unknown statuses\n * fall back to `defaultColor`.\n *\n * @example\n * import { UITableStatusDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableStatusDisplay\n * value=\"active\"\n * colorMap={{ active: 'success', inactive: 'danger', pending: 'warning' }}\n * />\n */\nexport const UITableStatusDisplay: React.FC<Props> = ({ value, colorMap, defaultColor = 'muted', variant = 'soft' }) => {\n if (value === null || value === undefined || value === '') return <UITableEmpty />;\n\n const color: BadgeColor = (colorMap && colorMap[value]) ?? defaultColor;\n const label = value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n\n return (\n <Badge variant={variant} color={color} size=\"sm\" className=\"min-w-16 justify-center capitalize\">\n {label}\n </Badge>\n );\n};\n"],"mappings":"wGAmCA,MAAa,GAAyC,CAAE,QAAO,WAAU,eAAe,QAAS,UAAU,UACrG,GAAU,MAA+B,IAAU,IAAW,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,GAM/E,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAgB,UAAS,OAJA,GAAY,EAAS,KAAW,EAIlB,KAAK,KAAK,UAAU,qCAH/C,SAAA,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAM,MAAM,CAAC,CAAC,CAAC,QAAQ,KAAM,GAAG,CAKrE,CAAA"}
@@ -1,2 +1,2 @@
1
- const e=require("./data-display/statistic.cjs"),t=require("./tables-CS3NhgTc.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a={up:`bg-success`,down:`bg-danger`,neutral:`bg-primary`},o=(0,n.memo)(()=>{let{summary:n,onSummaryItemClick:o}=t.Y(),{isOpen:s}=t.Z();return!s||!n||n.length===0?null:(0,i.jsx)(`div`,{"data-slot":`table-summary-bar`,className:`w-full overflow-x-auto px-2 pb-1`,children:(0,i.jsx)(`div`,{className:`grid gap-3`,style:{gridTemplateColumns:`repeat(auto-fill, minmax(200px, 240px))`},children:n.map(t=>{let n=a[t.trend??`neutral`],s=!!o;return(0,i.jsxs)(`div`,{className:(0,r.cn)(`flex flex-col overflow-hidden rounded border border-border bg-card shadow-card`,s&&`cursor-pointer transition-shadow hover:shadow-md`),onClick:s?()=>o(t):void 0,role:s?`button`:void 0,tabIndex:s?0:void 0,onKeyDown:s?e=>{(e.key===`Enter`||e.key===` `)&&o(t)}:void 0,children:[(0,i.jsx)(`div`,{className:(0,r.cn)(`h-0.75 w-full shrink-0`,n)}),(0,i.jsxs)(`div`,{className:`flex flex-1 flex-col gap-2 px-5 py-4`,children:[(0,i.jsx)(`span`,{className:`font-semibold text-[11px] text-text-positive-weak uppercase tracking-widest`,children:t.label}),t.value!==null&&t.value!==void 0?(0,i.jsx)(e.Statistic,{value:t.value,prefix:t.prefix,suffix:t.suffix,precision:t.precision,trend:t.trend,size:`xl`,className:`font-bold`}):(0,i.jsx)(`span`,{className:`font-bold text-text-positive-strong text-xl tabular-nums`,children:`—`}),!!t.description&&(0,i.jsx)(`span`,{className:`text-text-positive-weak text-xs`,children:t.description})]})]},t.label)})})})});o.displayName=`UITableSummaryBar`,exports.UITableSummaryBar=o;
2
- //# sourceMappingURL=summary-bar-DKZh-VSB.cjs.map
1
+ const e=require("./data-display/statistic.cjs"),t=require("./tables-BqZ4Zs6e.cjs");let n=require("react"),r=require("@customafk/react-toolkit/utils"),i=require("react/jsx-runtime");const a={up:`bg-success`,down:`bg-danger`,neutral:`bg-primary`},o=(0,n.memo)(()=>{let{summary:n,onSummaryItemClick:o}=t.Y(),{isOpen:s}=t.Z();return!s||!n||n.length===0?null:(0,i.jsx)(`div`,{"data-slot":`table-summary-bar`,className:`w-full overflow-x-auto px-2 pb-1`,children:(0,i.jsx)(`div`,{className:`grid gap-3`,style:{gridTemplateColumns:`repeat(auto-fill, minmax(200px, 240px))`},children:n.map(t=>{let n=a[t.trend??`neutral`],s=!!o;return(0,i.jsxs)(`div`,{className:(0,r.cn)(`flex flex-col overflow-hidden rounded border border-border bg-card shadow-card`,s&&`cursor-pointer transition-shadow hover:shadow-md`),onClick:s?()=>o(t):void 0,role:s?`button`:void 0,tabIndex:s?0:void 0,onKeyDown:s?e=>{(e.key===`Enter`||e.key===` `)&&o(t)}:void 0,children:[(0,i.jsx)(`div`,{className:(0,r.cn)(`h-0.75 w-full shrink-0`,n)}),(0,i.jsxs)(`div`,{className:`flex flex-1 flex-col gap-2 px-5 py-4`,children:[(0,i.jsx)(`span`,{className:`font-semibold text-[11px] text-text-positive-weak uppercase tracking-widest`,children:t.label}),t.value!==null&&t.value!==void 0?(0,i.jsx)(e.Statistic,{value:t.value,prefix:t.prefix,suffix:t.suffix,precision:t.precision,trend:t.trend,size:`xl`,className:`font-bold`}):(0,i.jsx)(`span`,{className:`font-bold text-text-positive-strong text-xl tabular-nums`,children:`—`}),!!t.description&&(0,i.jsx)(`span`,{className:`text-text-positive-weak text-xs`,children:t.description})]})]},t.label)})})})});o.displayName=`UITableSummaryBar`,exports.UITableSummaryBar=o;
2
+ //# sourceMappingURL=summary-bar-C08g8bb1.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"summary-bar-DKZh-VSB.cjs","names":["useUITableContext","useUITableSummaryContext","Statistic"],"sources":["../packages/components/features/tables/components/table/summary-bar.tsx"],"sourcesContent":["'use client';\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport { useUITableContext, useUITableSummaryContext } from '../../hooks/use-context';\nimport type { SummaryItem } from '../../types';\n\nconst trendAccent: Record<NonNullable<SummaryItem['trend']>, string> = {\n up: 'bg-success',\n down: 'bg-danger',\n neutral: 'bg-primary',\n};\n\nexport const UITableSummaryBar = memo(() => {\n const { summary, onSummaryItemClick } = useUITableContext();\n const { isOpen } = useUITableSummaryContext();\n\n if (!isOpen || !summary || summary.length === 0) return null;\n\n return (\n <div data-slot=\"table-summary-bar\" className=\"w-full overflow-x-auto px-2 pb-1\">\n <div className=\"grid gap-3\" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 240px))' }}>\n {summary.map(item => {\n const accent = trendAccent[item.trend ?? 'neutral'];\n const isClickable = !!onSummaryItemClick;\n\n return (\n <div\n key={item.label}\n className={cn(\n 'flex flex-col overflow-hidden rounded border border-border bg-card shadow-card',\n isClickable && 'cursor-pointer transition-shadow hover:shadow-md'\n )}\n onClick={isClickable ? () => onSummaryItemClick(item) : undefined}\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onKeyDown={\n isClickable\n ? e => {\n if (e.key === 'Enter' || e.key === ' ') onSummaryItemClick(item);\n }\n : undefined\n }\n >\n {/* Coloured accent strip */}\n <div className={cn('h-0.75 w-full shrink-0', accent)} />\n\n <div className=\"flex flex-1 flex-col gap-2 px-5 py-4\">\n {/* Label */}\n <span className=\"font-semibold text-[11px] text-text-positive-weak uppercase tracking-widest\">{item.label}</span>\n\n {/* Value */}\n {item.value !== null && item.value !== undefined ? (\n <Statistic\n value={item.value}\n prefix={item.prefix}\n suffix={item.suffix}\n precision={item.precision}\n trend={item.trend}\n size=\"xl\"\n className=\"font-bold\"\n />\n ) : (\n <span className=\"font-bold text-text-positive-strong text-xl tabular-nums\">—</span>\n )}\n\n {/* Description */}\n {!!item.description && <span className=\"text-text-positive-weak text-xs\">{item.description}</span>}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n});\nUITableSummaryBar.displayName = 'UITableSummaryBar';\n"],"mappings":"qLASA,MAAM,EAAiE,CACrE,GAAI,aACJ,KAAM,YACN,QAAS,YACX,EAEa,GAAA,EAAA,EAAA,KAAA,KAA+B,CAC1C,GAAM,CAAE,UAAS,sBAAuBA,EAAAA,EAAkB,EACpD,CAAE,UAAWC,EAAAA,EAAyB,EAI5C,MAFI,CAAC,GAAU,CAAC,GAAW,EAAQ,SAAW,EAAU,MAGtD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,oBAAoB,UAAU,mCAC3C,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,aAAa,MAAO,CAAE,oBAAqB,yCAA0C,EACjG,SAAA,EAAQ,IAAI,GAAQ,CACnB,IAAM,EAAS,EAAY,EAAK,OAAS,WACnC,EAAc,CAAC,CAAC,EAEtB,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAEE,WAAA,EAAA,EAAA,GAAA,CACE,iFACA,GAAe,kDACjB,EACA,QAAS,MAAoB,EAAmB,CAAI,EAAI,IAAA,GACxD,KAAM,EAAc,SAAW,IAAA,GAC/B,SAAU,EAAc,EAAI,IAAA,GAC5B,UACE,EACI,GAAK,EACC,EAAE,MAAQ,SAAW,EAAE,MAAQ,MAAK,EAAmB,CAAI,CACjE,EACA,IAAA,GAdR,SAAA,EAkBE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,WAAA,EAAA,EAAA,GAAA,CAAc,yBAA0B,CAAM,CAAI,CAAA,GAEvD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uCAAf,SAAA,EAEE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,8EAA+E,SAAA,EAAK,KAAY,CAAA,EAG/G,EAAK,QAAU,MAAQ,EAAK,QAAU,IAAA,IACrC,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CACE,MAAO,EAAK,MACZ,OAAQ,EAAK,OACb,OAAQ,EAAK,OACb,UAAW,EAAK,UAChB,MAAO,EAAK,MACZ,KAAK,KACL,UAAU,WACX,CAAA,GAED,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2DAA2D,SAAA,GAAO,CAAA,EAInF,CAAC,CAAC,EAAK,cAAe,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,kCAAmC,SAAA,EAAK,WAAkB,CAAA,CAC9F,CACF,CAAA,CAAA,CAzCE,EAAA,EAAK,KAyCP,CAET,CAAC,CACE,CAAA,CACF,CAAA,CAET,CAAC,EACD,EAAkB,YAAc"}
1
+ {"version":3,"file":"summary-bar-C08g8bb1.cjs","names":["useUITableContext","useUITableSummaryContext","Statistic"],"sources":["../packages/components/features/tables/components/table/summary-bar.tsx"],"sourcesContent":["'use client';\nimport { memo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport { useUITableContext, useUITableSummaryContext } from '../../hooks/use-context';\nimport type { SummaryItem } from '../../types';\n\nconst trendAccent: Record<NonNullable<SummaryItem['trend']>, string> = {\n up: 'bg-success',\n down: 'bg-danger',\n neutral: 'bg-primary',\n};\n\nexport const UITableSummaryBar = memo(() => {\n const { summary, onSummaryItemClick } = useUITableContext();\n const { isOpen } = useUITableSummaryContext();\n\n if (!isOpen || !summary || summary.length === 0) return null;\n\n return (\n <div data-slot=\"table-summary-bar\" className=\"w-full overflow-x-auto px-2 pb-1\">\n <div className=\"grid gap-3\" style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 240px))' }}>\n {summary.map(item => {\n const accent = trendAccent[item.trend ?? 'neutral'];\n const isClickable = !!onSummaryItemClick;\n\n return (\n <div\n key={item.label}\n className={cn(\n 'flex flex-col overflow-hidden rounded border border-border bg-card shadow-card',\n isClickable && 'cursor-pointer transition-shadow hover:shadow-md'\n )}\n onClick={isClickable ? () => onSummaryItemClick(item) : undefined}\n role={isClickable ? 'button' : undefined}\n tabIndex={isClickable ? 0 : undefined}\n onKeyDown={\n isClickable\n ? e => {\n if (e.key === 'Enter' || e.key === ' ') onSummaryItemClick(item);\n }\n : undefined\n }\n >\n {/* Coloured accent strip */}\n <div className={cn('h-0.75 w-full shrink-0', accent)} />\n\n <div className=\"flex flex-1 flex-col gap-2 px-5 py-4\">\n {/* Label */}\n <span className=\"font-semibold text-[11px] text-text-positive-weak uppercase tracking-widest\">{item.label}</span>\n\n {/* Value */}\n {item.value !== null && item.value !== undefined ? (\n <Statistic\n value={item.value}\n prefix={item.prefix}\n suffix={item.suffix}\n precision={item.precision}\n trend={item.trend}\n size=\"xl\"\n className=\"font-bold\"\n />\n ) : (\n <span className=\"font-bold text-text-positive-strong text-xl tabular-nums\">—</span>\n )}\n\n {/* Description */}\n {!!item.description && <span className=\"text-text-positive-weak text-xs\">{item.description}</span>}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n});\nUITableSummaryBar.displayName = 'UITableSummaryBar';\n"],"mappings":"qLASA,MAAM,EAAiE,CACrE,GAAI,aACJ,KAAM,YACN,QAAS,YACX,EAEa,GAAA,EAAA,EAAA,KAAA,KAA+B,CAC1C,GAAM,CAAE,UAAS,sBAAuBA,EAAAA,EAAkB,EACpD,CAAE,UAAWC,EAAAA,EAAyB,EAI5C,MAFI,CAAC,GAAU,CAAC,GAAW,EAAQ,SAAW,EAAU,MAGtD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,oBAAoB,UAAU,mCAC3C,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,aAAa,MAAO,CAAE,oBAAqB,yCAA0C,EACjG,SAAA,EAAQ,IAAI,GAAQ,CACnB,IAAM,EAAS,EAAY,EAAK,OAAS,WACnC,EAAc,CAAC,CAAC,EAEtB,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAEE,WAAA,EAAA,EAAA,GAAA,CACE,iFACA,GAAe,kDACjB,EACA,QAAS,MAAoB,EAAmB,CAAI,EAAI,IAAA,GACxD,KAAM,EAAc,SAAW,IAAA,GAC/B,SAAU,EAAc,EAAI,IAAA,GAC5B,UACE,EACI,GAAK,EACC,EAAE,MAAQ,SAAW,EAAE,MAAQ,MAAK,EAAmB,CAAI,CACjE,EACA,IAAA,GAdR,SAAA,EAkBE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,WAAA,EAAA,EAAA,GAAA,CAAc,yBAA0B,CAAM,CAAI,CAAA,GAEvD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uCAAf,SAAA,EAEE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,8EAA+E,SAAA,EAAK,KAAY,CAAA,EAG/G,EAAK,QAAU,MAAQ,EAAK,QAAU,IAAA,IACrC,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CACE,MAAO,EAAK,MACZ,OAAQ,EAAK,OACb,OAAQ,EAAK,OACb,UAAW,EAAK,UAChB,MAAO,EAAK,MACZ,KAAK,KACL,UAAU,WACX,CAAA,GAED,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2DAA2D,SAAA,GAAO,CAAA,EAInF,CAAC,CAAC,EAAK,cAAe,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,kCAAmC,SAAA,EAAK,WAAkB,CAAA,CAC9F,CACF,CAAA,CAAA,CAzCE,EAAA,EAAK,KAyCP,CAET,CAAC,CACE,CAAA,CACF,CAAA,CAET,CAAC,EACD,EAAkB,YAAc"}