@customafk/lunas-ui 0.2.81 → 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.
- package/dist/{analysis-panel-DYF2CmAH.cjs → analysis-panel-BoKjkPYz.cjs} +2 -2
- package/dist/{analysis-panel-DYF2CmAH.cjs.map → analysis-panel-BoKjkPYz.cjs.map} +1 -1
- package/dist/{analysis-panel-_s1fgcZC.mjs → analysis-panel-CZ8g9AAO.mjs} +2 -2
- package/dist/{analysis-panel-_s1fgcZC.mjs.map → analysis-panel-CZ8g9AAO.mjs.map} +1 -1
- package/dist/{badge-C_KLKwiS.d.cts → badge-BPiU1Ss2.d.cts} +2 -2
- package/dist/{badge-C_KLKwiS.d.mts → badge-BPiU1Ss2.d.mts} +2 -2
- package/dist/{badge-display-D6d7wTEE.mjs → badge-display-B5m09_Hs.mjs} +2 -2
- package/dist/{badge-display-D6d7wTEE.mjs.map → badge-display-B5m09_Hs.mjs.map} +1 -1
- package/dist/{badge-display-DWzSl3rs.cjs → badge-display-DHbCN998.cjs} +2 -2
- package/dist/{badge-display-DWzSl3rs.cjs.map → badge-display-DHbCN998.cjs.map} +1 -1
- package/dist/{boolean-display-Wko_5Jd5.mjs → boolean-display-CzHHDfHW.mjs} +2 -2
- package/dist/{boolean-display-Wko_5Jd5.mjs.map → boolean-display-CzHHDfHW.mjs.map} +1 -1
- package/dist/{boolean-display-C5GIuWnc.cjs → boolean-display-D2wjQhNX.cjs} +2 -2
- package/dist/{boolean-display-C5GIuWnc.cjs.map → boolean-display-D2wjQhNX.cjs.map} +1 -1
- package/dist/{button-CnKmz4qM.d.cts → button-BnoPktln.d.cts} +3 -3
- package/dist/{button-CnKmz4qM.d.mts → button-BnoPktln.d.mts} +3 -3
- package/dist/{calendar-BT6-Fo3T.d.mts → calendar-BkV5hTX2.d.mts} +2 -2
- package/dist/{calendar-D_QmR9VE.d.cts → calendar-iDMPT1kI.d.cts} +2 -2
- package/dist/{carousel-BBI4xPdK.d.mts → carousel-D7VXWJ3S.d.mts} +2 -2
- package/dist/{carousel-B_IXlBdH.d.cts → carousel-bBvM31sh.d.cts} +2 -2
- package/dist/currency-display-7w-ZjVUw.mjs +2 -0
- package/dist/currency-display-7w-ZjVUw.mjs.map +1 -0
- package/dist/currency-display-B06kc2IG.cjs +2 -0
- package/dist/currency-display-B06kc2IG.cjs.map +1 -0
- package/dist/{date-display-DXyb-Ai2.mjs → date-display-BO7OY_AC.mjs} +2 -2
- package/dist/{date-display-DXyb-Ai2.mjs.map → date-display-BO7OY_AC.mjs.map} +1 -1
- package/dist/{date-display-D38qvsh2.cjs → date-display-DHnZr_yf.cjs} +2 -2
- package/dist/{date-display-D38qvsh2.cjs.map → date-display-DHnZr_yf.cjs.map} +1 -1
- package/dist/{description-display-BwBMrRAi.mjs → description-display-CBfoP3Y2.mjs} +2 -2
- package/dist/{description-display-BwBMrRAi.mjs.map → description-display-CBfoP3Y2.mjs.map} +1 -1
- package/dist/{description-display-DIeHy7ll.cjs → description-display-Cckihd1s.cjs} +2 -2
- package/dist/{description-display-DIeHy7ll.cjs.map → description-display-Cckihd1s.cjs.map} +1 -1
- package/dist/dialogs/detail-dialog/components/sidebar.d.cts +1 -1
- package/dist/dialogs/detail-dialog/components/sidebar.d.mts +1 -1
- package/dist/dialogs/side-panel.cjs +2 -0
- package/dist/dialogs/side-panel.cjs.map +1 -0
- package/dist/dialogs/side-panel.d.cts +2 -0
- package/dist/dialogs/side-panel.d.mts +2 -0
- package/dist/dialogs/side-panel.mjs +2 -0
- package/dist/dialogs/side-panel.mjs.map +1 -0
- package/dist/{email-display-Be3b-kDL.mjs → email-display-Bk_furIx.mjs} +2 -2
- package/dist/{email-display-Be3b-kDL.mjs.map → email-display-Bk_furIx.mjs.map} +1 -1
- package/dist/{email-display-_FRE2qcO.cjs → email-display-w-hRYIeL.cjs} +2 -2
- package/dist/{email-display-_FRE2qcO.cjs.map → email-display-w-hRYIeL.cjs.map} +1 -1
- package/dist/features/descriptions/index.d.cts +1 -1
- package/dist/features/descriptions/index.d.mts +1 -1
- package/dist/features/tables/index.cjs +1 -1
- package/dist/features/tables/index.d.cts +1 -1
- package/dist/features/tables/index.d.mts +1 -1
- package/dist/features/tables/index.mjs +1 -1
- package/dist/{filter-C2wE49q7.mjs → filter-BO7ISTIR.mjs} +2 -2
- package/dist/{filter-C2wE49q7.mjs.map → filter-BO7ISTIR.mjs.map} +1 -1
- package/dist/{filter-z7p4lRp8.cjs → filter-CQ9BD0MV.cjs} +2 -2
- package/dist/{filter-z7p4lRp8.cjs.map → filter-CQ9BD0MV.cjs.map} +1 -1
- package/dist/{flex-CIzZIICK.d.cts → flex-CrxTaAXE.d.cts} +2 -2
- package/dist/{flex-CIzZIICK.d.mts → flex-CrxTaAXE.d.mts} +2 -2
- package/dist/{index-BSj8azta.d.cts → index-BMuVmm7f.d.mts} +2 -2
- package/dist/{index-CjiDR-94.d.mts → index-BPo-Lg3p.d.mts} +15 -12
- package/dist/{index-CEmVk1zP.d.mts → index-CLx89ATZ.d.cts} +2 -2
- package/dist/{index-DqAbPipJ.d.cts → index-DaLpXe5l.d.cts} +15 -12
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +13 -11
- package/dist/index.d.mts +13 -11
- package/dist/index.mjs +1 -1
- package/dist/layouts/flex.d.cts +1 -1
- package/dist/layouts/flex.d.mts +1 -1
- package/dist/layouts/ui-grid.cjs +2 -0
- package/dist/layouts/ui-grid.cjs.map +1 -0
- package/dist/layouts/ui-grid.d.cts +2 -0
- package/dist/layouts/ui-grid.d.mts +2 -0
- package/dist/layouts/ui-grid.mjs +2 -0
- package/dist/layouts/ui-grid.mjs.map +1 -0
- package/dist/{list-display-BvKGl7uq.cjs → list-display-DDeJoneW.cjs} +2 -2
- package/dist/{list-display-BvKGl7uq.cjs.map → list-display-DDeJoneW.cjs.map} +1 -1
- package/dist/{list-display-CWQvIMUj.mjs → list-display-DLsm8uAh.mjs} +2 -2
- package/dist/{list-display-CWQvIMUj.mjs.map → list-display-DLsm8uAh.mjs.map} +1 -1
- package/dist/{name-display-DfOtYp7d.cjs → name-display-CKnyugrP.cjs} +2 -2
- package/dist/{name-display-DfOtYp7d.cjs.map → name-display-CKnyugrP.cjs.map} +1 -1
- package/dist/{name-display-CnTRVqX4.mjs → name-display-H5HFH1fU.mjs} +2 -2
- package/dist/{name-display-CnTRVqX4.mjs.map → name-display-H5HFH1fU.mjs.map} +1 -1
- package/dist/{pagination-AxRzmAtZ.d.cts → pagination-BRw-yZBY.d.cts} +2 -2
- package/dist/{pagination-D12pR8_5.d.mts → pagination-BlLiOvY9.d.mts} +2 -2
- package/dist/{paragraph-C5HE9u0Q.d.mts → paragraph-CRo5eC7H.d.mts} +2 -2
- package/dist/{paragraph-DJlHIDmk.d.cts → paragraph-CkCNIsvz.d.cts} +2 -2
- package/dist/{permalink-DhqOATLQ.mjs → permalink-CaCx9fi6.mjs} +2 -2
- package/dist/{permalink-DhqOATLQ.mjs.map → permalink-CaCx9fi6.mjs.map} +1 -1
- package/dist/{permalink-29QzG9Xe.cjs → permalink-azuGQg2b.cjs} +2 -2
- package/dist/{permalink-29QzG9Xe.cjs.map → permalink-azuGQg2b.cjs.map} +1 -1
- package/dist/{phone-number-CQXrATQO.mjs → phone-number-Ba-f4s1Y.mjs} +2 -2
- package/dist/{phone-number-CQXrATQO.mjs.map → phone-number-Ba-f4s1Y.mjs.map} +1 -1
- package/dist/{phone-number-C2k8llhf.cjs → phone-number-BqRhKQdr.cjs} +2 -2
- package/dist/{phone-number-C2k8llhf.cjs.map → phone-number-BqRhKQdr.cjs.map} +1 -1
- package/dist/{progress-display-DZb1qjfY.mjs → progress-display-0UsBzt_r.mjs} +2 -2
- package/dist/{progress-display-DZb1qjfY.mjs.map → progress-display-0UsBzt_r.mjs.map} +1 -1
- package/dist/{progress-display-B4WVzdJw.cjs → progress-display-CiYWPOnq.cjs} +2 -2
- package/dist/{progress-display-B4WVzdJw.cjs.map → progress-display-CiYWPOnq.cjs.map} +1 -1
- package/dist/{resizable-D61lvcIL.d.cts → resizable-C3uADYIg.d.cts} +2 -2
- package/dist/{resizable-D61lvcIL.d.mts → resizable-C3uADYIg.d.mts} +2 -2
- package/dist/side-panel-DPrM5ygG.d.cts +86 -0
- package/dist/side-panel-DPrM5ygG.d.mts +86 -0
- package/dist/statistic-639yMA2d.mjs +2 -0
- package/dist/statistic-639yMA2d.mjs.map +1 -0
- package/dist/statistic-CE_Jg8SN.cjs +2 -0
- package/dist/statistic-CE_Jg8SN.cjs.map +1 -0
- package/dist/{status-display-CcihiYsH.mjs → status-display-BCYpNJmd.mjs} +2 -2
- package/dist/{status-display-CcihiYsH.mjs.map → status-display-BCYpNJmd.mjs.map} +1 -1
- package/dist/{status-display-DJ8fFqyX.cjs → status-display-xcCCGpGS.cjs} +2 -2
- package/dist/{status-display-DJ8fFqyX.cjs.map → status-display-xcCCGpGS.cjs.map} +1 -1
- package/dist/{summary-bar-DK8glsr4.cjs → summary-bar-C08g8bb1.cjs} +2 -2
- package/dist/{summary-bar-DK8glsr4.cjs.map → summary-bar-C08g8bb1.cjs.map} +1 -1
- package/dist/{summary-bar-C4loKj1L.mjs → summary-bar-C3NAnI3V.mjs} +2 -2
- package/dist/{summary-bar-C4loKj1L.mjs.map → summary-bar-C3NAnI3V.mjs.map} +1 -1
- package/dist/tables-BqZ4Zs6e.cjs +2 -0
- package/dist/tables-BqZ4Zs6e.cjs.map +1 -0
- package/dist/tables-Dg3KMBKA.mjs +2 -0
- package/dist/tables-Dg3KMBKA.mjs.map +1 -0
- package/dist/{tooltip-CLjCwnTD.cjs → tooltip-BVzKgxrZ.cjs} +3 -3
- package/dist/{tooltip-CLjCwnTD.cjs.map → tooltip-BVzKgxrZ.cjs.map} +1 -1
- package/dist/{tooltip-BKcU3bMc.mjs → tooltip-D7U_Nl5c.mjs} +3 -3
- package/dist/{tooltip-BKcU3bMc.mjs.map → tooltip-D7U_Nl5c.mjs.map} +1 -1
- package/dist/typography/paragraph.d.cts +1 -1
- package/dist/typography/paragraph.d.mts +1 -1
- package/dist/ui/alert-dialog.cjs +1 -1
- package/dist/ui/alert-dialog.cjs.map +1 -1
- package/dist/ui/alert-dialog.mjs +1 -1
- package/dist/ui/alert-dialog.mjs.map +1 -1
- package/dist/ui/badge.d.cts +1 -1
- package/dist/ui/badge.d.mts +1 -1
- package/dist/ui/button.d.cts +1 -1
- package/dist/ui/button.d.mts +1 -1
- package/dist/ui/calendar.d.cts +1 -1
- package/dist/ui/calendar.d.mts +1 -1
- package/dist/ui/carousel.d.cts +1 -1
- package/dist/ui/carousel.d.mts +1 -1
- package/dist/ui/dialog.cjs +1 -1
- package/dist/ui/dialog.cjs.map +1 -1
- package/dist/ui/dialog.mjs +1 -1
- package/dist/ui/dialog.mjs.map +1 -1
- package/dist/ui/pagination.d.cts +1 -1
- package/dist/ui/pagination.d.mts +1 -1
- package/dist/ui/resizable.d.cts +1 -1
- package/dist/ui/resizable.d.mts +1 -1
- package/dist/ui/sheet.cjs +1 -1
- package/dist/ui/sheet.cjs.map +1 -1
- package/dist/ui/sheet.mjs +1 -1
- package/dist/ui/sheet.mjs.map +1 -1
- package/dist/ui-grid-CzL5J7cm.d.cts +128 -0
- package/dist/ui-grid-CzL5J7cm.d.mts +128 -0
- package/package.json +9 -1
- package/dist/currency-display-BGkpGtN_.mjs +0 -2
- package/dist/currency-display-BGkpGtN_.mjs.map +0 -1
- package/dist/currency-display-Bbh5InhV.cjs +0 -2
- package/dist/currency-display-Bbh5InhV.cjs.map +0 -1
- package/dist/statistic-DoNUSe3e.mjs +0 -2
- package/dist/statistic-DoNUSe3e.mjs.map +0 -1
- package/dist/statistic-wnnjHsKj.cjs +0 -2
- package/dist/statistic-wnnjHsKj.cjs.map +0 -1
- package/dist/tables-BTBtN1di.mjs +0 -2
- package/dist/tables-BTBtN1di.mjs.map +0 -1
- package/dist/tables-BzP8Cnvh.cjs +0 -2
- package/dist/tables-BzP8Cnvh.cjs.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./data-display/statistic.cjs"),t=require("./tables-
|
|
2
|
-
//# sourceMappingURL=analysis-panel-
|
|
1
|
+
const e=require("./data-display/statistic.cjs"),t=require("./tables-BqZ4Zs6e.cjs");let n=require("lucide-react"),r=require("react"),i=require("@customafk/react-toolkit/utils"),a=require("react/jsx-runtime");const o={sum:`Tổng`,avg:`Trung bình`,count:`Đếm`,min:`Nhỏ nhất`,max:`Lớn nhất`},s=(0,r.memo)(()=>{let{table:s,totalRows:l}=t.Y(),{rowSelectionState:u}=t.J(),{isOpen:d,toggle:f}=t.q(),p=(0,r.useMemo)(()=>s.getRowModel().rows,[s]),m=(0,r.useMemo)(()=>s.getSelectedRowModel().flatRows,[s,u]),h=(0,r.useMemo)(()=>s.getHeaderGroups()[0]?.headers??[],[s]),g=(0,r.useMemo)(()=>h.filter(e=>![`select`,`actions`].includes(e.id)).flatMap(e=>{let n=e.column.columnDef.meta?.aggregation;if(!n)return[];let r=n.label??(typeof e.column.columnDef.header==`string`?e.column.columnDef.header:e.id),i=t.B(p,e.id),a=m.length>0?t.B(m,e.id):null;return[{colId:e.id,header:r,aggregation:n,allValue:t.z(p.length,i,n.type),selectedValue:a===null?null:t.z(m.length,a,n.type)}]}),[h,p,m]);return(0,a.jsxs)(`div`,{"data-slot":`table-analysis-panel`,className:`w-full border-t border-border`,children:[(0,a.jsxs)(`button`,{type:`button`,className:(0,i.cn)(`flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive`,`hover:bg-muted-bg-subtle transition-colors outline-none`,`focus-visible:ring-2 focus-visible:ring-primary-weak`),onClick:f,"aria-expanded":d,children:[(0,a.jsx)(`span`,{children:`Tổng quan dữ liệu`}),d?(0,a.jsx)(n.ChevronUpIcon,{size:14}):(0,a.jsx)(n.ChevronDownIcon,{size:14})]}),d&&(0,a.jsxs)(`div`,{className:`px-4 pb-4 pt-2 space-y-4`,children:[(0,a.jsxs)(`div`,{className:`flex flex-wrap gap-4`,children:[(0,a.jsx)(c,{label:`Tổng bản ghi`,value:l??p.length}),(0,a.jsx)(c,{label:`Hàng hiển thị`,value:p.length}),(0,a.jsx)(c,{label:`Hàng đã chọn`,value:m.length,highlight:m.length>0})]}),g.length>0&&(0,a.jsxs)(`div`,{children:[(0,a.jsx)(`p`,{className:`mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak`,children:`Tóm tắt cột`}),(0,a.jsx)(`div`,{className:`overflow-x-auto rounded-md border border-border`,children:(0,a.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,a.jsx)(`thead`,{children:(0,a.jsxs)(`tr`,{className:`border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak`,children:[(0,a.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Cột`}),(0,a.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Kiểu`}),(0,a.jsx)(`th`,{className:`px-3 py-2 text-right font-medium`,children:`Tất cả hàng`}),m.length>0&&(0,a.jsx)(`th`,{className:`px-3 py-2 text-right font-medium`,children:`Hàng đã chọn`})]})}),(0,a.jsx)(`tbody`,{children:g.map((t,n)=>(0,a.jsxs)(`tr`,{className:(0,i.cn)(`border-b border-border last:border-b-0`,n%2==1&&`bg-muted-bg-subtle/50`),children:[(0,a.jsx)(`td`,{className:`px-3 py-2 text-text-positive font-medium`,children:t.header}),(0,a.jsx)(`td`,{className:`px-3 py-2 text-text-positive-weak`,children:o[t.aggregation.type]}),(0,a.jsx)(`td`,{className:`px-3 py-2 text-right`,children:(0,a.jsx)(e.Statistic,{value:t.allValue,prefix:t.aggregation.prefix,suffix:t.aggregation.suffix,precision:t.aggregation.precision,size:`sm`})}),m.length>0&&(0,a.jsx)(`td`,{className:`px-3 py-2 text-right`,children:t.selectedValue===null?(0,a.jsx)(`span`,{className:`text-text-positive-weak`,children:`—`}):(0,a.jsx)(e.Statistic,{value:t.selectedValue,prefix:t.aggregation.prefix,suffix:t.aggregation.suffix,precision:t.aggregation.precision,size:`sm`})})]},t.colId))})]})})]})]})]})});s.displayName=`UITableAnalysisPanel`;const c=(0,r.memo)(({label:e,value:t,highlight:n})=>(0,a.jsxs)(`div`,{className:(0,i.cn)(`flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white`,n&&t>0?`border-primary bg-primary-bg-subtle`:`border-border bg-white`),children:[(0,a.jsx)(`span`,{className:`text-[11px] text-text-positive-weak`,children:e}),(0,a.jsx)(`span`,{className:`text-base font-semibold tabular-nums text-text-positive-strong`,children:t.toLocaleString()})]}));c.displayName=`StatChip`,exports.UITableAnalysisPanel=s;
|
|
2
|
+
//# sourceMappingURL=analysis-panel-BoKjkPYz.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-panel-DYF2CmAH.cjs","names":["useUITableContext","useUITableBodyContext","useUITableAnalysisContext","extractNumericValues","computeAggregation","ChevronUpIcon","ChevronDownIcon","Statistic"],"sources":["../packages/components/features/tables/components/table/analysis-panel.tsx"],"sourcesContent":["'use client';\nimport { memo, useMemo } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport type { AnyEntity } from '@/types';\nimport { useUITableAnalysisContext, useUITableBodyContext, useUITableContext } from '../../hooks/use-context';\nimport type { ColumnAggregation, ColumnAggregationType } from '../../types';\nimport { computeAggregation, extractNumericValues } from '../../utils/aggregation';\n\ntype AggregationLabel = {\n colId: string;\n header: string;\n aggregation: ColumnAggregation;\n allValue: number;\n selectedValue: number | null;\n};\n\nconst typeLabels: Record<ColumnAggregationType, string> = {\n sum: 'Tổng',\n avg: 'Trung bình',\n count: 'Đếm',\n min: 'Nhỏ nhất',\n max: 'Lớn nhất',\n};\n\nexport const UITableAnalysisPanel = memo(() => {\n const { table, totalRows } = useUITableContext();\n const { rowSelectionState } = useUITableBodyContext();\n const { isOpen, toggle } = useUITableAnalysisContext();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: row model\n const allRows = useMemo(() => table.getRowModel().rows, [table]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: selected rows\n const selectedRows = useMemo(() => table.getSelectedRowModel().flatRows, [table, rowSelectionState]);\n\n const headers = useMemo(() => table.getHeaderGroups()[0]?.headers ?? [], [table]);\n\n const aggregationRows = useMemo<AggregationLabel[]>(() => {\n return headers\n .filter(h => !['select', 'actions'].includes(h.id))\n .flatMap(header => {\n const agg = (header.column.columnDef.meta as AnyEntity)?.aggregation as ColumnAggregation | undefined;\n if (!agg) return [];\n\n const headerText = agg.label ?? (typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.id);\n\n const allValues = extractNumericValues(allRows, header.id);\n const selectedValues = selectedRows.length > 0 ? extractNumericValues(selectedRows, header.id) : null;\n\n return [\n {\n colId: header.id,\n header: headerText,\n aggregation: agg,\n allValue: computeAggregation(allRows.length, allValues, agg.type),\n selectedValue: selectedValues !== null ? computeAggregation(selectedRows.length, selectedValues, agg.type) : null,\n },\n ];\n });\n }, [headers, allRows, selectedRows]);\n\n return (\n <div data-slot=\"table-analysis-panel\" className=\"w-full border-t border-border\">\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive',\n 'hover:bg-muted-bg-subtle transition-colors outline-none',\n 'focus-visible:ring-2 focus-visible:ring-primary-weak'\n )}\n onClick={toggle}\n aria-expanded={isOpen}\n >\n <span>Tổng quan dữ liệu</span>\n {isOpen ? <ChevronUpIcon size={14} /> : <ChevronDownIcon size={14} />}\n </button>\n\n {isOpen && (\n <div className=\"px-4 pb-4 pt-2 space-y-4\">\n {/* Row summary */}\n <div className=\"flex flex-wrap gap-4\">\n <StatChip label=\"Tổng bản ghi\" value={totalRows ?? allRows.length} />\n <StatChip label=\"Hàng hiển thị\" value={allRows.length} />\n <StatChip label=\"Hàng đã chọn\" value={selectedRows.length} highlight={selectedRows.length > 0} />\n </div>\n\n {/* Column aggregations */}\n {aggregationRows.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak\">Tóm tắt cột</p>\n <div className=\"overflow-x-auto rounded-md border border-border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak\">\n <th className=\"px-3 py-2 text-left font-medium\">Cột</th>\n <th className=\"px-3 py-2 text-left font-medium\">Kiểu</th>\n <th className=\"px-3 py-2 text-right font-medium\">Tất cả hàng</th>\n {selectedRows.length > 0 && <th className=\"px-3 py-2 text-right font-medium\">Hàng đã chọn</th>}\n </tr>\n </thead>\n <tbody>\n {aggregationRows.map((row, idx) => (\n <tr key={row.colId} className={cn('border-b border-border last:border-b-0', idx % 2 === 1 && 'bg-muted-bg-subtle/50')}>\n <td className=\"px-3 py-2 text-text-positive font-medium\">{row.header}</td>\n <td className=\"px-3 py-2 text-text-positive-weak\">{typeLabels[row.aggregation.type]}</td>\n <td className=\"px-3 py-2 text-right\">\n <Statistic\n value={row.allValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n </td>\n {selectedRows.length > 0 && (\n <td className=\"px-3 py-2 text-right\">\n {row.selectedValue !== null ? (\n <Statistic\n value={row.selectedValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n ) : (\n <span className=\"text-text-positive-weak\">—</span>\n )}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\nUITableAnalysisPanel.displayName = 'UITableAnalysisPanel';\n\nconst StatChip = memo<{ label: string; value: number; highlight?: boolean }>(({ label, value, highlight }) => (\n <div\n className={cn(\n 'flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white',\n highlight && value > 0 ? 'border-primary bg-primary-bg-subtle' : 'border-border bg-white'\n )}\n >\n <span className=\"text-[11px] text-text-positive-weak\">{label}</span>\n <span className=\"text-base font-semibold tabular-nums text-text-positive-strong\">{value.toLocaleString()}</span>\n </div>\n));\nStatChip.displayName = 'StatChip';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analysis-panel-BoKjkPYz.cjs","names":["useUITableContext","useUITableBodyContext","useUITableAnalysisContext","extractNumericValues","computeAggregation","ChevronUpIcon","ChevronDownIcon","Statistic"],"sources":["../packages/components/features/tables/components/table/analysis-panel.tsx"],"sourcesContent":["'use client';\nimport { memo, useMemo } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport type { AnyEntity } from '@/types';\nimport { useUITableAnalysisContext, useUITableBodyContext, useUITableContext } from '../../hooks/use-context';\nimport type { ColumnAggregation, ColumnAggregationType } from '../../types';\nimport { computeAggregation, extractNumericValues } from '../../utils/aggregation';\n\ntype AggregationLabel = {\n colId: string;\n header: string;\n aggregation: ColumnAggregation;\n allValue: number;\n selectedValue: number | null;\n};\n\nconst typeLabels: Record<ColumnAggregationType, string> = {\n sum: 'Tổng',\n avg: 'Trung bình',\n count: 'Đếm',\n min: 'Nhỏ nhất',\n max: 'Lớn nhất',\n};\n\nexport const UITableAnalysisPanel = memo(() => {\n const { table, totalRows } = useUITableContext();\n const { rowSelectionState } = useUITableBodyContext();\n const { isOpen, toggle } = useUITableAnalysisContext();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: row model\n const allRows = useMemo(() => table.getRowModel().rows, [table]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: selected rows\n const selectedRows = useMemo(() => table.getSelectedRowModel().flatRows, [table, rowSelectionState]);\n\n const headers = useMemo(() => table.getHeaderGroups()[0]?.headers ?? [], [table]);\n\n const aggregationRows = useMemo<AggregationLabel[]>(() => {\n return headers\n .filter(h => !['select', 'actions'].includes(h.id))\n .flatMap(header => {\n const agg = (header.column.columnDef.meta as AnyEntity)?.aggregation as ColumnAggregation | undefined;\n if (!agg) return [];\n\n const headerText = agg.label ?? (typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.id);\n\n const allValues = extractNumericValues(allRows, header.id);\n const selectedValues = selectedRows.length > 0 ? extractNumericValues(selectedRows, header.id) : null;\n\n return [\n {\n colId: header.id,\n header: headerText,\n aggregation: agg,\n allValue: computeAggregation(allRows.length, allValues, agg.type),\n selectedValue: selectedValues !== null ? computeAggregation(selectedRows.length, selectedValues, agg.type) : null,\n },\n ];\n });\n }, [headers, allRows, selectedRows]);\n\n return (\n <div data-slot=\"table-analysis-panel\" className=\"w-full border-t border-border\">\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive',\n 'hover:bg-muted-bg-subtle transition-colors outline-none',\n 'focus-visible:ring-2 focus-visible:ring-primary-weak'\n )}\n onClick={toggle}\n aria-expanded={isOpen}\n >\n <span>Tổng quan dữ liệu</span>\n {isOpen ? <ChevronUpIcon size={14} /> : <ChevronDownIcon size={14} />}\n </button>\n\n {isOpen && (\n <div className=\"px-4 pb-4 pt-2 space-y-4\">\n {/* Row summary */}\n <div className=\"flex flex-wrap gap-4\">\n <StatChip label=\"Tổng bản ghi\" value={totalRows ?? allRows.length} />\n <StatChip label=\"Hàng hiển thị\" value={allRows.length} />\n <StatChip label=\"Hàng đã chọn\" value={selectedRows.length} highlight={selectedRows.length > 0} />\n </div>\n\n {/* Column aggregations */}\n {aggregationRows.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak\">Tóm tắt cột</p>\n <div className=\"overflow-x-auto rounded-md border border-border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak\">\n <th className=\"px-3 py-2 text-left font-medium\">Cột</th>\n <th className=\"px-3 py-2 text-left font-medium\">Kiểu</th>\n <th className=\"px-3 py-2 text-right font-medium\">Tất cả hàng</th>\n {selectedRows.length > 0 && <th className=\"px-3 py-2 text-right font-medium\">Hàng đã chọn</th>}\n </tr>\n </thead>\n <tbody>\n {aggregationRows.map((row, idx) => (\n <tr key={row.colId} className={cn('border-b border-border last:border-b-0', idx % 2 === 1 && 'bg-muted-bg-subtle/50')}>\n <td className=\"px-3 py-2 text-text-positive font-medium\">{row.header}</td>\n <td className=\"px-3 py-2 text-text-positive-weak\">{typeLabels[row.aggregation.type]}</td>\n <td className=\"px-3 py-2 text-right\">\n <Statistic\n value={row.allValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n </td>\n {selectedRows.length > 0 && (\n <td className=\"px-3 py-2 text-right\">\n {row.selectedValue !== null ? (\n <Statistic\n value={row.selectedValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n ) : (\n <span className=\"text-text-positive-weak\">—</span>\n )}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\nUITableAnalysisPanel.displayName = 'UITableAnalysisPanel';\n\nconst StatChip = memo<{ label: string; value: number; highlight?: boolean }>(({ label, value, highlight }) => (\n <div\n className={cn(\n 'flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white',\n highlight && value > 0 ? 'border-primary bg-primary-bg-subtle' : 'border-border bg-white'\n )}\n >\n <span className=\"text-[11px] text-text-positive-weak\">{label}</span>\n <span className=\"text-base font-semibold tabular-nums text-text-positive-strong\">{value.toLocaleString()}</span>\n </div>\n));\nStatChip.displayName = 'StatChip';\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Statistic as e}from"./data-display/statistic.mjs";import{B as t,J as n,Y as r,q as i,z as a}from"./tables-
|
|
2
|
-
//# sourceMappingURL=analysis-panel-
|
|
1
|
+
import{Statistic as e}from"./data-display/statistic.mjs";import{B as t,J as n,Y as r,q as i,z as a}from"./tables-Dg3KMBKA.mjs";import{ChevronDownIcon as o,ChevronUpIcon as s}from"lucide-react";import{memo as c,useMemo as l}from"react";import{cn as u}from"@customafk/react-toolkit/utils";import{jsx as d,jsxs as f}from"react/jsx-runtime";const p={sum:`Tổng`,avg:`Trung bình`,count:`Đếm`,min:`Nhỏ nhất`,max:`Lớn nhất`},m=c(()=>{let{table:c,totalRows:m}=r(),{rowSelectionState:g}=n(),{isOpen:_,toggle:v}=i(),y=l(()=>c.getRowModel().rows,[c]),b=l(()=>c.getSelectedRowModel().flatRows,[c,g]),x=l(()=>c.getHeaderGroups()[0]?.headers??[],[c]),S=l(()=>x.filter(e=>![`select`,`actions`].includes(e.id)).flatMap(e=>{let n=e.column.columnDef.meta?.aggregation;if(!n)return[];let r=n.label??(typeof e.column.columnDef.header==`string`?e.column.columnDef.header:e.id),i=t(y,e.id),o=b.length>0?t(b,e.id):null;return[{colId:e.id,header:r,aggregation:n,allValue:a(y.length,i,n.type),selectedValue:o===null?null:a(b.length,o,n.type)}]}),[x,y,b]);return f(`div`,{"data-slot":`table-analysis-panel`,className:`w-full border-t border-border`,children:[f(`button`,{type:`button`,className:u(`flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive`,`hover:bg-muted-bg-subtle transition-colors outline-none`,`focus-visible:ring-2 focus-visible:ring-primary-weak`),onClick:v,"aria-expanded":_,children:[d(`span`,{children:`Tổng quan dữ liệu`}),d(_?s:o,{size:14})]}),_&&f(`div`,{className:`px-4 pb-4 pt-2 space-y-4`,children:[f(`div`,{className:`flex flex-wrap gap-4`,children:[d(h,{label:`Tổng bản ghi`,value:m??y.length}),d(h,{label:`Hàng hiển thị`,value:y.length}),d(h,{label:`Hàng đã chọn`,value:b.length,highlight:b.length>0})]}),S.length>0&&f(`div`,{children:[d(`p`,{className:`mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak`,children:`Tóm tắt cột`}),d(`div`,{className:`overflow-x-auto rounded-md border border-border`,children:f(`table`,{className:`w-full text-sm`,children:[d(`thead`,{children:f(`tr`,{className:`border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak`,children:[d(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Cột`}),d(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Kiểu`}),d(`th`,{className:`px-3 py-2 text-right font-medium`,children:`Tất cả hàng`}),b.length>0&&d(`th`,{className:`px-3 py-2 text-right font-medium`,children:`Hàng đã chọn`})]})}),d(`tbody`,{children:S.map((t,n)=>f(`tr`,{className:u(`border-b border-border last:border-b-0`,n%2==1&&`bg-muted-bg-subtle/50`),children:[d(`td`,{className:`px-3 py-2 text-text-positive font-medium`,children:t.header}),d(`td`,{className:`px-3 py-2 text-text-positive-weak`,children:p[t.aggregation.type]}),d(`td`,{className:`px-3 py-2 text-right`,children:d(e,{value:t.allValue,prefix:t.aggregation.prefix,suffix:t.aggregation.suffix,precision:t.aggregation.precision,size:`sm`})}),b.length>0&&d(`td`,{className:`px-3 py-2 text-right`,children:t.selectedValue===null?d(`span`,{className:`text-text-positive-weak`,children:`—`}):d(e,{value:t.selectedValue,prefix:t.aggregation.prefix,suffix:t.aggregation.suffix,precision:t.aggregation.precision,size:`sm`})})]},t.colId))})]})})]})]})]})});m.displayName=`UITableAnalysisPanel`;const h=c(({label:e,value:t,highlight:n})=>f(`div`,{className:u(`flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white`,n&&t>0?`border-primary bg-primary-bg-subtle`:`border-border bg-white`),children:[d(`span`,{className:`text-[11px] text-text-positive-weak`,children:e}),d(`span`,{className:`text-base font-semibold tabular-nums text-text-positive-strong`,children:t.toLocaleString()})]}));h.displayName=`StatChip`;export{m as UITableAnalysisPanel};
|
|
2
|
+
//# sourceMappingURL=analysis-panel-CZ8g9AAO.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-panel-_s1fgcZC.mjs","names":[],"sources":["../packages/components/features/tables/components/table/analysis-panel.tsx"],"sourcesContent":["'use client';\nimport { memo, useMemo } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport type { AnyEntity } from '@/types';\nimport { useUITableAnalysisContext, useUITableBodyContext, useUITableContext } from '../../hooks/use-context';\nimport type { ColumnAggregation, ColumnAggregationType } from '../../types';\nimport { computeAggregation, extractNumericValues } from '../../utils/aggregation';\n\ntype AggregationLabel = {\n colId: string;\n header: string;\n aggregation: ColumnAggregation;\n allValue: number;\n selectedValue: number | null;\n};\n\nconst typeLabels: Record<ColumnAggregationType, string> = {\n sum: 'Tổng',\n avg: 'Trung bình',\n count: 'Đếm',\n min: 'Nhỏ nhất',\n max: 'Lớn nhất',\n};\n\nexport const UITableAnalysisPanel = memo(() => {\n const { table, totalRows } = useUITableContext();\n const { rowSelectionState } = useUITableBodyContext();\n const { isOpen, toggle } = useUITableAnalysisContext();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: row model\n const allRows = useMemo(() => table.getRowModel().rows, [table]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: selected rows\n const selectedRows = useMemo(() => table.getSelectedRowModel().flatRows, [table, rowSelectionState]);\n\n const headers = useMemo(() => table.getHeaderGroups()[0]?.headers ?? [], [table]);\n\n const aggregationRows = useMemo<AggregationLabel[]>(() => {\n return headers\n .filter(h => !['select', 'actions'].includes(h.id))\n .flatMap(header => {\n const agg = (header.column.columnDef.meta as AnyEntity)?.aggregation as ColumnAggregation | undefined;\n if (!agg) return [];\n\n const headerText = agg.label ?? (typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.id);\n\n const allValues = extractNumericValues(allRows, header.id);\n const selectedValues = selectedRows.length > 0 ? extractNumericValues(selectedRows, header.id) : null;\n\n return [\n {\n colId: header.id,\n header: headerText,\n aggregation: agg,\n allValue: computeAggregation(allRows.length, allValues, agg.type),\n selectedValue: selectedValues !== null ? computeAggregation(selectedRows.length, selectedValues, agg.type) : null,\n },\n ];\n });\n }, [headers, allRows, selectedRows]);\n\n return (\n <div data-slot=\"table-analysis-panel\" className=\"w-full border-t border-border\">\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive',\n 'hover:bg-muted-bg-subtle transition-colors outline-none',\n 'focus-visible:ring-2 focus-visible:ring-primary-weak'\n )}\n onClick={toggle}\n aria-expanded={isOpen}\n >\n <span>Tổng quan dữ liệu</span>\n {isOpen ? <ChevronUpIcon size={14} /> : <ChevronDownIcon size={14} />}\n </button>\n\n {isOpen && (\n <div className=\"px-4 pb-4 pt-2 space-y-4\">\n {/* Row summary */}\n <div className=\"flex flex-wrap gap-4\">\n <StatChip label=\"Tổng bản ghi\" value={totalRows ?? allRows.length} />\n <StatChip label=\"Hàng hiển thị\" value={allRows.length} />\n <StatChip label=\"Hàng đã chọn\" value={selectedRows.length} highlight={selectedRows.length > 0} />\n </div>\n\n {/* Column aggregations */}\n {aggregationRows.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak\">Tóm tắt cột</p>\n <div className=\"overflow-x-auto rounded-md border border-border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak\">\n <th className=\"px-3 py-2 text-left font-medium\">Cột</th>\n <th className=\"px-3 py-2 text-left font-medium\">Kiểu</th>\n <th className=\"px-3 py-2 text-right font-medium\">Tất cả hàng</th>\n {selectedRows.length > 0 && <th className=\"px-3 py-2 text-right font-medium\">Hàng đã chọn</th>}\n </tr>\n </thead>\n <tbody>\n {aggregationRows.map((row, idx) => (\n <tr key={row.colId} className={cn('border-b border-border last:border-b-0', idx % 2 === 1 && 'bg-muted-bg-subtle/50')}>\n <td className=\"px-3 py-2 text-text-positive font-medium\">{row.header}</td>\n <td className=\"px-3 py-2 text-text-positive-weak\">{typeLabels[row.aggregation.type]}</td>\n <td className=\"px-3 py-2 text-right\">\n <Statistic\n value={row.allValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n </td>\n {selectedRows.length > 0 && (\n <td className=\"px-3 py-2 text-right\">\n {row.selectedValue !== null ? (\n <Statistic\n value={row.selectedValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n ) : (\n <span className=\"text-text-positive-weak\">—</span>\n )}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\nUITableAnalysisPanel.displayName = 'UITableAnalysisPanel';\n\nconst StatChip = memo<{ label: string; value: number; highlight?: boolean }>(({ label, value, highlight }) => (\n <div\n className={cn(\n 'flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white',\n highlight && value > 0 ? 'border-primary bg-primary-bg-subtle' : 'border-border bg-white'\n )}\n >\n <span className=\"text-[11px] text-text-positive-weak\">{label}</span>\n <span className=\"text-base font-semibold tabular-nums text-text-positive-strong\">{value.toLocaleString()}</span>\n </div>\n));\nStatChip.displayName = 'StatChip';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analysis-panel-CZ8g9AAO.mjs","names":[],"sources":["../packages/components/features/tables/components/table/analysis-panel.tsx"],"sourcesContent":["'use client';\nimport { memo, useMemo } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Statistic } from '@/components/data-display/statistic';\nimport type { AnyEntity } from '@/types';\nimport { useUITableAnalysisContext, useUITableBodyContext, useUITableContext } from '../../hooks/use-context';\nimport type { ColumnAggregation, ColumnAggregationType } from '../../types';\nimport { computeAggregation, extractNumericValues } from '../../utils/aggregation';\n\ntype AggregationLabel = {\n colId: string;\n header: string;\n aggregation: ColumnAggregation;\n allValue: number;\n selectedValue: number | null;\n};\n\nconst typeLabels: Record<ColumnAggregationType, string> = {\n sum: 'Tổng',\n avg: 'Trung bình',\n count: 'Đếm',\n min: 'Nhỏ nhất',\n max: 'Lớn nhất',\n};\n\nexport const UITableAnalysisPanel = memo(() => {\n const { table, totalRows } = useUITableContext();\n const { rowSelectionState } = useUITableBodyContext();\n const { isOpen, toggle } = useUITableAnalysisContext();\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: row model\n const allRows = useMemo(() => table.getRowModel().rows, [table]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: selected rows\n const selectedRows = useMemo(() => table.getSelectedRowModel().flatRows, [table, rowSelectionState]);\n\n const headers = useMemo(() => table.getHeaderGroups()[0]?.headers ?? [], [table]);\n\n const aggregationRows = useMemo<AggregationLabel[]>(() => {\n return headers\n .filter(h => !['select', 'actions'].includes(h.id))\n .flatMap(header => {\n const agg = (header.column.columnDef.meta as AnyEntity)?.aggregation as ColumnAggregation | undefined;\n if (!agg) return [];\n\n const headerText = agg.label ?? (typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.id);\n\n const allValues = extractNumericValues(allRows, header.id);\n const selectedValues = selectedRows.length > 0 ? extractNumericValues(selectedRows, header.id) : null;\n\n return [\n {\n colId: header.id,\n header: headerText,\n aggregation: agg,\n allValue: computeAggregation(allRows.length, allValues, agg.type),\n selectedValue: selectedValues !== null ? computeAggregation(selectedRows.length, selectedValues, agg.type) : null,\n },\n ];\n });\n }, [headers, allRows, selectedRows]);\n\n return (\n <div data-slot=\"table-analysis-panel\" className=\"w-full border-t border-border\">\n <button\n type=\"button\"\n className={cn(\n 'flex w-full items-center justify-between px-4 py-2 text-sm font-medium text-text-positive',\n 'hover:bg-muted-bg-subtle transition-colors outline-none',\n 'focus-visible:ring-2 focus-visible:ring-primary-weak'\n )}\n onClick={toggle}\n aria-expanded={isOpen}\n >\n <span>Tổng quan dữ liệu</span>\n {isOpen ? <ChevronUpIcon size={14} /> : <ChevronDownIcon size={14} />}\n </button>\n\n {isOpen && (\n <div className=\"px-4 pb-4 pt-2 space-y-4\">\n {/* Row summary */}\n <div className=\"flex flex-wrap gap-4\">\n <StatChip label=\"Tổng bản ghi\" value={totalRows ?? allRows.length} />\n <StatChip label=\"Hàng hiển thị\" value={allRows.length} />\n <StatChip label=\"Hàng đã chọn\" value={selectedRows.length} highlight={selectedRows.length > 0} />\n </div>\n\n {/* Column aggregations */}\n {aggregationRows.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-wide text-text-positive-weak\">Tóm tắt cột</p>\n <div className=\"overflow-x-auto rounded-md border border-border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border bg-muted-bg-subtle text-xs text-text-positive-weak\">\n <th className=\"px-3 py-2 text-left font-medium\">Cột</th>\n <th className=\"px-3 py-2 text-left font-medium\">Kiểu</th>\n <th className=\"px-3 py-2 text-right font-medium\">Tất cả hàng</th>\n {selectedRows.length > 0 && <th className=\"px-3 py-2 text-right font-medium\">Hàng đã chọn</th>}\n </tr>\n </thead>\n <tbody>\n {aggregationRows.map((row, idx) => (\n <tr key={row.colId} className={cn('border-b border-border last:border-b-0', idx % 2 === 1 && 'bg-muted-bg-subtle/50')}>\n <td className=\"px-3 py-2 text-text-positive font-medium\">{row.header}</td>\n <td className=\"px-3 py-2 text-text-positive-weak\">{typeLabels[row.aggregation.type]}</td>\n <td className=\"px-3 py-2 text-right\">\n <Statistic\n value={row.allValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n </td>\n {selectedRows.length > 0 && (\n <td className=\"px-3 py-2 text-right\">\n {row.selectedValue !== null ? (\n <Statistic\n value={row.selectedValue}\n prefix={row.aggregation.prefix}\n suffix={row.aggregation.suffix}\n precision={row.aggregation.precision}\n size=\"sm\"\n />\n ) : (\n <span className=\"text-text-positive-weak\">—</span>\n )}\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\nUITableAnalysisPanel.displayName = 'UITableAnalysisPanel';\n\nconst StatChip = memo<{ label: string; value: number; highlight?: boolean }>(({ label, value, highlight }) => (\n <div\n className={cn(\n 'flex flex-col gap-0.5 rounded border px-3 py-2 min-w-25 bg-white',\n highlight && value > 0 ? 'border-primary bg-primary-bg-subtle' : 'border-border bg-white'\n )}\n >\n <span className=\"text-[11px] text-text-positive-weak\">{label}</span>\n <span className=\"text-base font-semibold tabular-nums text-text-positive-strong\">{value.toLocaleString()}</span>\n </div>\n));\nStatChip.displayName = 'StatChip';\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
2
2
|
//#region packages/components/ui/badge.d.ts
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
4
|
variant?: "solid" | "soft" | "outline" | null | undefined;
|
|
5
|
-
color?: "
|
|
5
|
+
color?: "primary" | "secondary" | "muted" | "accent" | "info" | "success" | "warning" | "danger" | null | undefined;
|
|
6
6
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
|
|
7
7
|
pill?: boolean | null | undefined;
|
|
8
8
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -29,4 +29,4 @@ type BadgeProps = VariantProps<typeof badgeVariants> & React.ComponentPropsWitho
|
|
|
29
29
|
declare function Badge({ className, variant, color, size, pill, ...props }: BadgeProps): import("react").JSX.Element;
|
|
30
30
|
//#endregion
|
|
31
31
|
export { BadgeProps as n, badgeVariants as r, Badge as t };
|
|
32
|
-
//# sourceMappingURL=badge-
|
|
32
|
+
//# sourceMappingURL=badge-BPiU1Ss2.d.cts.map
|
|
@@ -2,7 +2,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
2
2
|
//#region packages/components/ui/badge.d.ts
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
4
|
variant?: "solid" | "soft" | "outline" | null | undefined;
|
|
5
|
-
color?: "
|
|
5
|
+
color?: "primary" | "secondary" | "muted" | "accent" | "info" | "success" | "warning" | "danger" | null | undefined;
|
|
6
6
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
|
|
7
7
|
pill?: boolean | null | undefined;
|
|
8
8
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -29,4 +29,4 @@ type BadgeProps = VariantProps<typeof badgeVariants> & React.ComponentPropsWitho
|
|
|
29
29
|
declare function Badge({ className, variant, color, size, pill, ...props }: BadgeProps): import("react").JSX.Element;
|
|
30
30
|
//#endregion
|
|
31
31
|
export { BadgeProps as n, badgeVariants as r, Badge as t };
|
|
32
|
-
//# sourceMappingURL=badge-
|
|
32
|
+
//# sourceMappingURL=badge-BPiU1Ss2.d.mts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Q as e}from"./tables-
|
|
2
|
-
//# sourceMappingURL=badge-display-
|
|
1
|
+
import{Q as e}from"./tables-Dg3KMBKA.mjs";import{XIcon as t}from"lucide-react";import{jsx as n,jsxs as r}from"react/jsx-runtime";const i=({label:i,onClick:a,onRemove:o})=>i?o?r(`div`,{className:`flex w-fit gap-x-0.5 rounded-full border border-border py-1 pr-2 pl-3 text-text-positive text-xs shadow-xs`,onClick:e=>{a?.(),e.stopPropagation(),e.preventDefault()},children:[i,n(`button`,{className:`cursor-pointer text-text-positive-weak hover:text-text-positive-strong`,onClick:e=>{o?.(),e.stopPropagation(),e.preventDefault()},children:n(t,{size:12})})]}):n(`button`,{className:`w-fit rounded-full border border-border px-3 py-1 text-text-positive text-xs shadow-xs`,onClick:e=>{a?.(),e.stopPropagation(),e.preventDefault()},children:i}):n(e,{});export{i as UITableBadgeDisplay};
|
|
2
|
+
//# sourceMappingURL=badge-display-B5m09_Hs.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge-display-
|
|
1
|
+
{"version":3,"file":"badge-display-B5m09_Hs.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/badge-display.tsx"],"sourcesContent":["import { XIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders a pill-shaped badge for a table cell that optionally supports a click\n * action and an inline remove button; falls back to {@link UITableEmpty} when\n * `label` is falsy.\n *\n * @example\n * import { UITableBadgeDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableBadgeDisplay\n * label=\"Active\"\n * onClick={() => console.log('badge clicked')}\n * onRemove={() => console.log('remove clicked')}\n * />\n */\nexport const UITableBadgeDisplay: React.FC<{\n /** The text or number to display inside the badge. */\n label: string | number | null | undefined;\n /** Optional callback fired when the badge itself is clicked. */\n onClick?: () => void;\n /** When provided, renders a remove (×) button and fires this callback on click. */\n onRemove?: () => void;\n}> = ({ label, onClick, onRemove }) => {\n if (!label) return <UITableEmpty />;\n if (onRemove) {\n return (\n <div\n className=\"flex w-fit gap-x-0.5 rounded-full border border-border py-1 pr-2 pl-3 text-text-positive text-xs shadow-xs\"\n onClick={e => {\n onClick?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {label}\n <button\n className=\"cursor-pointer text-text-positive-weak hover:text-text-positive-strong\"\n onClick={e => {\n onRemove?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <XIcon size={12} />\n </button>\n </div>\n );\n }\n return (\n <button\n className=\"w-fit rounded-full border border-border px-3 py-1 text-text-positive text-xs shadow-xs\"\n onClick={e => {\n onClick?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {label}\n </button>\n );\n};\n"],"mappings":"iIAkBA,MAAa,GAOP,CAAE,QAAO,UAAS,cACjB,EACD,EAEA,EAAC,MAAD,CACE,UAAU,6GACV,QAAS,GAAK,CACZ,IAAU,EACV,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EANF,SAAA,CAQG,EACD,EAAC,SAAD,CACE,UAAU,yEACV,QAAS,GAAK,CACZ,IAAW,EACX,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EAEA,SAAA,EAAC,EAAD,CAAO,KAAM,EAAK,CAAA,CACZ,CAAA,CACL,IAIP,EAAC,SAAD,CACE,UAAU,yFACV,QAAS,GAAK,CACZ,IAAU,EACV,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EAEC,SAAA,CACK,CAAA,EAnCS,EAAC,EAAD,CAAe,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./tables-
|
|
2
|
-
//# sourceMappingURL=badge-display-
|
|
1
|
+
const e=require("./tables-BqZ4Zs6e.cjs");let t=require("lucide-react"),n=require("react/jsx-runtime");const r=({label:r,onClick:i,onRemove:a})=>r?a?(0,n.jsxs)(`div`,{className:`flex w-fit gap-x-0.5 rounded-full border border-border py-1 pr-2 pl-3 text-text-positive text-xs shadow-xs`,onClick:e=>{i?.(),e.stopPropagation(),e.preventDefault()},children:[r,(0,n.jsx)(`button`,{className:`cursor-pointer text-text-positive-weak hover:text-text-positive-strong`,onClick:e=>{a?.(),e.stopPropagation(),e.preventDefault()},children:(0,n.jsx)(t.XIcon,{size:12})})]}):(0,n.jsx)(`button`,{className:`w-fit rounded-full border border-border px-3 py-1 text-text-positive text-xs shadow-xs`,onClick:e=>{i?.(),e.stopPropagation(),e.preventDefault()},children:r}):(0,n.jsx)(e.Q,{});exports.UITableBadgeDisplay=r;
|
|
2
|
+
//# sourceMappingURL=badge-display-DHbCN998.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge-display-
|
|
1
|
+
{"version":3,"file":"badge-display-DHbCN998.cjs","names":["UITableEmpty","XIcon"],"sources":["../packages/components/features/tables/components/atoms/badge-display.tsx"],"sourcesContent":["import { XIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\n/**\n * Renders a pill-shaped badge for a table cell that optionally supports a click\n * action and an inline remove button; falls back to {@link UITableEmpty} when\n * `label` is falsy.\n *\n * @example\n * import { UITableBadgeDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableBadgeDisplay\n * label=\"Active\"\n * onClick={() => console.log('badge clicked')}\n * onRemove={() => console.log('remove clicked')}\n * />\n */\nexport const UITableBadgeDisplay: React.FC<{\n /** The text or number to display inside the badge. */\n label: string | number | null | undefined;\n /** Optional callback fired when the badge itself is clicked. */\n onClick?: () => void;\n /** When provided, renders a remove (×) button and fires this callback on click. */\n onRemove?: () => void;\n}> = ({ label, onClick, onRemove }) => {\n if (!label) return <UITableEmpty />;\n if (onRemove) {\n return (\n <div\n className=\"flex w-fit gap-x-0.5 rounded-full border border-border py-1 pr-2 pl-3 text-text-positive text-xs shadow-xs\"\n onClick={e => {\n onClick?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {label}\n <button\n className=\"cursor-pointer text-text-positive-weak hover:text-text-positive-strong\"\n onClick={e => {\n onRemove?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <XIcon size={12} />\n </button>\n </div>\n );\n }\n return (\n <button\n className=\"w-fit rounded-full border border-border px-3 py-1 text-text-positive text-xs shadow-xs\"\n onClick={e => {\n onClick?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {label}\n </button>\n );\n};\n"],"mappings":"sGAkBA,MAAa,GAOP,CAAE,QAAO,UAAS,cACjB,EACD,GAEA,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAU,6GACV,QAAS,GAAK,CACZ,IAAU,EACV,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EANF,SAAA,CAQG,GACD,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,UAAU,yEACV,QAAS,GAAK,CACZ,IAAW,EACX,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EAEA,UAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAO,KAAM,EAAK,CAAA,CACZ,CAAA,CACL,KAIP,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,UAAU,yFACV,QAAS,GAAK,CACZ,IAAU,EACV,EAAE,gBAAgB,EAClB,EAAE,eAAe,CACnB,EAEC,SAAA,CACK,CAAA,GAnCS,EAAA,EAAA,IAAA,CAACD,EAAAA,EAAD,CAAe,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Q as e}from"./tables-
|
|
2
|
-
//# sourceMappingURL=boolean-display-
|
|
1
|
+
import{Q as e}from"./tables-Dg3KMBKA.mjs";import{CheckIcon as t,XIcon as n}from"lucide-react";import{jsx as r}from"react/jsx-runtime";const i=({value:i})=>i==null?r(e,{}):i===!1?r(n,{size:14,strokeWidth:2,className:`text-danger-strong`}):r(t,{size:14,strokeWidth:2,className:`text-success-strong`});export{i as UITableBooleanDisplay};
|
|
2
|
+
//# sourceMappingURL=boolean-display-CzHHDfHW.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boolean-display-
|
|
1
|
+
{"version":3,"file":"boolean-display-CzHHDfHW.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/boolean-display.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\nexport const UITableBooleanDisplay: React.FC<{\n value: boolean | null | undefined;\n}> = ({ value }) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n if (value === false) {\n return <XIcon size={14} strokeWidth={2} className=\"text-danger-strong\" />;\n }\n return <CheckIcon size={14} strokeWidth={2} className=\"text-success-strong\" />;\n};\n"],"mappings":"sIAIA,MAAa,GAEP,CAAE,WACF,GAAU,KAAoC,EAAC,EAAD,CAAe,CAAA,EAC7D,IAAU,GACL,EAAC,EAAD,CAAO,KAAM,GAAI,YAAa,EAAG,UAAU,oBAAsB,CAAA,EAEnE,EAAC,EAAD,CAAW,KAAM,GAAI,YAAa,EAAG,UAAU,qBAAuB,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./tables-
|
|
2
|
-
//# sourceMappingURL=boolean-display-
|
|
1
|
+
const e=require("./tables-BqZ4Zs6e.cjs");let t=require("lucide-react"),n=require("react/jsx-runtime");const r=({value:r})=>r==null?(0,n.jsx)(e.Q,{}):r===!1?(0,n.jsx)(t.XIcon,{size:14,strokeWidth:2,className:`text-danger-strong`}):(0,n.jsx)(t.CheckIcon,{size:14,strokeWidth:2,className:`text-success-strong`});exports.UITableBooleanDisplay=r;
|
|
2
|
+
//# sourceMappingURL=boolean-display-D2wjQhNX.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boolean-display-
|
|
1
|
+
{"version":3,"file":"boolean-display-D2wjQhNX.cjs","names":["UITableEmpty","XIcon","CheckIcon"],"sources":["../packages/components/features/tables/components/atoms/boolean-display.tsx"],"sourcesContent":["import { CheckIcon, XIcon } from 'lucide-react';\n\nimport { UITableEmpty } from './empty';\n\nexport const UITableBooleanDisplay: React.FC<{\n value: boolean | null | undefined;\n}> = ({ value }) => {\n if (value === null || value === undefined) return <UITableEmpty />;\n if (value === false) {\n return <XIcon size={14} strokeWidth={2} className=\"text-danger-strong\" />;\n }\n return <CheckIcon size={14} strokeWidth={2} className=\"text-success-strong\" />;\n};\n"],"mappings":"sGAIA,MAAa,GAEP,CAAE,WACF,GAAU,MAAoC,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,EAC7D,IAAU,IACL,EAAA,EAAA,IAAA,CAACC,EAAAA,MAAD,CAAO,KAAM,GAAI,YAAa,EAAG,UAAU,oBAAsB,CAAA,GAEnE,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,KAAM,GAAI,YAAa,EAAG,UAAU,qBAAuB,CAAA"}
|
|
@@ -4,8 +4,8 @@ import { VariantProps } from "class-variance-authority";
|
|
|
4
4
|
* Button variants definition for styling using class-variance-authority
|
|
5
5
|
*/
|
|
6
6
|
declare const buttonVariants: (props?: ({
|
|
7
|
-
variant?: "default" | "
|
|
8
|
-
color?: "
|
|
7
|
+
variant?: "default" | "soft" | "outline" | "link" | "ghost" | "subtle" | null | undefined;
|
|
8
|
+
color?: "primary" | "secondary" | "muted" | "info" | "success" | "warning" | "danger" | "important" | null | undefined;
|
|
9
9
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "default" | "icon" | null | undefined;
|
|
10
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
11
|
type ButtonVariantProps = VariantProps<typeof buttonVariants>;
|
|
@@ -155,4 +155,4 @@ interface ButtonProps extends Omit<React.ComponentProps<'button'>, 'color'> {
|
|
|
155
155
|
declare function Button({ className, variant, size, color, asChild, isLoading, children, disabled, type, innerClassName, ...props }: ButtonProps): import("react").JSX.Element;
|
|
156
156
|
//#endregion
|
|
157
157
|
export { ButtonProps as n, Button as t };
|
|
158
|
-
//# sourceMappingURL=button-
|
|
158
|
+
//# sourceMappingURL=button-BnoPktln.d.cts.map
|
|
@@ -4,8 +4,8 @@ import { VariantProps } from "class-variance-authority";
|
|
|
4
4
|
* Button variants definition for styling using class-variance-authority
|
|
5
5
|
*/
|
|
6
6
|
declare const buttonVariants: (props?: ({
|
|
7
|
-
variant?: "default" | "
|
|
8
|
-
color?: "
|
|
7
|
+
variant?: "default" | "soft" | "outline" | "link" | "ghost" | "subtle" | null | undefined;
|
|
8
|
+
color?: "primary" | "secondary" | "muted" | "info" | "success" | "warning" | "danger" | "important" | null | undefined;
|
|
9
9
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "default" | "icon" | null | undefined;
|
|
10
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
11
|
type ButtonVariantProps = VariantProps<typeof buttonVariants>;
|
|
@@ -155,4 +155,4 @@ interface ButtonProps extends Omit<React.ComponentProps<'button'>, 'color'> {
|
|
|
155
155
|
declare function Button({ className, variant, size, color, asChild, isLoading, children, disabled, type, innerClassName, ...props }: ButtonProps): import("react").JSX.Element;
|
|
156
156
|
//#endregion
|
|
157
157
|
export { ButtonProps as n, Button as t };
|
|
158
|
-
//# sourceMappingURL=button-
|
|
158
|
+
//# sourceMappingURL=button-BnoPktln.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "./button-
|
|
1
|
+
import { t as Button } from "./button-BnoPktln.mjs";
|
|
2
2
|
import { DayButton, DayPicker } from "react-day-picker";
|
|
3
3
|
//#region packages/components/ui/calendar.d.ts
|
|
4
4
|
declare const CalendarDayButton: ({ className, day, modifiers, color: _, ...props }: React.ComponentProps<typeof DayButton>) => import("react").JSX.Element;
|
|
@@ -25,4 +25,4 @@ declare function Calendar({ className, classNames, showOutsideDays, captionLayou
|
|
|
25
25
|
}): import("react").JSX.Element;
|
|
26
26
|
//#endregion
|
|
27
27
|
export { CalendarDayButton as n, Calendar as t };
|
|
28
|
-
//# sourceMappingURL=calendar-
|
|
28
|
+
//# sourceMappingURL=calendar-BkV5hTX2.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "./button-
|
|
1
|
+
import { t as Button } from "./button-BnoPktln.cjs";
|
|
2
2
|
import { DayButton, DayPicker } from "react-day-picker";
|
|
3
3
|
//#region packages/components/ui/calendar.d.ts
|
|
4
4
|
declare const CalendarDayButton: ({ className, day, modifiers, color: _, ...props }: React.ComponentProps<typeof DayButton>) => import("react").JSX.Element;
|
|
@@ -25,4 +25,4 @@ declare function Calendar({ className, classNames, showOutsideDays, captionLayou
|
|
|
25
25
|
}): import("react").JSX.Element;
|
|
26
26
|
//#endregion
|
|
27
27
|
export { CalendarDayButton as n, Calendar as t };
|
|
28
|
-
//# sourceMappingURL=calendar-
|
|
28
|
+
//# sourceMappingURL=calendar-iDMPT1kI.d.cts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "./button-
|
|
1
|
+
import { t as Button } from "./button-BnoPktln.mjs";
|
|
2
2
|
import useEmblaCarousel, { UseEmblaCarouselType } from "embla-carousel-react";
|
|
3
3
|
//#region packages/components/ui/carousel.d.ts
|
|
4
4
|
type CarouselApi = UseEmblaCarouselType[1];
|
|
@@ -42,4 +42,4 @@ declare function CarouselPrevious({ className, variant, size, ...props }: React.
|
|
|
42
42
|
declare function CarouselNext({ className, variant, size, ...props }: React.ComponentProps<typeof Button>): import("react").JSX.Element;
|
|
43
43
|
//#endregion
|
|
44
44
|
export { CarouselNext as a, CarouselItem as i, CarouselApi as n, CarouselPrevious as o, CarouselContent as r, Carousel as t };
|
|
45
|
-
//# sourceMappingURL=carousel-
|
|
45
|
+
//# sourceMappingURL=carousel-D7VXWJ3S.d.mts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "./button-
|
|
1
|
+
import { t as Button } from "./button-BnoPktln.cjs";
|
|
2
2
|
import useEmblaCarousel, { UseEmblaCarouselType } from "embla-carousel-react";
|
|
3
3
|
//#region packages/components/ui/carousel.d.ts
|
|
4
4
|
type CarouselApi = UseEmblaCarouselType[1];
|
|
@@ -42,4 +42,4 @@ declare function CarouselPrevious({ className, variant, size, ...props }: React.
|
|
|
42
42
|
declare function CarouselNext({ className, variant, size, ...props }: React.ComponentProps<typeof Button>): import("react").JSX.Element;
|
|
43
43
|
//#endregion
|
|
44
44
|
export { CarouselNext as a, CarouselItem as i, CarouselApi as n, CarouselPrevious as o, CarouselContent as r, Carousel as t };
|
|
45
|
-
//# sourceMappingURL=carousel-
|
|
45
|
+
//# sourceMappingURL=carousel-bBvM31sh.d.cts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Q as e}from"./tables-Dg3KMBKA.mjs";import{memo as t,useMemo as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{jsx as i}from"react/jsx-runtime";const a=t(({value:t,currency:a=`USD`,locale:o=`en-US`,display:s=`symbol`,size:c=`md`,colorize:l=!1,trend:u})=>{let d=n(()=>{let e=typeof t==`string`?Number(t.trim()):t;return e==null||Number.isNaN(e)||!Number.isFinite(e)?null:new Intl.NumberFormat(o,{style:`currency`,currency:a,currencyDisplay:s,minimumFractionDigits:0,maximumFractionDigits:0}).format(e)},[t,a,o,s]),f=n(()=>{if(u)return u;if(!l)return;let e=typeof t==`string`?Number(t.trim()):t;if(!(typeof e!=`number`||Number.isNaN(e)))return e<0?`down`:e>0?`up`:`neutral`},[u,l,t]);return d?i(`p`,{className:r(`font-number tabular-nums`,c===`xs`&&`text-xs`,c===`sm`&&`text-sm`,c===`md`&&`text-base`,c===`lg`&&`text-lg`,c===`xl`&&`text-xl`,!f&&`text-text-positive`,f===`down`&&`text-danger-strong`,f===`up`&&`text-success-strong`,f===`neutral`&&`text-text-positive`),children:d}):i(e,{})});a.displayName=`UITableCurrencyDisplay`;export{a as UITableCurrencyDisplay};
|
|
2
|
+
//# sourceMappingURL=currency-display-7w-ZjVUw.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency-display-7w-ZjVUw.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/currency-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useMemo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableCurrencyDisplay} component. */\ntype Props = {\n /** The numeric value to format as currency; falsy / `NaN` renders an empty state. */\n value: number | string | null | undefined;\n /** ISO 4217 currency code (default: `'USD'`). */\n currency?: string;\n /**\n * BCP 47 locale used for number formatting (default: `'en-US'`).\n * Controls digit grouping and decimal separators.\n */\n locale?: string;\n /** How to display the currency symbol — `'symbol'` (default), `'code'`, or `'name'`. */\n display?: 'symbol' | 'code' | 'name';\n /** Font-size variant (default: `'md'`). */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\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 expense 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 * Formats a numeric value as a locale-aware currency string in a table cell.\n * Always shows exactly two decimal places and uses the browser's `Intl` API for\n * symbol placement. Renders {@link UITableEmpty} when the value is absent or\n * invalid.\n *\n * @example\n * import { UITableCurrencyDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableCurrencyDisplay value={1234.5} currency=\"USD\" colorize />\n * <UITableCurrencyDisplay value={9800.5} currency=\"USD\" trend=\"down\" />\n */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false, trend }: Props) => {\n const formatted = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n if (num === null || num === undefined || Number.isNaN(num) || !Number.isFinite(num)) return null;\n\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n currencyDisplay: display,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(num);\n }, [value, currency, locale, display]);\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 (!formatted) return <UITableEmpty />;\n\n return (\n <p\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-strong',\n effectiveTrend === 'up' && 'text-success-strong',\n effectiveTrend === 'neutral' && 'text-text-positive'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"gLA6CA,MAAa,EAAyB,GAAM,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,GAAO,WAAmB,CAC7J,IAAM,EAAY,MAAc,CAC9B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAG/D,OAFI,GAAQ,MAA6B,OAAO,MAAM,CAAG,GAAK,CAAC,OAAO,SAAS,CAAG,EAAU,KAErF,IAAI,KAAK,aAAa,EAAQ,CACnC,MAAO,WACP,WACA,gBAAiB,EACjB,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,CAAC,CAAC,OAAO,CAAG,CACf,EAAG,CAAC,EAAO,EAAU,EAAQ,CAAO,CAAC,EAE/B,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,EAI3B,OAFK,EAGH,EAAC,IAAD,CACE,UAAW,EACT,2BACA,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,YACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,CAAC,GAAkB,qBACnB,IAAmB,QAAU,qBAC7B,IAAmB,MAAQ,sBAC3B,IAAmB,WAAa,oBAClC,EAEC,SAAA,CACA,CAAA,EAlBkB,EAAC,EAAD,CAAe,CAAA,CAoBxC,CAAC,EACD,EAAuB,YAAc"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./tables-BqZ4Zs6e.cjs");let t=require("react"),n=require("@customafk/react-toolkit/utils"),r=require("react/jsx-runtime");const i=(0,t.memo)(({value:i,currency:a=`USD`,locale:o=`en-US`,display:s=`symbol`,size:c=`md`,colorize:l=!1,trend:u})=>{let d=(0,t.useMemo)(()=>{let e=typeof i==`string`?Number(i.trim()):i;return e==null||Number.isNaN(e)||!Number.isFinite(e)?null:new Intl.NumberFormat(o,{style:`currency`,currency:a,currencyDisplay:s,minimumFractionDigits:0,maximumFractionDigits:0}).format(e)},[i,a,o,s]),f=(0,t.useMemo)(()=>{if(u)return u;if(!l)return;let e=typeof i==`string`?Number(i.trim()):i;if(!(typeof e!=`number`||Number.isNaN(e)))return e<0?`down`:e>0?`up`:`neutral`},[u,l,i]);return d?(0,r.jsx)(`p`,{className:(0,n.cn)(`font-number tabular-nums`,c===`xs`&&`text-xs`,c===`sm`&&`text-sm`,c===`md`&&`text-base`,c===`lg`&&`text-lg`,c===`xl`&&`text-xl`,!f&&`text-text-positive`,f===`down`&&`text-danger-strong`,f===`up`&&`text-success-strong`,f===`neutral`&&`text-text-positive`),children:d}):(0,r.jsx)(e.Q,{})});i.displayName=`UITableCurrencyDisplay`,exports.UITableCurrencyDisplay=i;
|
|
2
|
+
//# sourceMappingURL=currency-display-B06kc2IG.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currency-display-B06kc2IG.cjs","names":["UITableEmpty"],"sources":["../packages/components/features/tables/components/atoms/currency-display.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useMemo } from 'react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableCurrencyDisplay} component. */\ntype Props = {\n /** The numeric value to format as currency; falsy / `NaN` renders an empty state. */\n value: number | string | null | undefined;\n /** ISO 4217 currency code (default: `'USD'`). */\n currency?: string;\n /**\n * BCP 47 locale used for number formatting (default: `'en-US'`).\n * Controls digit grouping and decimal separators.\n */\n locale?: string;\n /** How to display the currency symbol — `'symbol'` (default), `'code'`, or `'name'`. */\n display?: 'symbol' | 'code' | 'name';\n /** Font-size variant (default: `'md'`). */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\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 expense 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 * Formats a numeric value as a locale-aware currency string in a table cell.\n * Always shows exactly two decimal places and uses the browser's `Intl` API for\n * symbol placement. Renders {@link UITableEmpty} when the value is absent or\n * invalid.\n *\n * @example\n * import { UITableCurrencyDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableCurrencyDisplay value={1234.5} currency=\"USD\" colorize />\n * <UITableCurrencyDisplay value={9800.5} currency=\"USD\" trend=\"down\" />\n */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false, trend }: Props) => {\n const formatted = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n if (num === null || num === undefined || Number.isNaN(num) || !Number.isFinite(num)) return null;\n\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n currencyDisplay: display,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n }).format(num);\n }, [value, currency, locale, display]);\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 (!formatted) return <UITableEmpty />;\n\n return (\n <p\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-strong',\n effectiveTrend === 'up' && 'text-success-strong',\n effectiveTrend === 'neutral' && 'text-text-positive'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"2IA6CA,MAAa,GAAA,EAAA,EAAA,KAAA,EAA+B,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,GAAO,WAAmB,CAC7J,IAAM,GAAA,EAAA,EAAA,QAAA,KAA0B,CAC9B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAG/D,OAFI,GAAQ,MAA6B,OAAO,MAAM,CAAG,GAAK,CAAC,OAAO,SAAS,CAAG,EAAU,KAErF,IAAI,KAAK,aAAa,EAAQ,CACnC,MAAO,WACP,WACA,gBAAiB,EACjB,sBAAuB,EACvB,sBAAuB,CACzB,CAAC,CAAC,CAAC,OAAO,CAAG,CACf,EAAG,CAAC,EAAO,EAAU,EAAQ,CAAO,CAAC,EAE/B,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,EAI3B,OAFK,GAGH,EAAA,EAAA,IAAA,CAAC,IAAD,CACE,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,qBAC7B,IAAmB,MAAQ,sBAC3B,IAAmB,WAAa,oBAClC,EAEC,SAAA,CACA,CAAA,GAlBkB,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,CAoBxC,CAAC,EACD,EAAuB,YAAc"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"./date-Nsz0Pewe.mjs";import{Tooltip as t,TooltipContent as n,TooltipProvider as r,TooltipTrigger as i}from"./ui/tooltip.mjs";import{Q as a}from"./tables-
|
|
2
|
-
//# sourceMappingURL=date-display-
|
|
1
|
+
import{t as e}from"./date-Nsz0Pewe.mjs";import{Tooltip as t,TooltipContent as n,TooltipProvider as r,TooltipTrigger as i}from"./ui/tooltip.mjs";import{Q as a}from"./tables-Dg3KMBKA.mjs";import{jsx as o,jsxs as s}from"react/jsx-runtime";const c=({date:c})=>c==null?o(a,{}):o(r,{children:s(t,{children:[o(i,{asChild:!0,children:o(e,{date:c,format:`medium`})}),o(n,{className:`rounded px-2`,children:o(e,{date:c,format:`full`,showTime:!0,className:`font-medium text-text-negative text-xs`})})]})});export{c as UITableDateDisplay};
|
|
2
|
+
//# sourceMappingURL=date-display-BO7OY_AC.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-display-
|
|
1
|
+
{"version":3,"file":"date-display-BO7OY_AC.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/date-display.tsx"],"sourcesContent":["// import { Badge } from '@/components/ui/badge';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { DateDisplay } from '@/components/data-display/date';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableDateDisplay} component. */\ntype Props = {\n /** The date value to format and display; `null`/`undefined` renders an empty state. */\n date: Date | string | number | null | undefined;\n};\n\n/**\n * Displays a date as a compact badge in a table cell with a tooltip that shows\n * the full date and time on hover; renders {@link UITableEmpty} when `date` is\n * `null` or `undefined`.\n *\n * @example\n * import { UITableDateDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableDateDisplay date={new Date('2024-06-15T10:30:00Z')} />\n */\nexport const UITableDateDisplay: React.FC<Props> = ({ date }) => {\n if (typeof date === 'undefined' || date === null) return <UITableEmpty />;\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n {/*<Badge className=\"h-fit\">*/}\n <DateDisplay date={date} format=\"medium\" />\n {/*</Badge>*/}\n </TooltipTrigger>\n <TooltipContent className=\"rounded px-2\">\n <DateDisplay date={date} format=\"full\" showTime className=\"font-medium text-text-negative text-xs\" />\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};\n"],"mappings":"4OAsBA,MAAa,GAAuC,CAAE,UACzC,GAAiC,KAAa,EAAC,EAAD,CAAe,CAAA,EAEtE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GAEd,SAAA,EAAC,EAAD,CAAmB,OAAM,OAAO,QAAU,CAAA,CAE5B,CAAA,EAChB,EAAC,EAAD,CAAgB,UAAU,eACxB,SAAA,EAAC,EAAD,CAAmB,OAAM,OAAO,OAAO,SAAA,GAAS,UAAU,wCAA0C,CAAA,CACtF,CAAA,CACT,CAAA,CAAA,CACM,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./date-B3cozmfV.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-
|
|
2
|
-
//# sourceMappingURL=date-display-
|
|
1
|
+
const e=require("./date-B3cozmfV.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-BqZ4Zs6e.cjs");let r=require("react/jsx-runtime");const i=({date:i})=>i==null?(0,r.jsx)(n.Q,{}):(0,r.jsx)(t.TooltipProvider,{children:(0,r.jsxs)(t.Tooltip,{children:[(0,r.jsx)(t.TooltipTrigger,{asChild:!0,children:(0,r.jsx)(e.t,{date:i,format:`medium`})}),(0,r.jsx)(t.TooltipContent,{className:`rounded px-2`,children:(0,r.jsx)(e.t,{date:i,format:`full`,showTime:!0,className:`font-medium text-text-negative text-xs`})})]})});exports.UITableDateDisplay=i;
|
|
2
|
+
//# sourceMappingURL=date-display-DHnZr_yf.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-display-
|
|
1
|
+
{"version":3,"file":"date-display-DHnZr_yf.cjs","names":["UITableEmpty","TooltipProvider","Tooltip","TooltipTrigger","DateDisplay","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/date-display.tsx"],"sourcesContent":["// import { Badge } from '@/components/ui/badge';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { DateDisplay } from '@/components/data-display/date';\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableDateDisplay} component. */\ntype Props = {\n /** The date value to format and display; `null`/`undefined` renders an empty state. */\n date: Date | string | number | null | undefined;\n};\n\n/**\n * Displays a date as a compact badge in a table cell with a tooltip that shows\n * the full date and time on hover; renders {@link UITableEmpty} when `date` is\n * `null` or `undefined`.\n *\n * @example\n * import { UITableDateDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableDateDisplay date={new Date('2024-06-15T10:30:00Z')} />\n */\nexport const UITableDateDisplay: React.FC<Props> = ({ date }) => {\n if (typeof date === 'undefined' || date === null) return <UITableEmpty />;\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n {/*<Badge className=\"h-fit\">*/}\n <DateDisplay date={date} format=\"medium\" />\n {/*</Badge>*/}\n </TooltipTrigger>\n <TooltipContent className=\"rounded px-2\">\n <DateDisplay date={date} format=\"full\" showTime className=\"font-medium text-text-negative text-xs\" />\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};\n"],"mappings":"2IAsBA,MAAa,GAAuC,CAAE,UACzC,GAAiC,MAAa,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,GAEtE,EAAA,EAAA,IAAA,CAACC,EAAAA,gBAAD,CAAA,UACE,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GAEd,UAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAAmB,OAAM,OAAO,QAAU,CAAA,CAE5B,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,UAAU,eACxB,UAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,EAAD,CAAmB,OAAM,OAAO,OAAO,SAAA,GAAS,UAAU,wCAA0C,CAAA,CACtF,CAAA,CACT,CAAA,CAAA,CACM,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-
|
|
2
|
-
//# sourceMappingURL=description-display-
|
|
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=({content:s})=>s==null?a(i,{}):o(t,{children:[a(r,{children:a(e,{variant:`sm`,className:`line-clamp-2 whitespace-pre-line break-all`,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(e,{variant:`xs`,className:`whitespace-pre-line text-wrap break-keep text-text-negative-weak`,children:s}),o(`p`,{className:`w-full text-end`,children:[s.toString().length,` chars`]})]})})]});export{s as UITableDescriptionDisplay};
|
|
2
|
+
//# sourceMappingURL=description-display-CBfoP3Y2.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"description-display-
|
|
1
|
+
{"version":3,"file":"description-display-CBfoP3Y2.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/description-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\nimport { Paragraph } from '@/components/typography/paragraph';\n\n/**\n * Renders a two-line-clamped description in a table cell with a tooltip that\n * reveals the full text and its character count; falls back to\n * {@link UITableEmpty} when `content` is `null` or `undefined`.\n *\n * @example\n * import { UITableDescriptionDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableDescriptionDisplay content=\"A detailed description of this record.\" />\n */\nexport const UITableDescriptionDisplay: React.FC<{\n /** The text or numeric value to display; `null`/`undefined` renders an empty state. */\n content: string | null | undefined | number;\n}> = ({ content }) => {\n if (content === undefined || content === null) {\n return <UITableEmpty />;\n }\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 whitespace-pre-line break-all\">\n {content}\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 <Paragraph variant=\"xs\" className=\"whitespace-pre-line text-wrap break-keep text-text-negative-weak\">\n {content}\n </Paragraph>\n <p className=\"w-full text-end\">{content.toString().length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"sOAeA,MAAa,GAGP,CAAE,aACF,GAAqC,KAChC,EAAC,EAAD,CAAe,CAAA,EAGtB,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAA,SACE,EAAC,EAAD,CAAW,QAAQ,KAAK,UAAU,6CAC/B,SAAA,CACQ,CAAA,CACG,CAAA,EAChB,EAAC,EAAD,CAAgB,MAAM,QAAQ,UAAU,+BACtC,SAAA,EAAC,MAAD,CAAK,UAAU,wBAAf,SAAA,CACE,EAAC,EAAD,CAAW,QAAQ,KAAK,UAAU,mEAC/B,SAAA,CACQ,CAAA,EACX,EAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAQ,SAAS,CAAC,CAAC,OAAO,QAAS,CAChE,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./typography/paragraph.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-
|
|
2
|
-
//# sourceMappingURL=description-display-
|
|
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=({content:i})=>i==null?(0,r.jsx)(n.Q,{}):(0,r.jsxs)(t.Tooltip,{children:[(0,r.jsx)(t.TooltipTrigger,{children:(0,r.jsx)(e.Paragraph,{variant:`sm`,className:`line-clamp-2 whitespace-pre-line break-all`,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)(e.Paragraph,{variant:`xs`,className:`whitespace-pre-line text-wrap break-keep text-text-negative-weak`,children:i}),(0,r.jsxs)(`p`,{className:`w-full text-end`,children:[i.toString().length,` chars`]})]})})]});exports.UITableDescriptionDisplay=i;
|
|
2
|
+
//# sourceMappingURL=description-display-Cckihd1s.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"description-display-
|
|
1
|
+
{"version":3,"file":"description-display-Cckihd1s.cjs","names":["UITableEmpty","Tooltip","TooltipTrigger","Paragraph","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/description-display.tsx"],"sourcesContent":["import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\nimport { Paragraph } from '@/components/typography/paragraph';\n\n/**\n * Renders a two-line-clamped description in a table cell with a tooltip that\n * reveals the full text and its character count; falls back to\n * {@link UITableEmpty} when `content` is `null` or `undefined`.\n *\n * @example\n * import { UITableDescriptionDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableDescriptionDisplay content=\"A detailed description of this record.\" />\n */\nexport const UITableDescriptionDisplay: React.FC<{\n /** The text or numeric value to display; `null`/`undefined` renders an empty state. */\n content: string | null | undefined | number;\n}> = ({ content }) => {\n if (content === undefined || content === null) {\n return <UITableEmpty />;\n }\n return (\n <Tooltip>\n <TooltipTrigger>\n <Paragraph variant=\"sm\" className=\"line-clamp-2 whitespace-pre-line break-all\">\n {content}\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 <Paragraph variant=\"xs\" className=\"whitespace-pre-line text-wrap break-keep text-text-negative-weak\">\n {content}\n </Paragraph>\n <p className=\"w-full text-end\">{content.toString().length} chars</p>\n </div>\n </TooltipContent>\n </Tooltip>\n );\n};\n"],"mappings":"kJAeA,MAAa,GAGP,CAAE,aACF,GAAqC,MAChC,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,GAGtB,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,6CAC/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,CAACD,EAAAA,UAAD,CAAW,QAAQ,KAAK,UAAU,mEAC/B,SAAA,CACQ,CAAA,GACX,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAU,kBAAb,SAAA,CAAgC,EAAQ,SAAS,CAAC,CAAC,OAAO,QAAS,CAChE,CAAA,CAAA,GACS,CAAA,CACT,CAAA,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "../../../button-
|
|
1
|
+
import { t as Button } from "../../../button-BnoPktln.cjs";
|
|
2
2
|
import { n as TooltipContent } from "../../../tooltip-BVYKhsC2.cjs";
|
|
3
3
|
import { t as Separator } from "../../../separator-Cvxkpzrj.cjs";
|
|
4
4
|
import { VariantProps } from "class-variance-authority";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Button } from "../../../button-
|
|
1
|
+
import { t as Button } from "../../../button-BnoPktln.mjs";
|
|
2
2
|
import { n as TooltipContent } from "../../../tooltip-BVYKhsC2.mjs";
|
|
3
3
|
import { t as Separator } from "../../../separator-Cvxkpzrj.mjs";
|
|
4
4
|
import { VariantProps } from "class-variance-authority";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../typography/paragraph.cjs"),t=require("../close-BYHgEZvZ.cjs");let n=require("@customafk/react-toolkit/utils"),r=require("react/jsx-runtime"),i=require("radix-ui");const a=({open:a,onOpenChange:o,title:s,description:c,footer:l,showCloseButton:u=!0,children:d,width:f=`sm:w-1/2 sm:max-w-2xl`,modal:p=!0,className:m})=>{let h=!p||u;return(0,r.jsx)(i.Dialog.Root,{open:a,onOpenChange:o,modal:p,children:(0,r.jsxs)(i.Dialog.Portal,{children:[p&&(0,r.jsx)(i.Dialog.Overlay,{className:(0,n.cn)(`fixed inset-0 z-50 bg-black/50`,`data-[state=open]:fade-in-0 data-[state=open]:animate-in`,`data-[state=closed]:fade-out-0 data-[state=closed]:animate-out`)}),(0,r.jsxs)(i.Dialog.Content,{className:(0,n.cn)(`fixed z-50 flex flex-col bg-background`,`rounded-2xl border border-border-weak shadow-dialog outline-none`,`inset-2 sm:inset-y-2 sm:right-2 sm:left-auto`,f,`data-[state=open]:slide-in-from-right data-[state=open]:animate-in data-[state=open]:duration-500`,`data-[state=closed]:slide-out-to-right data-[state=closed]:animate-out data-[state=closed]:duration-300`,m),onEscapeKeyDown:e=>{p||e.preventDefault()},onInteractOutside:e=>{p||e.preventDefault()},children:[(s||c)&&(0,r.jsxs)(`div`,{className:(0,n.cn)(`flex flex-none flex-col gap-1 border-border-weak border-b p-4`,h&&`pr-14`),children:[s&&(0,r.jsx)(i.Dialog.Title,{className:`font-bold text-base text-text-positive-strong`,children:s}),c&&(0,r.jsx)(i.Dialog.Description,{className:(0,n.cn)(e.paragraphVariants({variant:`muted`}),`not-first:mt-0 md:text-sm`),children:c})]}),(0,r.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto p-4`,children:d}),l&&(0,r.jsx)(`div`,{className:`mt-auto flex flex-none flex-col-reverse gap-2 border-t border-border-weak p-4 sm:flex-row sm:justify-end`,children:l}),h&&(0,r.jsx)(i.Dialog.Close,{tabIndex:-1,asChild:!0,className:`absolute top-4 right-4`,children:(0,r.jsx)(t.t,{"aria-label":`Đóng`})})]})]})})};exports.SidePanel=a;
|
|
2
|
+
//# sourceMappingURL=side-panel.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"side-panel.cjs","names":["SidePanelPrimitive","paragraphVariants","CloseButton"],"sources":["../../packages/components/dialogs/side-panel.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog as SidePanelPrimitive } from 'radix-ui';\nimport { paragraphVariants } from '../typography/paragraph';\nimport { CloseButton } from '../ui/buttons/close';\n\n/**\n * Props for the {@link SidePanel} component.\n */\nexport type SidePanelProps = {\n /**\n * Controls whether the panel is currently open.\n * This is a **controlled** prop — pair it with `onOpenChange` to manage state.\n */\n open?: boolean;\n\n /**\n * Callback fired when the open state changes (e.g. backdrop click, close button, `Escape`).\n *\n * @param open - `true` when opening, `false` when closing.\n */\n onOpenChange?: (open: boolean) => void;\n\n /** Heading rendered at the top of the panel. */\n title?: React.ReactNode;\n\n /** Supporting text rendered below the title. */\n description?: React.ReactNode;\n\n /** Content rendered pinned to the bottom of the panel, typically action buttons. */\n footer?: React.ReactNode;\n\n /**\n * When `true` (default), renders a `CloseButton` in the top-right corner of the panel.\n *\n * @default true\n */\n showCloseButton?: boolean;\n\n /** Main scrollable body content of the panel. */\n children?: React.ReactNode;\n\n /**\n * Tailwind width classes applied to the panel from the `sm` breakpoint up (below `sm` the\n * panel always fills the available inset area). Override to make the panel narrower, wider,\n * or a fixed size, e.g. `'sm:w-96'` or `'sm:w-full sm:max-w-3xl'`.\n *\n * @default 'sm:w-1/2 sm:max-w-2xl'\n */\n width?: string;\n\n /**\n * When `false`, the panel becomes non-modal: no dimmed overlay is rendered, background content\n * stays fully visible and interactive, and the panel can only be closed via its close button\n * (`Escape` and outside clicks are disabled). `showCloseButton` is forced to `true` in this mode\n * regardless of what's passed, since it becomes the only way to close the panel.\n *\n * @default true\n */\n modal?: boolean;\n\n /** Additional class names applied to the panel itself. */\n className?: string;\n};\n\n/**\n * A controlled dialog panel anchored to the right half of the screen, inset from the viewport\n * edges on both axes. Always lays out as a fixed header, a scrollable body, and a fixed footer.\n *\n * **Import:** `import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel'`\n *\n * @example\n * ```tsx\n * import { useState } from 'react';\n * import { Button } from '@customafk/lunas-ui/ui/button';\n * import { SidePanel } from '@customafk/lunas-ui/dialogs/side-panel';\n *\n * export function OrderDetailPanel({ order }: { order: Order }) {\n * const [open, setOpen] = useState(false);\n *\n * return (\n * <>\n * <Button onClick={() => setOpen(true)}>Xem chi tiết</Button>\n * <SidePanel\n * open={open}\n * onOpenChange={setOpen}\n * title=\"Chi tiết đơn hàng\"\n * description=\"Xem và cập nhật thông tin đơn hàng.\"\n * footer={<Button onClick={() => setOpen(false)}>Lưu thay đổi</Button>}\n * >\n * <p>Nội dung có thể cuộn ở đây.</p>\n * </SidePanel>\n * </>\n * );\n * }\n * ```\n */\nexport const SidePanel: React.FC<SidePanelProps> = ({\n open,\n onOpenChange,\n title,\n description,\n footer,\n showCloseButton = true,\n children,\n width = 'sm:w-1/2 sm:max-w-2xl',\n modal = true,\n className,\n}) => {\n const resolvedShowCloseButton = modal ? showCloseButton : true;\n\n return (\n <SidePanelPrimitive.Root open={open} onOpenChange={onOpenChange} modal={modal}>\n <SidePanelPrimitive.Portal>\n {modal && (\n <SidePanelPrimitive.Overlay\n className={cn(\n 'fixed inset-0 z-50 bg-black/50',\n 'data-[state=open]:fade-in-0 data-[state=open]:animate-in',\n 'data-[state=closed]:fade-out-0 data-[state=closed]:animate-out'\n )}\n />\n )}\n <SidePanelPrimitive.Content\n className={cn(\n 'fixed z-50 flex flex-col bg-background',\n 'rounded-2xl border border-border-weak shadow-dialog outline-none',\n 'inset-2 sm:inset-y-2 sm:right-2 sm:left-auto',\n width,\n 'data-[state=open]:slide-in-from-right data-[state=open]:animate-in data-[state=open]:duration-500',\n 'data-[state=closed]:slide-out-to-right data-[state=closed]:animate-out data-[state=closed]:duration-300',\n className\n )}\n onEscapeKeyDown={event => {\n if (!modal) event.preventDefault();\n }}\n onInteractOutside={event => {\n if (!modal) event.preventDefault();\n }}\n >\n {(title || description) && (\n <div className={cn('flex flex-none flex-col gap-1 border-border-weak border-b p-4', resolvedShowCloseButton && 'pr-14')}>\n {title && <SidePanelPrimitive.Title className=\"font-bold text-base text-text-positive-strong\">{title}</SidePanelPrimitive.Title>}\n {description && (\n <SidePanelPrimitive.Description className={cn(paragraphVariants({ variant: 'muted' }), 'not-first:mt-0 md:text-sm')}>\n {description}\n </SidePanelPrimitive.Description>\n )}\n </div>\n )}\n <div className=\"min-h-0 flex-1 overflow-y-auto p-4\">{children}</div>\n {footer && <div className=\"mt-auto flex flex-none flex-col-reverse gap-2 border-t border-border-weak p-4 sm:flex-row sm:justify-end\">{footer}</div>}\n {resolvedShowCloseButton && (\n <SidePanelPrimitive.Close tabIndex={-1} asChild className=\"absolute top-4 right-4\">\n <CloseButton aria-label=\"Đóng\" />\n </SidePanelPrimitive.Close>\n )}\n </SidePanelPrimitive.Content>\n </SidePanelPrimitive.Portal>\n </SidePanelPrimitive.Root>\n );\n};\n"],"mappings":"uQAmGA,MAAa,GAAuC,CAClD,OACA,eACA,QACA,cACA,SACA,kBAAkB,GAClB,WACA,QAAQ,wBACR,QAAQ,GACR,eACI,CACJ,IAAM,EAA0B,IAAQ,EAExC,OACE,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAmB,KAApB,CAA+B,OAAoB,eAAqB,QACtE,UAAA,EAAA,EAAA,KAAA,CAACA,EAAAA,OAAmB,OAApB,CAAA,SAAA,CACG,IACC,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAmB,QAApB,CACE,WAAA,EAAA,EAAA,GAAA,CACE,iCACA,2DACA,gEACF,CACD,CAAA,GAEH,EAAA,EAAA,KAAA,CAACA,EAAAA,OAAmB,QAApB,CACE,WAAA,EAAA,EAAA,GAAA,CACE,yCACA,mEACA,+CACA,EACA,oGACA,0GACA,CACF,EACA,gBAAiB,GAAS,CACnB,GAAO,EAAM,eAAe,CACnC,EACA,kBAAmB,GAAS,CACrB,GAAO,EAAM,eAAe,CACnC,EAfF,SAAA,EAiBI,GAAS,KACT,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,WAAA,EAAA,EAAA,GAAA,CAAc,gEAAiE,GAA2B,OAAO,EAAtH,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAmB,MAApB,CAA0B,UAAU,gDAAiD,SAAA,CAAgC,CAAA,EAC9H,IACC,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAmB,YAApB,CAAgC,WAAA,EAAA,EAAA,GAAA,CAAcC,EAAAA,kBAAkB,CAAE,QAAS,OAAQ,CAAC,EAAG,2BAA2B,EAC/G,SAAA,CAC6B,CAAA,CAE/B,KAEP,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,qCAAsC,UAAc,CAAA,EAClE,IAAU,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,2GAA4G,SAAA,CAAY,CAAA,EACjJ,IACC,EAAA,EAAA,IAAA,CAACD,EAAAA,OAAmB,MAApB,CAA0B,SAAU,GAAI,QAAA,GAAQ,UAAU,yBACxD,UAAA,EAAA,EAAA,IAAA,CAACE,EAAAA,EAAD,CAAa,aAAW,MAAQ,CAAA,CACR,CAAA,CAEF,CACH,CAAA,CAAA,CAAA,CAAA,CACJ,CAAA,CAE7B"}
|