@customafk/lunas-ui 0.2.79 → 0.2.81
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-Bg0lCfWv.cjs → analysis-panel-DYF2CmAH.cjs} +2 -2
- package/dist/{analysis-panel-Bg0lCfWv.cjs.map → analysis-panel-DYF2CmAH.cjs.map} +1 -1
- package/dist/{analysis-panel-Cop-l4lx.mjs → analysis-panel-_s1fgcZC.mjs} +2 -2
- package/dist/{analysis-panel-Cop-l4lx.mjs.map → analysis-panel-_s1fgcZC.mjs.map} +1 -1
- package/dist/{badge-BPiU1Ss2.d.cts → badge-C_KLKwiS.d.cts} +2 -2
- package/dist/{badge-BPiU1Ss2.d.mts → badge-C_KLKwiS.d.mts} +2 -2
- package/dist/{badge-display-B0BKsU9T.mjs → badge-display-D6d7wTEE.mjs} +2 -2
- package/dist/{badge-display-B0BKsU9T.mjs.map → badge-display-D6d7wTEE.mjs.map} +1 -1
- package/dist/{badge-display-Dv2UTvzp.cjs → badge-display-DWzSl3rs.cjs} +2 -2
- package/dist/{badge-display-Dv2UTvzp.cjs.map → badge-display-DWzSl3rs.cjs.map} +1 -1
- package/dist/{boolean-display-CPX7H39m.cjs → boolean-display-C5GIuWnc.cjs} +2 -2
- package/dist/{boolean-display-CPX7H39m.cjs.map → boolean-display-C5GIuWnc.cjs.map} +1 -1
- package/dist/{boolean-display-CMX5AupA.mjs → boolean-display-Wko_5Jd5.mjs} +2 -2
- package/dist/{boolean-display-CMX5AupA.mjs.map → boolean-display-Wko_5Jd5.mjs.map} +1 -1
- package/dist/{button-DQLIL8K2.d.cts → button-CnKmz4qM.d.cts} +4 -4
- package/dist/{button-DQLIL8K2.d.mts → button-CnKmz4qM.d.mts} +4 -4
- package/dist/{calendar-5VVBPn4F.d.mts → calendar-BT6-Fo3T.d.mts} +2 -2
- package/dist/{calendar-DHcoDDIc.d.cts → calendar-D_QmR9VE.d.cts} +2 -2
- package/dist/{carousel-D0jTbSoW.d.cts → carousel-BBI4xPdK.d.mts} +2 -2
- package/dist/{carousel-qH6YsFKK.d.mts → carousel-B_IXlBdH.d.cts} +2 -2
- package/dist/{currency-display-CanjOswc.mjs → currency-display-BGkpGtN_.mjs} +2 -2
- package/dist/{currency-display-CanjOswc.mjs.map → currency-display-BGkpGtN_.mjs.map} +1 -1
- package/dist/{currency-display-xxK62yo4.cjs → currency-display-Bbh5InhV.cjs} +2 -2
- package/dist/{currency-display-xxK62yo4.cjs.map → currency-display-Bbh5InhV.cjs.map} +1 -1
- package/dist/{date-display-DMPhFq8v.cjs → date-display-D38qvsh2.cjs} +2 -2
- package/dist/{date-display-DMPhFq8v.cjs.map → date-display-D38qvsh2.cjs.map} +1 -1
- package/dist/{date-display-YE8NIIrl.mjs → date-display-DXyb-Ai2.mjs} +2 -2
- package/dist/{date-display-YE8NIIrl.mjs.map → date-display-DXyb-Ai2.mjs.map} +1 -1
- package/dist/{description-display-B4KoH6ql.mjs → description-display-BwBMrRAi.mjs} +2 -2
- package/dist/{description-display-B4KoH6ql.mjs.map → description-display-BwBMrRAi.mjs.map} +1 -1
- package/dist/{description-display-jmAaeMBD.cjs → description-display-DIeHy7ll.cjs} +2 -2
- package/dist/{description-display-jmAaeMBD.cjs.map → description-display-DIeHy7ll.cjs.map} +1 -1
- package/dist/detail-dialog-BCM0iEXQ.cjs +2 -0
- package/dist/detail-dialog-BCM0iEXQ.cjs.map +1 -0
- package/dist/detail-dialog-DwfTi9Fl.mjs +2 -0
- package/dist/detail-dialog-DwfTi9Fl.mjs.map +1 -0
- package/dist/dialogs/detail-dialog/components/sidebar.d.cts +2 -2
- package/dist/dialogs/detail-dialog/components/sidebar.d.mts +2 -2
- package/dist/dialogs/detail-dialog/index.cjs +1 -1
- package/dist/dialogs/detail-dialog/index.d.cts +1 -1
- package/dist/dialogs/detail-dialog/index.d.mts +1 -1
- package/dist/dialogs/detail-dialog/index.mjs +1 -1
- package/dist/{email-display-D_k7AUmp.mjs → email-display-Be3b-kDL.mjs} +2 -2
- package/dist/{email-display-D_k7AUmp.mjs.map → email-display-Be3b-kDL.mjs.map} +1 -1
- package/dist/{email-display-CzvqQMhG.cjs → email-display-_FRE2qcO.cjs} +2 -2
- package/dist/{email-display-CzvqQMhG.cjs.map → email-display-_FRE2qcO.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/file-icons/index.cjs +2 -0
- package/dist/features/file-icons/index.cjs.map +1 -0
- package/dist/features/file-icons/index.d.cts +34 -0
- package/dist/features/file-icons/index.d.mts +34 -0
- package/dist/features/file-icons/index.mjs +2 -0
- package/dist/features/file-icons/index.mjs.map +1 -0
- 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 +2 -0
- package/dist/{filter-BCNjqiBx.mjs.map → filter-C2wE49q7.mjs.map} +1 -1
- package/dist/filter-z7p4lRp8.cjs +2 -0
- package/dist/{filter-B5EnnL9I.cjs.map → filter-z7p4lRp8.cjs.map} +1 -1
- package/dist/{flex-CWo0w9K1.d.cts → flex-CIzZIICK.d.cts} +2 -2
- package/dist/{flex-CWo0w9K1.d.mts → flex-CIzZIICK.d.mts} +2 -2
- package/dist/{index-CLx89ATZ.d.cts → index-BSj8azta.d.cts} +2 -2
- package/dist/{index-BOifmu0V.d.cts → index-BXqx1kOJ.d.cts} +4 -2
- package/dist/{index-BOifmu0V.d.mts → index-BXqx1kOJ.d.mts} +4 -2
- package/dist/{index-BMuVmm7f.d.mts → index-CEmVk1zP.d.mts} +2 -2
- package/dist/{index-CFgFCg9H.d.mts → index-CjiDR-94.d.mts} +16 -15
- package/dist/{index-BapooVnN.d.cts → index-DqAbPipJ.d.cts} +16 -15
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +14 -14
- package/dist/index.d.mts +14 -14
- package/dist/index.mjs +1 -1
- package/dist/{item-CtLZgUB6.d.cts → item-BxUBO7Hd.d.cts} +2 -2
- package/dist/{item-Brbp9t6f.d.mts → item-ChW41yKF.d.mts} +2 -2
- package/dist/layouts/flex.d.cts +1 -1
- package/dist/layouts/flex.d.mts +1 -1
- package/dist/{list-display-DPxZ_Jbf.cjs → list-display-BvKGl7uq.cjs} +2 -2
- package/dist/{list-display-DPxZ_Jbf.cjs.map → list-display-BvKGl7uq.cjs.map} +1 -1
- package/dist/{list-display-M43N3kle.mjs → list-display-CWQvIMUj.mjs} +2 -2
- package/dist/{list-display-M43N3kle.mjs.map → list-display-CWQvIMUj.mjs.map} +1 -1
- package/dist/{name-display-pWhLLS05.mjs → name-display-CnTRVqX4.mjs} +2 -2
- package/dist/{name-display-pWhLLS05.mjs.map → name-display-CnTRVqX4.mjs.map} +1 -1
- package/dist/{name-display-BJ1wPUnS.cjs → name-display-DfOtYp7d.cjs} +2 -2
- package/dist/{name-display-BJ1wPUnS.cjs.map → name-display-DfOtYp7d.cjs.map} +1 -1
- package/dist/{pagination-BVA_yrBO.d.mts → pagination-AxRzmAtZ.d.cts} +2 -2
- package/dist/{pagination-DqJlXNY0.d.cts → pagination-D12pR8_5.d.mts} +2 -2
- package/dist/{paragraph-CRo5eC7H.d.mts → paragraph-C5HE9u0Q.d.mts} +2 -2
- package/dist/{paragraph-CkCNIsvz.d.cts → paragraph-DJlHIDmk.d.cts} +2 -2
- package/dist/{permalink-CMcI__V4.cjs → permalink-29QzG9Xe.cjs} +2 -2
- package/dist/{permalink-CMcI__V4.cjs.map → permalink-29QzG9Xe.cjs.map} +1 -1
- package/dist/{permalink-BaMvnKIz.mjs → permalink-DhqOATLQ.mjs} +2 -2
- package/dist/{permalink-BaMvnKIz.mjs.map → permalink-DhqOATLQ.mjs.map} +1 -1
- package/dist/{phone-number-F9I9sNLK.cjs → phone-number-C2k8llhf.cjs} +2 -2
- package/dist/{phone-number-F9I9sNLK.cjs.map → phone-number-C2k8llhf.cjs.map} +1 -1
- package/dist/{phone-number-ao2oCmrO.mjs → phone-number-CQXrATQO.mjs} +2 -2
- package/dist/{phone-number-ao2oCmrO.mjs.map → phone-number-CQXrATQO.mjs.map} +1 -1
- package/dist/{progress-display-F8xXJ3T1.cjs → progress-display-B4WVzdJw.cjs} +2 -2
- package/dist/{progress-display-F8xXJ3T1.cjs.map → progress-display-B4WVzdJw.cjs.map} +1 -1
- package/dist/{progress-display-atwRFD6e.mjs → progress-display-DZb1qjfY.mjs} +2 -2
- package/dist/{progress-display-atwRFD6e.mjs.map → progress-display-DZb1qjfY.mjs.map} +1 -1
- package/dist/{resizable-B61Fbl57.d.cts → resizable-D61lvcIL.d.cts} +2 -2
- package/dist/{resizable-B61Fbl57.d.mts → resizable-D61lvcIL.d.mts} +2 -2
- package/dist/{statistic-CJVc9sNs.mjs → statistic-DoNUSe3e.mjs} +2 -2
- package/dist/{statistic-CJVc9sNs.mjs.map → statistic-DoNUSe3e.mjs.map} +1 -1
- package/dist/{statistic-B9OqfhOl.cjs → statistic-wnnjHsKj.cjs} +2 -2
- package/dist/{statistic-B9OqfhOl.cjs.map → statistic-wnnjHsKj.cjs.map} +1 -1
- package/dist/{status-display-DInGGgiP.mjs → status-display-CcihiYsH.mjs} +2 -2
- package/dist/{status-display-DInGGgiP.mjs.map → status-display-CcihiYsH.mjs.map} +1 -1
- package/dist/{status-display-DpKsYvZJ.cjs → status-display-DJ8fFqyX.cjs} +2 -2
- package/dist/{status-display-DpKsYvZJ.cjs.map → status-display-DJ8fFqyX.cjs.map} +1 -1
- package/dist/{summary-bar-DX_sOiuL.mjs → summary-bar-C4loKj1L.mjs} +2 -2
- package/dist/{summary-bar-DX_sOiuL.mjs.map → summary-bar-C4loKj1L.mjs.map} +1 -1
- package/dist/{summary-bar-DKZh-VSB.cjs → summary-bar-DK8glsr4.cjs} +2 -2
- package/dist/{summary-bar-DKZh-VSB.cjs.map → summary-bar-DK8glsr4.cjs.map} +1 -1
- package/dist/{tables-7_KgoyS-.mjs → tables-BTBtN1di.mjs} +2 -2
- package/dist/{tables-7_KgoyS-.mjs.map → tables-BTBtN1di.mjs.map} +1 -1
- package/dist/{tables-CS3NhgTc.cjs → tables-BzP8Cnvh.cjs} +2 -2
- package/dist/{tables-CS3NhgTc.cjs.map → tables-BzP8Cnvh.cjs.map} +1 -1
- package/dist/{toggle-v1PgAvdG.d.cts → toggle-CqTmiPDi.d.cts} +2 -2
- package/dist/{toggle-v1PgAvdG.d.mts → toggle-CqTmiPDi.d.mts} +2 -2
- package/dist/{toggle-group-DM5tS0Kt.d.cts → toggle-group--bJylFDV.d.cts} +2 -2
- package/dist/{toggle-group-_PBz44Im.d.mts → toggle-group-l_Mi7NRg.d.mts} +2 -2
- package/dist/tooltip-BKcU3bMc.mjs +4 -0
- package/dist/tooltip-BKcU3bMc.mjs.map +1 -0
- package/dist/tooltip-CLjCwnTD.cjs +4 -0
- package/dist/tooltip-CLjCwnTD.cjs.map +1 -0
- package/dist/typography/paragraph.d.cts +1 -1
- package/dist/typography/paragraph.d.mts +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/file-uploader.cjs +2 -2
- package/dist/ui/file-uploader.cjs.map +1 -1
- package/dist/ui/file-uploader.mjs +2 -2
- package/dist/ui/file-uploader.mjs.map +1 -1
- package/dist/ui/item.d.cts +1 -1
- package/dist/ui/item.d.mts +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/status.d.cts +1 -1
- package/dist/ui/status.d.mts +1 -1
- package/dist/ui/toggle-group.d.cts +1 -1
- package/dist/ui/toggle-group.d.mts +1 -1
- package/dist/ui/toggle.d.cts +1 -1
- package/dist/ui/toggle.d.mts +1 -1
- package/package.json +5 -1
- package/dist/detail-dialog-Ct0vAjFe.mjs +0 -2
- package/dist/detail-dialog-Ct0vAjFe.mjs.map +0 -1
- package/dist/detail-dialog-uN5mrCa7.cjs +0 -2
- package/dist/detail-dialog-uN5mrCa7.cjs.map +0 -1
- package/dist/filter-B5EnnL9I.cjs +0 -2
- package/dist/filter-BCNjqiBx.mjs +0 -2
- package/dist/tooltip-BcQG6Zw9.cjs +0 -4
- package/dist/tooltip-BcQG6Zw9.cjs.map +0 -1
- package/dist/tooltip-C6flMQgc.mjs +0 -4
- package/dist/tooltip-C6flMQgc.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detail-dialog-Ct0vAjFe.mjs","names":["DialogPrimitive"],"sources":["../packages/components/dialogs/detail-dialog/components/content.tsx","../packages/components/dialogs/detail-dialog/components/header.tsx","../packages/components/dialogs/detail-dialog/components/provider.tsx","../packages/components/dialogs/detail-dialog/components/sidebar-panel.tsx","../packages/components/dialogs/detail-dialog/components/wrapper.tsx","../packages/components/dialogs/detail-dialog/index.tsx"],"sourcesContent":["'use client';\n\nimport { Suspense } from 'react';\n\nimport { Flex } from '@/components/layouts/flex';\n\nexport type DetailDialogContentProps = React.PropsWithChildren<{\n /** When `true`, replaces the content with a centered loading spinner. */\n isLoading?: boolean;\n}>;\n\nfunction DetailDialogLoader() {\n return (\n <Flex justify=\"center\" className=\"inset-shadow-sm min-h-0 bg-muted-muted\">\n <div className=\"loader\" />\n </Flex>\n );\n}\n\nexport function DetailDialogContent({ isLoading, children }: DetailDialogContentProps) {\n return (\n <main data-slot=\"detail-dialog-main\" className=\"@container col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1\">\n {isLoading ? (\n <DetailDialogLoader />\n ) : (\n <Suspense fallback={<DetailDialogLoader />}>\n <section data-slot=\"detail-dialog-body\" className=\"relative inset-shadow-sm grid min-h-0 snap-y grid-cols-1 overflow-y-auto bg-white\">\n {children}\n </section>\n </Suspense>\n )}\n </main>\n );\n}\n","'use client';\n\nimport { Suspense } from 'react';\n\nimport { CalendarIcon } from 'lucide-react';\n\nimport { Skeleton } from '@/components/ui/skeleton';\n\nimport { DateDisplay } from '@/components/data-display/date';\nimport { Title } from '@/components/typography/title';\nimport { DetailDialogSidebarTrigger } from './sidebar-core';\n\nexport type DetailDialogHeaderProps = {\n /** Primary title displayed in the dialog header. */\n title?: string;\n /** ISO string, `Date` object, or Unix timestamp shown as a formatted creation date below the title. */\n createdAt?: string | Date | number | null;\n /** Custom content replacing the default title/date block, e.g. for consumer-specific headers. Suspense-wrapped. */\n headerComponent?: React.ReactNode;\n};\n\nfunction DetailDialogHeaderSkeleton() {\n return (\n <div data-slot=\"detail-dialog-header-skeleton\" className=\"grid justify-items-start gap-1.5\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-3 w-24\" />\n </div>\n );\n}\n\nexport function DetailDialogHeader({ title, createdAt, headerComponent }: DetailDialogHeaderProps) {\n return (\n <header\n data-slot=\"detail-dialog-header\"\n className=\"col-start-2 row-start-1 grid grid-cols-[auto_1fr] items-start gap-x-2.5 border-border-weak border-b bg-card py-2.5 pr-12 pl-2\"\n >\n <DetailDialogSidebarTrigger />\n <div data-slot=\"detail-dialog-header-content\" className=\"min-w-0 overflow-x-auto\">\n <Suspense fallback={<DetailDialogHeaderSkeleton />}>\n {headerComponent ?? (\n <div className=\"grid justify-items-start gap-0\">\n <Title level={5} className=\"line-clamp-1 truncate text-wrap\">\n {title || 'Detail Dialog'}\n </Title>\n {!!createdAt && (\n <div className=\"relative grid grid-flow-col items-center gap-1 text-text-positive-weak\">\n <CalendarIcon size={12} className=\"text-primary-strong\" />\n <p className=\"text-primary-strong text-xs\">Ngày Tạo</p>\n <DateDisplay showHoliday date={createdAt} format=\"medium\" />\n </div>\n )}\n </div>\n )}\n </Suspense>\n </div>\n </header>\n );\n}\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { TooltipProvider } from '@/components/ui/tooltip';\n\nimport { SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON, SidebarContext, useSidebarState } from './sidebar-core';\n\n/**\n * Context provider for `DetailDialog`'s sidebar/header/content grid shell. Manages sidebar\n * open/collapsed state (persisted via a cookie, shared with `SidebarProvider` via\n * `useSidebarState`) and renders the 2x2 grid wrapper — sidebar spanning both rows in column 1,\n * header/content in column 2. DetailDialog-specific, not a standalone-reusable provider like\n * `./sidebar-core`'s `SidebarProvider`.\n */\nexport function DetailDialogProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n /** Whether the sidebar is open by default (uncontrolled). Defaults to `true`. */\n defaultOpen?: boolean;\n /** Controlled open state. When provided the component becomes controlled. */\n open?: boolean;\n /** Callback fired when the open state changes in controlled mode. */\n onOpenChange?: (open: boolean) => void;\n}) {\n const contextValue = useSidebarState({ defaultOpen, open: openProp, onOpenChange: setOpenProp });\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"detail-dialog-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn('group/sidebar-wrapper size-full min-h-[85dvh]', 'grid grid-cols-[auto_1fr] grid-rows-[auto_1fr]', className)}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n","'use client';\n\nimport { LunasLogo } from '@/components/features/logo';\n\nimport {\n DetailDialogSidebarContent,\n DetailDialogSidebarFooter,\n DetailDialogSidebarHeader,\n DetailDialogSidebarMenu,\n DetailDialogSidebarMenuButton,\n DetailDialogSidebarMenuItem,\n Sidebar,\n} from './sidebar-core';\n\nexport type DetailDialogSidebarPanelProps = {\n /** Title shown in the collapsible sidebar header. Defaults to `'Detail Dialog'`. */\n title?: string;\n /** Title shown in the collapsible sidebar header. Defaults to `'Detail Dialog'`. */\n sidebarTitle?: string;\n /** Arbitrary content rendered inside the sidebar scrollable area. */\n content?: React.ReactNode;\n /** Arbitrary content rendered at the bottom of the sidebar footer. */\n footer?: React.ReactNode;\n};\n\nexport function DetailDialogSidebarPanel({ title, sidebarTitle, content, footer }: DetailDialogSidebarPanelProps) {\n return (\n <div className=\"col-start-1 row-span-2 row-start-1\">\n <Sidebar>\n <DetailDialogSidebarHeader>\n <DetailDialogSidebarMenu>\n <DetailDialogSidebarMenuItem>\n <DetailDialogSidebarMenuButton size=\"lg\" tabIndex={-1}>\n <LunasLogo variant=\"icon\" iconStyle=\"solid\" size=\"md\" className=\"size-8 min-h-8 min-w-8\" />\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{sidebarTitle || 'Detail Dialog'}</span>\n <span className=\"truncate text-xs\">Lunas Enterprise</span>\n </div>\n </DetailDialogSidebarMenuButton>\n </DetailDialogSidebarMenuItem>\n </DetailDialogSidebarMenu>\n </DetailDialogSidebarHeader>\n <DetailDialogSidebarContent>{content}</DetailDialogSidebarContent>\n <DetailDialogSidebarFooter>{footer}</DetailDialogSidebarFooter>\n </Sidebar>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nexport type DetailDialogWrapperProps = React.PropsWithChildren<{\n /** Controls whether the dialog is open. */\n open?: boolean;\n /** Callback invoked when the dialog open state changes. */\n onOpenChange?: (open: boolean) => void;\n}>;\n\n/**\n * Outer Radix Dialog scaffolding for `DetailDialog` — Root, Portal, Overlay (scrollable,\n * min-width/min-height-safe centering), Content (the dialog card), and the close button.\n * `children` render inside Content, alongside `DetailDialogProvider`'s grid shell.\n */\nexport function DetailDialogWrapper({ open, onOpenChange, children }: DetailDialogWrapperProps) {\n const handleInteractOutside = useCallback<NonNullable<React.ComponentProps<typeof DialogPrimitive.Content>['onInteractOutside']>>(event => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n return (\n <DialogPrimitive.Root data-slot=\"detail-dialog\" open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal data-slot=\"detail-dialog-portal\">\n <DialogPrimitive.Overlay\n data-slot=\"detail-dialog-overlay\"\n className=\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 flex overflow-auto bg-black/50 p-4 data-[state=closed]:animate-out data-[state=open]:animate-in supports-backdrop-filter:backdrop-blur-xs\"\n >\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'relative z-50 m-auto grid',\n 'gap-4 overflow-hidden rounded-sm border-none bg-background p-0 shadow-dialog outline-none duration-200',\n 'size-full max-h-dvh min-h-160 min-w-264 max-w-svw',\n 'data-[state=closed]:animate-out data-[state=open]:animate-in',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-80 data-[state=open]:zoom-in-80'\n )}\n onInteractOutside={handleInteractOutside}\n >\n {children}\n\n <DialogPrimitive.Close data-slot=\"dialog-close\" tabIndex={-1} asChild className=\"absolute top-3 right-3\">\n <button className=\"flex cursor-pointer items-center justify-center rounded-full p-2 text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive active:bg-muted-weak active:text-text-positive-strong disabled:pointer-events-none disabled:opacity-60\">\n <XIcon size={24} />\n </button>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPrimitive.Overlay>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n","'use client';\n\nimport { DetailDialogContent } from './components/content';\nimport { DetailDialogHeader } from './components/header';\nimport { DetailDialogProvider } from './components/provider';\nimport { DetailDialogSidebarPanel, type DetailDialogSidebarPanelProps } from './components/sidebar-panel';\nimport { DetailDialogWrapper } from './components/wrapper';\n\nexport type DetailDialogProps = {\n /** Controls whether the dialog is open. */\n open?: boolean;\n /** When `true`, replaces the main content area with a centered loading spinner. */\n isLoading?: boolean;\n /** Primary title displayed in the dialog header. */\n title?: string;\n /** ISO string, `Date` object, or Unix timestamp shown as a formatted creation date below the title. */\n createdAt?: string | Date | number | null;\n /** Optional sidebar configuration — title, body content, and footer content. */\n sidebar?: DetailDialogSidebarPanelProps;\n /** Custom content replacing the default title/date block in the header. Suspense-wrapped. */\n headerComponent?: React.ReactNode;\n /** Callback invoked when the dialog open state changes. */\n onOpenChange?: (open: boolean) => void;\n};\n\n/**\n * Full-screen detail dialog with a collapsible sidebar, a header with creation date, and a scrollable content area.\n *\n * @example\n * ```tsx\n * import { DetailDialog } from '@customafk/lunas-ui/dialogs/detail-dialog';\n *\n * <DetailDialog\n * open={open}\n * title=\"Order #1234\"\n * createdAt=\"2024-01-15T09:00:00Z\"\n * sidebar={{ title: 'Navigation', content: <nav>...</nav> }}\n * onOpenChange={setOpen}\n * >\n * <p>Detail content goes here.</p>\n * </DetailDialog>\n * ```\n */\nexport const DetailDialog: React.FC<React.PropsWithChildren<DetailDialogProps>> = ({\n open,\n isLoading,\n title,\n createdAt,\n onOpenChange,\n sidebar,\n headerComponent,\n children,\n}) => {\n return (\n <DetailDialogWrapper open={open} onOpenChange={onOpenChange}>\n <DetailDialogProvider>\n <DetailDialogSidebarPanel title={sidebar?.title} content={sidebar?.content} footer={sidebar?.footer} />\n <DetailDialogHeader title={title} createdAt={createdAt} headerComponent={headerComponent} />\n <DetailDialogContent isLoading={isLoading}>{children}</DetailDialogContent>\n </DetailDialogProvider>\n </DetailDialogWrapper>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./ui/skeleton.cjs"),t=require("./layouts/flex.cjs"),n=require("./date-B3cozmfV.cjs"),r=require("./ui/tooltip.cjs"),i=require("./typography/title.cjs"),a=require("./sidebar-core-DUdB9WCv.cjs"),o=require("./features/logo/index.cjs");let s=require("lucide-react"),c=require("react"),l=require("@customafk/react-toolkit/utils"),u=require("react/jsx-runtime"),d=require("radix-ui");function f(){return(0,u.jsx)(t.Flex,{justify:`center`,className:`inset-shadow-sm min-h-0 bg-muted-muted`,children:(0,u.jsx)(`div`,{className:`loader`})})}function p({isLoading:e,children:t}){return(0,u.jsx)(`main`,{"data-slot":`detail-dialog-main`,className:`@container col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1`,children:e?(0,u.jsx)(f,{}):(0,u.jsx)(c.Suspense,{fallback:(0,u.jsx)(f,{}),children:(0,u.jsx)(`section`,{"data-slot":`detail-dialog-body`,className:`relative inset-shadow-sm grid min-h-0 snap-y grid-cols-1 overflow-y-auto bg-white`,children:t})})})}function m(){return(0,u.jsxs)(`div`,{"data-slot":`detail-dialog-header-skeleton`,className:`grid justify-items-start gap-1.5`,children:[(0,u.jsx)(e.Skeleton,{className:`h-5 w-40`}),(0,u.jsx)(e.Skeleton,{className:`h-3 w-24`})]})}function h({title:e,createdAt:t,headerComponent:r}){return(0,u.jsxs)(`header`,{"data-slot":`detail-dialog-header`,className:`col-start-2 row-start-1 grid grid-cols-[auto_1fr] items-start gap-x-2.5 border-border-weak border-b bg-card py-2.5 pr-12 pl-2`,children:[(0,u.jsx)(a.s,{}),(0,u.jsx)(`div`,{"data-slot":`detail-dialog-header-content`,className:`min-w-0 overflow-x-auto`,children:(0,u.jsx)(c.Suspense,{fallback:(0,u.jsx)(m,{}),children:r??(0,u.jsxs)(`div`,{className:`grid justify-items-start gap-0`,children:[(0,u.jsx)(i.Title,{level:5,className:`line-clamp-1 truncate text-wrap`,children:e||`Detail Dialog`}),!!t&&(0,u.jsxs)(`div`,{className:`relative grid grid-flow-col items-center gap-1 text-text-positive-weak`,children:[(0,u.jsx)(s.CalendarIcon,{size:12,className:`text-primary-strong`}),(0,u.jsx)(`p`,{className:`text-primary-strong text-xs`,children:`Ngày Tạo`}),(0,u.jsx)(n.t,{showHoliday:!0,date:t,format:`medium`})]})]})})})]})}function g({defaultOpen:e=!0,open:t,onOpenChange:n,className:i,style:o,children:s,...c}){let d=a._({defaultOpen:e,open:t,onOpenChange:n});return(0,u.jsx)(a.m.Provider,{value:d,children:(0,u.jsx)(r.TooltipProvider,{delayDuration:0,children:(0,u.jsx)(`div`,{"data-slot":`detail-dialog-wrapper`,style:{"--sidebar-width":a.d,"--sidebar-width-icon":a.f,...o},className:(0,l.cn)(`group/sidebar-wrapper size-full min-h-[85dvh]`,`grid grid-cols-[auto_1fr] grid-rows-[auto_1fr]`,i),...c,children:s})})})}function _({title:e,sidebarTitle:t,content:n,footer:r}){return(0,u.jsx)(`div`,{className:`col-start-1 row-span-2 row-start-1`,children:(0,u.jsxs)(a.p,{children:[(0,u.jsx)(a.r,{children:(0,u.jsx)(a.i,{children:(0,u.jsx)(a.o,{children:(0,u.jsxs)(a.a,{size:`lg`,tabIndex:-1,children:[(0,u.jsx)(o.LunasLogo,{variant:`icon`,iconStyle:`solid`,size:`md`,className:`size-8 min-h-8 min-w-8`}),(0,u.jsxs)(`div`,{className:`grid flex-1 text-left text-sm leading-tight`,children:[(0,u.jsx)(`span`,{className:`truncate font-medium`,children:t||`Detail Dialog`}),(0,u.jsx)(`span`,{className:`truncate text-xs`,children:`Lunas Enterprise`})]})]})})})}),(0,u.jsx)(a.t,{children:n}),(0,u.jsx)(a.n,{children:r})]})})}function v({open:e,onOpenChange:t,children:n}){let r=(0,c.useCallback)(e=>{e.preventDefault(),e.stopPropagation()},[]);return(0,u.jsx)(d.Dialog.Root,{"data-slot":`detail-dialog`,open:e,onOpenChange:t,children:(0,u.jsx)(d.Dialog.Portal,{"data-slot":`detail-dialog-portal`,children:(0,u.jsx)(d.Dialog.Overlay,{"data-slot":`detail-dialog-overlay`,className:`data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 flex overflow-auto bg-black/50 p-4 data-[state=closed]:animate-out data-[state=open]:animate-in supports-backdrop-filter:backdrop-blur-xs`,children:(0,u.jsxs)(d.Dialog.Content,{"data-slot":`dialog-content`,className:(0,l.cn)(`relative z-50 m-auto grid`,`gap-4 overflow-hidden rounded-sm border-none bg-background p-0 shadow-dialog outline-none duration-200`,`size-full max-h-dvh min-h-160 min-w-264 max-w-svw`,`data-[state=closed]:animate-out data-[state=open]:animate-in`,`data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,`data-[state=closed]:zoom-out-80 data-[state=open]:zoom-in-80`),onInteractOutside:r,children:[n,(0,u.jsx)(d.Dialog.Close,{"data-slot":`dialog-close`,tabIndex:-1,asChild:!0,className:`absolute top-3 right-3`,children:(0,u.jsx)(`button`,{className:`flex cursor-pointer items-center justify-center rounded-full p-2 text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive active:bg-muted-weak active:text-text-positive-strong disabled:pointer-events-none disabled:opacity-60`,children:(0,u.jsx)(s.XIcon,{size:24})})})]})})})})}const y=({open:e,isLoading:t,title:n,createdAt:r,onOpenChange:i,sidebar:a,headerComponent:o,children:s})=>(0,u.jsx)(v,{open:e,onOpenChange:i,children:(0,u.jsxs)(g,{children:[(0,u.jsx)(_,{title:a?.title,content:a?.content,footer:a?.footer}),(0,u.jsx)(h,{title:n,createdAt:r,headerComponent:o}),(0,u.jsx)(p,{isLoading:t,children:s})]})});Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return y}});
|
|
2
|
-
//# sourceMappingURL=detail-dialog-uN5mrCa7.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detail-dialog-uN5mrCa7.cjs","names":["Flex","Suspense","Skeleton","DetailDialogSidebarTrigger","Suspense","Title","CalendarIcon","DateDisplay","useSidebarState","SidebarContext","TooltipProvider","SIDEBAR_WIDTH","SIDEBAR_WIDTH_ICON","Sidebar","DetailDialogSidebarHeader","DetailDialogSidebarMenu","DetailDialogSidebarMenuItem","DetailDialogSidebarMenuButton","LunasLogo","DetailDialogSidebarContent","DetailDialogSidebarFooter","DialogPrimitive","XIcon"],"sources":["../packages/components/dialogs/detail-dialog/components/content.tsx","../packages/components/dialogs/detail-dialog/components/header.tsx","../packages/components/dialogs/detail-dialog/components/provider.tsx","../packages/components/dialogs/detail-dialog/components/sidebar-panel.tsx","../packages/components/dialogs/detail-dialog/components/wrapper.tsx","../packages/components/dialogs/detail-dialog/index.tsx"],"sourcesContent":["'use client';\n\nimport { Suspense } from 'react';\n\nimport { Flex } from '@/components/layouts/flex';\n\nexport type DetailDialogContentProps = React.PropsWithChildren<{\n /** When `true`, replaces the content with a centered loading spinner. */\n isLoading?: boolean;\n}>;\n\nfunction DetailDialogLoader() {\n return (\n <Flex justify=\"center\" className=\"inset-shadow-sm min-h-0 bg-muted-muted\">\n <div className=\"loader\" />\n </Flex>\n );\n}\n\nexport function DetailDialogContent({ isLoading, children }: DetailDialogContentProps) {\n return (\n <main data-slot=\"detail-dialog-main\" className=\"@container col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1\">\n {isLoading ? (\n <DetailDialogLoader />\n ) : (\n <Suspense fallback={<DetailDialogLoader />}>\n <section data-slot=\"detail-dialog-body\" className=\"relative inset-shadow-sm grid min-h-0 snap-y grid-cols-1 overflow-y-auto bg-white\">\n {children}\n </section>\n </Suspense>\n )}\n </main>\n );\n}\n","'use client';\n\nimport { Suspense } from 'react';\n\nimport { CalendarIcon } from 'lucide-react';\n\nimport { Skeleton } from '@/components/ui/skeleton';\n\nimport { DateDisplay } from '@/components/data-display/date';\nimport { Title } from '@/components/typography/title';\nimport { DetailDialogSidebarTrigger } from './sidebar-core';\n\nexport type DetailDialogHeaderProps = {\n /** Primary title displayed in the dialog header. */\n title?: string;\n /** ISO string, `Date` object, or Unix timestamp shown as a formatted creation date below the title. */\n createdAt?: string | Date | number | null;\n /** Custom content replacing the default title/date block, e.g. for consumer-specific headers. Suspense-wrapped. */\n headerComponent?: React.ReactNode;\n};\n\nfunction DetailDialogHeaderSkeleton() {\n return (\n <div data-slot=\"detail-dialog-header-skeleton\" className=\"grid justify-items-start gap-1.5\">\n <Skeleton className=\"h-5 w-40\" />\n <Skeleton className=\"h-3 w-24\" />\n </div>\n );\n}\n\nexport function DetailDialogHeader({ title, createdAt, headerComponent }: DetailDialogHeaderProps) {\n return (\n <header\n data-slot=\"detail-dialog-header\"\n className=\"col-start-2 row-start-1 grid grid-cols-[auto_1fr] items-start gap-x-2.5 border-border-weak border-b bg-card py-2.5 pr-12 pl-2\"\n >\n <DetailDialogSidebarTrigger />\n <div data-slot=\"detail-dialog-header-content\" className=\"min-w-0 overflow-x-auto\">\n <Suspense fallback={<DetailDialogHeaderSkeleton />}>\n {headerComponent ?? (\n <div className=\"grid justify-items-start gap-0\">\n <Title level={5} className=\"line-clamp-1 truncate text-wrap\">\n {title || 'Detail Dialog'}\n </Title>\n {!!createdAt && (\n <div className=\"relative grid grid-flow-col items-center gap-1 text-text-positive-weak\">\n <CalendarIcon size={12} className=\"text-primary-strong\" />\n <p className=\"text-primary-strong text-xs\">Ngày Tạo</p>\n <DateDisplay showHoliday date={createdAt} format=\"medium\" />\n </div>\n )}\n </div>\n )}\n </Suspense>\n </div>\n </header>\n );\n}\n","'use client';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { TooltipProvider } from '@/components/ui/tooltip';\n\nimport { SIDEBAR_WIDTH, SIDEBAR_WIDTH_ICON, SidebarContext, useSidebarState } from './sidebar-core';\n\n/**\n * Context provider for `DetailDialog`'s sidebar/header/content grid shell. Manages sidebar\n * open/collapsed state (persisted via a cookie, shared with `SidebarProvider` via\n * `useSidebarState`) and renders the 2x2 grid wrapper — sidebar spanning both rows in column 1,\n * header/content in column 2. DetailDialog-specific, not a standalone-reusable provider like\n * `./sidebar-core`'s `SidebarProvider`.\n */\nexport function DetailDialogProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n /** Whether the sidebar is open by default (uncontrolled). Defaults to `true`. */\n defaultOpen?: boolean;\n /** Controlled open state. When provided the component becomes controlled. */\n open?: boolean;\n /** Callback fired when the open state changes in controlled mode. */\n onOpenChange?: (open: boolean) => void;\n}) {\n const contextValue = useSidebarState({ defaultOpen, open: openProp, onOpenChange: setOpenProp });\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"detail-dialog-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn('group/sidebar-wrapper size-full min-h-[85dvh]', 'grid grid-cols-[auto_1fr] grid-rows-[auto_1fr]', className)}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n","'use client';\n\nimport { LunasLogo } from '@/components/features/logo';\n\nimport {\n DetailDialogSidebarContent,\n DetailDialogSidebarFooter,\n DetailDialogSidebarHeader,\n DetailDialogSidebarMenu,\n DetailDialogSidebarMenuButton,\n DetailDialogSidebarMenuItem,\n Sidebar,\n} from './sidebar-core';\n\nexport type DetailDialogSidebarPanelProps = {\n /** Title shown in the collapsible sidebar header. Defaults to `'Detail Dialog'`. */\n title?: string;\n /** Title shown in the collapsible sidebar header. Defaults to `'Detail Dialog'`. */\n sidebarTitle?: string;\n /** Arbitrary content rendered inside the sidebar scrollable area. */\n content?: React.ReactNode;\n /** Arbitrary content rendered at the bottom of the sidebar footer. */\n footer?: React.ReactNode;\n};\n\nexport function DetailDialogSidebarPanel({ title, sidebarTitle, content, footer }: DetailDialogSidebarPanelProps) {\n return (\n <div className=\"col-start-1 row-span-2 row-start-1\">\n <Sidebar>\n <DetailDialogSidebarHeader>\n <DetailDialogSidebarMenu>\n <DetailDialogSidebarMenuItem>\n <DetailDialogSidebarMenuButton size=\"lg\" tabIndex={-1}>\n <LunasLogo variant=\"icon\" iconStyle=\"solid\" size=\"md\" className=\"size-8 min-h-8 min-w-8\" />\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{sidebarTitle || 'Detail Dialog'}</span>\n <span className=\"truncate text-xs\">Lunas Enterprise</span>\n </div>\n </DetailDialogSidebarMenuButton>\n </DetailDialogSidebarMenuItem>\n </DetailDialogSidebarMenu>\n </DetailDialogSidebarHeader>\n <DetailDialogSidebarContent>{content}</DetailDialogSidebarContent>\n <DetailDialogSidebarFooter>{footer}</DetailDialogSidebarFooter>\n </Sidebar>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { XIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Dialog as DialogPrimitive } from 'radix-ui';\n\nexport type DetailDialogWrapperProps = React.PropsWithChildren<{\n /** Controls whether the dialog is open. */\n open?: boolean;\n /** Callback invoked when the dialog open state changes. */\n onOpenChange?: (open: boolean) => void;\n}>;\n\n/**\n * Outer Radix Dialog scaffolding for `DetailDialog` — Root, Portal, Overlay (scrollable,\n * min-width/min-height-safe centering), Content (the dialog card), and the close button.\n * `children` render inside Content, alongside `DetailDialogProvider`'s grid shell.\n */\nexport function DetailDialogWrapper({ open, onOpenChange, children }: DetailDialogWrapperProps) {\n const handleInteractOutside = useCallback<NonNullable<React.ComponentProps<typeof DialogPrimitive.Content>['onInteractOutside']>>(event => {\n event.preventDefault();\n event.stopPropagation();\n }, []);\n\n return (\n <DialogPrimitive.Root data-slot=\"detail-dialog\" open={open} onOpenChange={onOpenChange}>\n <DialogPrimitive.Portal data-slot=\"detail-dialog-portal\">\n <DialogPrimitive.Overlay\n data-slot=\"detail-dialog-overlay\"\n className=\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 flex overflow-auto bg-black/50 p-4 data-[state=closed]:animate-out data-[state=open]:animate-in supports-backdrop-filter:backdrop-blur-xs\"\n >\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n 'relative z-50 m-auto grid',\n 'gap-4 overflow-hidden rounded-sm border-none bg-background p-0 shadow-dialog outline-none duration-200',\n 'size-full max-h-dvh min-h-160 min-w-264 max-w-svw',\n 'data-[state=closed]:animate-out data-[state=open]:animate-in',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-80 data-[state=open]:zoom-in-80'\n )}\n onInteractOutside={handleInteractOutside}\n >\n {children}\n\n <DialogPrimitive.Close data-slot=\"dialog-close\" tabIndex={-1} asChild className=\"absolute top-3 right-3\">\n <button className=\"flex cursor-pointer items-center justify-center rounded-full p-2 text-text-positive-weak transition-colors hover:bg-muted-muted hover:text-text-positive active:bg-muted-weak active:text-text-positive-strong disabled:pointer-events-none disabled:opacity-60\">\n <XIcon size={24} />\n </button>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPrimitive.Overlay>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n","'use client';\n\nimport { DetailDialogContent } from './components/content';\nimport { DetailDialogHeader } from './components/header';\nimport { DetailDialogProvider } from './components/provider';\nimport { DetailDialogSidebarPanel, type DetailDialogSidebarPanelProps } from './components/sidebar-panel';\nimport { DetailDialogWrapper } from './components/wrapper';\n\nexport type DetailDialogProps = {\n /** Controls whether the dialog is open. */\n open?: boolean;\n /** When `true`, replaces the main content area with a centered loading spinner. */\n isLoading?: boolean;\n /** Primary title displayed in the dialog header. */\n title?: string;\n /** ISO string, `Date` object, or Unix timestamp shown as a formatted creation date below the title. */\n createdAt?: string | Date | number | null;\n /** Optional sidebar configuration — title, body content, and footer content. */\n sidebar?: DetailDialogSidebarPanelProps;\n /** Custom content replacing the default title/date block in the header. Suspense-wrapped. */\n headerComponent?: React.ReactNode;\n /** Callback invoked when the dialog open state changes. */\n onOpenChange?: (open: boolean) => void;\n};\n\n/**\n * Full-screen detail dialog with a collapsible sidebar, a header with creation date, and a scrollable content area.\n *\n * @example\n * ```tsx\n * import { DetailDialog } from '@customafk/lunas-ui/dialogs/detail-dialog';\n *\n * <DetailDialog\n * open={open}\n * title=\"Order #1234\"\n * createdAt=\"2024-01-15T09:00:00Z\"\n * sidebar={{ title: 'Navigation', content: <nav>...</nav> }}\n * onOpenChange={setOpen}\n * >\n * <p>Detail content goes here.</p>\n * </DetailDialog>\n * ```\n */\nexport const DetailDialog: React.FC<React.PropsWithChildren<DetailDialogProps>> = ({\n open,\n isLoading,\n title,\n createdAt,\n onOpenChange,\n sidebar,\n headerComponent,\n children,\n}) => {\n return (\n <DetailDialogWrapper open={open} onOpenChange={onOpenChange}>\n <DetailDialogProvider>\n <DetailDialogSidebarPanel title={sidebar?.title} content={sidebar?.content} footer={sidebar?.footer} />\n <DetailDialogHeader title={title} createdAt={createdAt} headerComponent={headerComponent} />\n <DetailDialogContent isLoading={isLoading}>{children}</DetailDialogContent>\n </DetailDialogProvider>\n </DetailDialogWrapper>\n );\n};\n"],"mappings":"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"}
|
package/dist/filter-B5EnnL9I.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./ui/button.cjs"),t=require("./tables-CS3NhgTc.cjs"),n=require("./ui/checkbox.cjs"),r=require("./ui/dropdown-menu.cjs"),i=require("./ui/resizable.cjs"),a=require("./ui/popover.cjs"),o=require("./ui/input.cjs"),s=require("./ui/separator.cjs"),c=require("./ui/label.cjs"),l=require("./ui/select.cjs");let u=require("lucide-react"),d=require("react"),f=require("@customafk/react-toolkit/utils"),p=require("react/jsx-runtime");const m={tag:(0,p.jsx)(u.TagIcon,{size:14}),"single-tag":(0,p.jsx)(u.TagIcon,{size:14}),"date-range":(0,p.jsx)(u.CalendarIcon,{size:14}),number:(0,p.jsx)(u.HashIcon,{size:14}),text:(0,p.jsx)(u.TypeIcon,{size:14}),boolean:(0,p.jsx)(u.ToggleLeftIcon,{size:14})},h=[{value:`eq`,label:`Bằng (=)`},{value:`ne`,label:`Không bằng (≠)`},{value:`gt`,label:`Lớn hơn (>)`},{value:`gte`,label:`Ít nhất (≥)`},{value:`lt`,label:`Nhỏ hơn (<)`},{value:`lte`,label:`Nhiều nhất (≤)`},{value:`between`,label:`Trong khoảng`}],g=[{value:`contains`,label:`Chứa`},{value:`equals`,label:`Bằng`},{value:`starts-with`,label:`Bắt đầu bằng`},{value:`ends-with`,label:`Kết thúc bằng`}];function _(e,t){switch(e.type){case`single-tag`:return e.value?t.options?.find(t=>t.value===e.value)?.label??e.value:`Chưa đặt`;case`tag`:return e.values.length?e.values.map(e=>t.options?.find(t=>t.value===e)?.label??e).join(`, `):`Chưa đặt`;case`date-range`:return!e.from&&!e.to?`Ngày không xác định`:e.from&&e.to?`${e.from} → ${e.to}`:e.from?`từ ${e.from}`:`đến ${e.to}`;case`number`:{let t={eq:`=`,ne:`≠`,gt:`>`,gte:`≥`,lt:`<`,lte:`≤`,between:`trong khoảng`}[e.operator];return e.value===void 0?t:e.operator===`between`?`${t} ${e.value} – ${e.valueTo??`?`}`:`${t} ${e.value}`}case`text`:{let t={contains:`chứa`,equals:`là`,"starts-with":`bắt đầu bằng`,"ends-with":`kết thúc bằng`}[e.operator];return e.value?`${t} "${e.value}"`:t}case`boolean`:return e.value===null?`Không xác định`:e.value?`Có`:`Không`}}const v=({value:e,definition:t,onChange:r})=>(0,p.jsx)(`div`,{className:`flex flex-col gap-1 p-3`,children:(t.options??[]).length===0?(0,p.jsx)(`p`,{className:`text-xs text-text-positive-muted`,children:`Không có tùy chọn`}):t.options.map(t=>(0,p.jsxs)(c.Label,{className:(0,f.cn)(`flex items-center gap-2 bg-secondary-bg-subtle hover:bg-secondary-muted px-4 py-2 rounded transition-colors`,e.values.includes(t.value)&&`bg-primary-muted hover:bg-primary-subtle`),children:[(0,p.jsx)(n.Checkbox,{checked:e.values.includes(t.value),onCheckedChange:n=>{r({type:`tag`,values:n?[...e.values,t.value]:e.values.filter(e=>e!==t.value)})}}),(0,p.jsx)(`span`,{className:`text-sm`,children:t.label})]},t.value))}),y=({value:e,definition:t,onChange:r})=>(0,p.jsx)(`div`,{className:`flex flex-col gap-1 p-3`,children:(t.options??[]).length===0?(0,p.jsx)(`p`,{className:`text-xs text-text-positive-muted`,children:`Không có tùy chọn`}):t.options.map(t=>(0,p.jsxs)(c.Label,{className:(0,f.cn)(`flex items-center gap-2 bg-secondary-bg-subtle hover:bg-secondary-muted px-4 py-2 rounded transition-colors`,e.value===t.value&&`bg-primary-muted hover:bg-primary-subtle`),children:[(0,p.jsx)(n.Checkbox,{checked:e.value===t.value,onCheckedChange:e=>{r({type:`single-tag`,value:e?t.value:null})}}),(0,p.jsx)(`span`,{className:`text-sm`,children:t.label})]},t.value))}),b=({value:e,onChange:t})=>(0,p.jsxs)(`div`,{className:`flex flex-col gap-3 p-3`,children:[(0,p.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,p.jsx)(`span`,{className:`text-text-positive-muted text-xs`,children:`Từ ngày`}),(0,p.jsx)(o.Input,{type:`date`,size:`md`,value:e.from??``,onValueChange:n=>t({...e,from:n||void 0})})]}),(0,p.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,p.jsx)(`span`,{className:`text-text-positive-muted text-xs`,children:`Đến ngày`}),(0,p.jsx)(o.Input,{type:`date`,size:`md`,value:e.to??``,onValueChange:n=>t({...e,to:n||void 0})})]})]}),x=({value:e,onChange:t})=>(0,p.jsxs)(`div`,{className:`flex flex-col gap-3 p-3`,children:[(0,p.jsxs)(l.Select,{value:e.operator,onValueChange:n=>t({...e,operator:n}),children:[(0,p.jsx)(l.SelectTrigger,{size:`sm`,children:(0,p.jsx)(l.SelectValue,{})}),(0,p.jsx)(l.SelectContent,{children:h.map(e=>(0,p.jsx)(l.SelectItem,{value:e.value,children:e.label},e.value))})]}),(0,p.jsx)(o.Input,{type:`number`,size:`md`,placeholder:`Giá trị`,value:e.value??``,onValueChange:n=>t({...e,value:n?Number(n):void 0})}),e.operator===`between`&&(0,p.jsx)(o.Input,{type:`number`,size:`md`,placeholder:`Đến giá trị`,value:e.valueTo??``,onValueChange:n=>t({...e,valueTo:n?Number(n):void 0})})]}),S=({value:e,onChange:t})=>(0,p.jsxs)(`div`,{className:`flex flex-col gap-3 p-3`,children:[(0,p.jsxs)(l.Select,{value:e.operator,onValueChange:n=>t({...e,operator:n}),children:[(0,p.jsx)(l.SelectTrigger,{size:`sm`,children:(0,p.jsx)(l.SelectValue,{})}),(0,p.jsx)(l.SelectContent,{children:g.map(e=>(0,p.jsx)(l.SelectItem,{value:e.value,children:e.label},e.value))})]}),(0,p.jsx)(o.Input,{type:`text`,size:`md`,placeholder:`Nhập văn bản...`,value:e.value,onValueChange:n=>t({...e,value:n})})]}),C=[{label:`Có`,value:!0},{label:`Không`,value:!1},{label:`Không xác định`,value:null}],w=({value:t,onChange:n})=>(0,p.jsx)(`div`,{className:`flex flex-col gap-1 p-3`,children:C.map(({label:r,value:i})=>(0,p.jsx)(e.Button,{type:`button`,tabIndex:-1,variant:`outline`,className:(0,f.cn)(`rounded px-3 py-1.5 text-left text-sm transition-colors`,t.value===i?`bg-primary-muted font-medium`:`hover:bg-muted-bg-subtle`),onClick:()=>n({type:`boolean`,value:i}),children:r},r))});function T({value:e,definition:t,onChange:n}){switch(e.type){case`tag`:return(0,p.jsx)(v,{value:e,definition:t,onChange:n});case`single-tag`:return(0,p.jsx)(y,{value:e,definition:t,onChange:n});case`date-range`:return(0,p.jsx)(b,{value:e,onChange:n});case`number`:return(0,p.jsx)(x,{value:e,onChange:n});case`text`:return(0,p.jsx)(S,{value:e,onChange:n});case`boolean`:return(0,p.jsx)(w,{value:e,onChange:n})}}const E=({filter:t,definition:n,onRemove:r,onUpdate:i})=>(0,p.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,p.jsxs)(a.Popover,{children:[(0,p.jsx)(a.PopoverTrigger,{asChild:!0,children:(0,p.jsxs)(e.Button,{type:`button`,variant:`outline`,color:`muted`,className:`flex-1 bg-white max-w-[calc(100%-32px)] justify-start`,innerClassName:`flex truncate gap-1.5`,children:[(0,p.jsx)(`span`,{className:`shrink-0 text-text-positive font-medium`,children:n.label}),(0,p.jsx)(`span`,{className:`truncate text-xs text-text-positive-weak`,children:_(t.value,n)})]})}),(0,p.jsxs)(a.PopoverContent,{className:`w-64 p-0`,align:`start`,side:`bottom`,children:[(0,p.jsx)(`div`,{className:`border-b border-border px-3 py-2`,children:(0,p.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,p.jsx)(`span`,{className:`text-text-positive-muted`,children:m[n.type]}),(0,p.jsx)(`p`,{className:`font-medium`,children:n.label})]})}),(0,p.jsx)(T,{value:t.value,definition:n,onChange:i})]})]}),(0,p.jsx)(e.Button,{type:`button`,size:`icon`,variant:`soft`,color:`danger`,className:`shrink`,onClick:r,children:(0,p.jsx)(u.Trash2Icon,{size:13})})]}),D=()=>{let{filterDefinitions:n,activeFilters:a,addFilter:o,removeFilter:c,updateFilter:l}=t.X(),[h,g]=(0,d.useState)(null),_=n.filter(e=>!a.some(t=>t.definitionId===e.id));return(0,p.jsx)(i.ResizablePanel,{defaultSize:25,className:(0,f.cn)(`bg-card`,h===null?`max-w-8!`:`min-w-64`),children:(0,p.jsxs)(`div`,{className:`relative z-20 flex size-full bg-muted-bg-subtle`,children:[(0,p.jsx)(`div`,{className:`min-w-0 flex-1 overflow-hidden`,children:(0,p.jsx)(d.Activity,{mode:h===`filters`?`visible`:`hidden`,children:(0,p.jsxs)(`div`,{className:`flex size-full flex-col gap-2 p-4`,children:[(0,p.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,p.jsx)(`p`,{className:`font-medium`,children:`Bộ lọc`}),(0,p.jsxs)(r.DropdownMenu,{children:[(0,p.jsx)(r.DropdownMenuTrigger,{asChild:!0,children:(0,p.jsxs)(e.Button,{variant:`outline`,color:`muted`,disabled:_.length===0,children:[(0,p.jsx)(u.ListFilterPlus,{size:13}),`Thêm bộ lọc`]})}),(0,p.jsx)(r.DropdownMenuContent,{align:`end`,children:_.map(e=>(0,p.jsxs)(r.DropdownMenuItem,{className:`flex items-center gap-2`,onClick:()=>o(e.id),children:[m[e.type],e.label]},e.id))})]})]}),(0,p.jsx)(s.Separator,{}),a.length===0?(0,p.jsx)(`p`,{className:`py-6 text-center text-xs text-text-positive-muted`,children:`Không có bộ lọc nào`}):(0,p.jsx)(`div`,{className:`flex flex-col gap-2 pt-1`,children:a.map(e=>{let t=n.find(t=>t.id===e.definitionId);return t?(0,p.jsx)(E,{filter:e,definition:t,onRemove:()=>c(e.id),onUpdate:t=>l(e.id,t)},e.id):null})})]})})}),(0,p.jsxs)(`div`,{className:`flex h-full flex-col border-l border-border bg-muted-bg-subtle text-sm`,children:[(0,p.jsxs)(`button`,{type:`button`,className:(0,f.cn)(`relative flex h-32 cursor-pointer flex-col items-center gap-y-2 p-2 py-4`,h===`filters`&&`bg-card`),onClick:()=>g(h===`filters`?null:`filters`),children:[(0,p.jsx)(u.ListFilterIcon,{size:18}),a.length>0&&(0,p.jsx)(`span`,{className:`absolute top-2 right-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[10px] leading-none text-primary-foreground`,children:a.length}),(0,p.jsx)(`span`,{className:`text-nowrap [writing-mode:vertical-lr]`,children:`Bộ lọc`})]}),(0,p.jsx)(s.Separator,{})]})]})})};exports.UITableFilter=D;
|
|
2
|
-
//# sourceMappingURL=filter-B5EnnL9I.cjs.map
|
package/dist/filter-BCNjqiBx.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{Button as e}from"./ui/button.mjs";import{X as t}from"./tables-7_KgoyS-.mjs";import{Checkbox as n}from"./ui/checkbox.mjs";import{DropdownMenu as r,DropdownMenuContent as i,DropdownMenuItem as a,DropdownMenuTrigger as o}from"./ui/dropdown-menu.mjs";import{ResizablePanel as s}from"./ui/resizable.mjs";import{Popover as c,PopoverContent as l,PopoverTrigger as u}from"./ui/popover.mjs";import{Input as d}from"./ui/input.mjs";import{Separator as f}from"./ui/separator.mjs";import{Label as p}from"./ui/label.mjs";import{Select as m,SelectContent as h,SelectItem as g,SelectTrigger as _,SelectValue as v}from"./ui/select.mjs";import{CalendarIcon as y,HashIcon as b,ListFilterIcon as x,ListFilterPlus as S,TagIcon as C,ToggleLeftIcon as w,Trash2Icon as T,TypeIcon as E}from"lucide-react";import{Activity as D,useState as O}from"react";import{cn as k}from"@customafk/react-toolkit/utils";import{jsx as A,jsxs as j}from"react/jsx-runtime";const M={tag:A(C,{size:14}),"single-tag":A(C,{size:14}),"date-range":A(y,{size:14}),number:A(b,{size:14}),text:A(E,{size:14}),boolean:A(w,{size:14})},N=[{value:`eq`,label:`Bằng (=)`},{value:`ne`,label:`Không bằng (≠)`},{value:`gt`,label:`Lớn hơn (>)`},{value:`gte`,label:`Ít nhất (≥)`},{value:`lt`,label:`Nhỏ hơn (<)`},{value:`lte`,label:`Nhiều nhất (≤)`},{value:`between`,label:`Trong khoảng`}],P=[{value:`contains`,label:`Chứa`},{value:`equals`,label:`Bằng`},{value:`starts-with`,label:`Bắt đầu bằng`},{value:`ends-with`,label:`Kết thúc bằng`}];function F(e,t){switch(e.type){case`single-tag`:return e.value?t.options?.find(t=>t.value===e.value)?.label??e.value:`Chưa đặt`;case`tag`:return e.values.length?e.values.map(e=>t.options?.find(t=>t.value===e)?.label??e).join(`, `):`Chưa đặt`;case`date-range`:return!e.from&&!e.to?`Ngày không xác định`:e.from&&e.to?`${e.from} → ${e.to}`:e.from?`từ ${e.from}`:`đến ${e.to}`;case`number`:{let t={eq:`=`,ne:`≠`,gt:`>`,gte:`≥`,lt:`<`,lte:`≤`,between:`trong khoảng`}[e.operator];return e.value===void 0?t:e.operator===`between`?`${t} ${e.value} – ${e.valueTo??`?`}`:`${t} ${e.value}`}case`text`:{let t={contains:`chứa`,equals:`là`,"starts-with":`bắt đầu bằng`,"ends-with":`kết thúc bằng`}[e.operator];return e.value?`${t} "${e.value}"`:t}case`boolean`:return e.value===null?`Không xác định`:e.value?`Có`:`Không`}}const I=({value:e,definition:t,onChange:r})=>A(`div`,{className:`flex flex-col gap-1 p-3`,children:(t.options??[]).length===0?A(`p`,{className:`text-xs text-text-positive-muted`,children:`Không có tùy chọn`}):t.options.map(t=>j(p,{className:k(`flex items-center gap-2 bg-secondary-bg-subtle hover:bg-secondary-muted px-4 py-2 rounded transition-colors`,e.values.includes(t.value)&&`bg-primary-muted hover:bg-primary-subtle`),children:[A(n,{checked:e.values.includes(t.value),onCheckedChange:n=>{r({type:`tag`,values:n?[...e.values,t.value]:e.values.filter(e=>e!==t.value)})}}),A(`span`,{className:`text-sm`,children:t.label})]},t.value))}),L=({value:e,definition:t,onChange:r})=>A(`div`,{className:`flex flex-col gap-1 p-3`,children:(t.options??[]).length===0?A(`p`,{className:`text-xs text-text-positive-muted`,children:`Không có tùy chọn`}):t.options.map(t=>j(p,{className:k(`flex items-center gap-2 bg-secondary-bg-subtle hover:bg-secondary-muted px-4 py-2 rounded transition-colors`,e.value===t.value&&`bg-primary-muted hover:bg-primary-subtle`),children:[A(n,{checked:e.value===t.value,onCheckedChange:e=>{r({type:`single-tag`,value:e?t.value:null})}}),A(`span`,{className:`text-sm`,children:t.label})]},t.value))}),R=({value:e,onChange:t})=>j(`div`,{className:`flex flex-col gap-3 p-3`,children:[j(`div`,{className:`flex flex-col gap-1`,children:[A(`span`,{className:`text-text-positive-muted text-xs`,children:`Từ ngày`}),A(d,{type:`date`,size:`md`,value:e.from??``,onValueChange:n=>t({...e,from:n||void 0})})]}),j(`div`,{className:`flex flex-col gap-1`,children:[A(`span`,{className:`text-text-positive-muted text-xs`,children:`Đến ngày`}),A(d,{type:`date`,size:`md`,value:e.to??``,onValueChange:n=>t({...e,to:n||void 0})})]})]}),z=({value:e,onChange:t})=>j(`div`,{className:`flex flex-col gap-3 p-3`,children:[j(m,{value:e.operator,onValueChange:n=>t({...e,operator:n}),children:[A(_,{size:`sm`,children:A(v,{})}),A(h,{children:N.map(e=>A(g,{value:e.value,children:e.label},e.value))})]}),A(d,{type:`number`,size:`md`,placeholder:`Giá trị`,value:e.value??``,onValueChange:n=>t({...e,value:n?Number(n):void 0})}),e.operator===`between`&&A(d,{type:`number`,size:`md`,placeholder:`Đến giá trị`,value:e.valueTo??``,onValueChange:n=>t({...e,valueTo:n?Number(n):void 0})})]}),B=({value:e,onChange:t})=>j(`div`,{className:`flex flex-col gap-3 p-3`,children:[j(m,{value:e.operator,onValueChange:n=>t({...e,operator:n}),children:[A(_,{size:`sm`,children:A(v,{})}),A(h,{children:P.map(e=>A(g,{value:e.value,children:e.label},e.value))})]}),A(d,{type:`text`,size:`md`,placeholder:`Nhập văn bản...`,value:e.value,onValueChange:n=>t({...e,value:n})})]}),V=[{label:`Có`,value:!0},{label:`Không`,value:!1},{label:`Không xác định`,value:null}],H=({value:t,onChange:n})=>A(`div`,{className:`flex flex-col gap-1 p-3`,children:V.map(({label:r,value:i})=>A(e,{type:`button`,tabIndex:-1,variant:`outline`,className:k(`rounded px-3 py-1.5 text-left text-sm transition-colors`,t.value===i?`bg-primary-muted font-medium`:`hover:bg-muted-bg-subtle`),onClick:()=>n({type:`boolean`,value:i}),children:r},r))});function U({value:e,definition:t,onChange:n}){switch(e.type){case`tag`:return A(I,{value:e,definition:t,onChange:n});case`single-tag`:return A(L,{value:e,definition:t,onChange:n});case`date-range`:return A(R,{value:e,onChange:n});case`number`:return A(z,{value:e,onChange:n});case`text`:return A(B,{value:e,onChange:n});case`boolean`:return A(H,{value:e,onChange:n})}}const W=({filter:t,definition:n,onRemove:r,onUpdate:i})=>j(`div`,{className:`flex items-center gap-1`,children:[j(c,{children:[A(u,{asChild:!0,children:j(e,{type:`button`,variant:`outline`,color:`muted`,className:`flex-1 bg-white max-w-[calc(100%-32px)] justify-start`,innerClassName:`flex truncate gap-1.5`,children:[A(`span`,{className:`shrink-0 text-text-positive font-medium`,children:n.label}),A(`span`,{className:`truncate text-xs text-text-positive-weak`,children:F(t.value,n)})]})}),j(l,{className:`w-64 p-0`,align:`start`,side:`bottom`,children:[A(`div`,{className:`border-b border-border px-3 py-2`,children:j(`div`,{className:`flex items-center gap-1.5`,children:[A(`span`,{className:`text-text-positive-muted`,children:M[n.type]}),A(`p`,{className:`font-medium`,children:n.label})]})}),A(U,{value:t.value,definition:n,onChange:i})]})]}),A(e,{type:`button`,size:`icon`,variant:`soft`,color:`danger`,className:`shrink`,onClick:r,children:A(T,{size:13})})]}),G=()=>{let{filterDefinitions:n,activeFilters:c,addFilter:l,removeFilter:u,updateFilter:d}=t(),[p,m]=O(null),h=n.filter(e=>!c.some(t=>t.definitionId===e.id));return A(s,{defaultSize:25,className:k(`bg-card`,p===null?`max-w-8!`:`min-w-64`),children:j(`div`,{className:`relative z-20 flex size-full bg-muted-bg-subtle`,children:[A(`div`,{className:`min-w-0 flex-1 overflow-hidden`,children:A(D,{mode:p===`filters`?`visible`:`hidden`,children:j(`div`,{className:`flex size-full flex-col gap-2 p-4`,children:[j(`div`,{className:`flex items-center justify-between gap-2`,children:[A(`p`,{className:`font-medium`,children:`Bộ lọc`}),j(r,{children:[A(o,{asChild:!0,children:j(e,{variant:`outline`,color:`muted`,disabled:h.length===0,children:[A(S,{size:13}),`Thêm bộ lọc`]})}),A(i,{align:`end`,children:h.map(e=>j(a,{className:`flex items-center gap-2`,onClick:()=>l(e.id),children:[M[e.type],e.label]},e.id))})]})]}),A(f,{}),c.length===0?A(`p`,{className:`py-6 text-center text-xs text-text-positive-muted`,children:`Không có bộ lọc nào`}):A(`div`,{className:`flex flex-col gap-2 pt-1`,children:c.map(e=>{let t=n.find(t=>t.id===e.definitionId);return t?A(W,{filter:e,definition:t,onRemove:()=>u(e.id),onUpdate:t=>d(e.id,t)},e.id):null})})]})})}),j(`div`,{className:`flex h-full flex-col border-l border-border bg-muted-bg-subtle text-sm`,children:[j(`button`,{type:`button`,className:k(`relative flex h-32 cursor-pointer flex-col items-center gap-y-2 p-2 py-4`,p===`filters`&&`bg-card`),onClick:()=>m(p===`filters`?null:`filters`),children:[A(x,{size:18}),c.length>0&&A(`span`,{className:`absolute top-2 right-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[10px] leading-none text-primary-foreground`,children:c.length}),A(`span`,{className:`text-nowrap [writing-mode:vertical-lr]`,children:`Bộ lọc`})]}),A(f,{})]})]})})};export{G as UITableFilter};
|
|
2
|
-
//# sourceMappingURL=filter-BCNjqiBx.mjs.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
const e=require("./tables-CS3NhgTc.cjs"),t=require("./ui/input.cjs");let n=require("lucide-react"),r=require("react"),i=require("@customafk/react-toolkit/utils"),a=require("react/jsx-runtime"),o=require("@customafk/react-toolkit/hooks/useDebounceCallback");function s(e){if(e==null)return``;if(typeof e==`number`)return String(e);if(typeof e==`boolean`)return e?`true`:`false`;let t=String(e);return t.includes(`,`)||t.includes(`"`)||t.includes(`
|
|
2
|
-
`)||t.includes(`\r`)?`"${t.replace(/"/g,`""`)}"`:t}function c(e){if(e.length===0)return``;let t=e[0].map(e=>s(e.label)),n=e.map(e=>e.map(e=>s(e.value)).join(`,`));return[t.join(`,`),...n].join(`
|
|
3
|
-
`)}function l(e,t){let n=c(e);if(!n)return;let r=new Blob([n],{type:`text/csv;charset=utf-8;`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=`${t}.csv`,a.click(),URL.revokeObjectURL(i)}const u=({onSearch:e,onChange:r,...i})=>{let s=(0,o.useDebounceCallback)(t=>{e?.(t)},500);return(0,a.jsxs)(`div`,{className:`relative w-full max-w-80 flex-1`,children:[(0,a.jsx)(t.Input,{...i,size:`lg`,type:`search`,placeholder:`Tìm kiếm...`,className:`flex-1 ps-9 pe-9`,onChange:e=>{r?.(e),s(e.target.value??``)}}),(0,a.jsx)(`div`,{className:`pointer-events-none absolute inset-y-0 inset-s-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50`,children:(0,a.jsx)(n.SearchIcon,{size:16})}),(0,a.jsx)(`button`,{className:`absolute inset-y-0 inset-e-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50`,"aria-label":`Submit search`,type:`submit`,children:(0,a.jsx)(n.ArrowRightIcon,{size:16,"aria-hidden":`true`})})]})},d=({children:e,disabled:t,onClick:n,className:r,...o})=>(0,a.jsx)(`button`,{type:`button`,disabled:t,className:(0,i.cn)(`flex cursor-pointer items-center gap-x-1 rounded-sm border border-border bg-background p-2.5 text-sm text-text-positive-weak outline-none transition-all hover:shadow-card focus:border-border-emphasis focus:bg-muted-muted active:border-border-emphasis active:bg-muted-muted active:text-text-positive disabled:pointer-events-none disabled:cursor-default disabled:opacity-60 [&_svg]:size-3.5`,r),onClick:n,...o,children:e}),f=({onCreate:t,onDownload:i,onRefresh:o})=>{let{table:s,csvData:c,csvFileName:u,title:f,showAnalysisPanel:p,summary:m}=e.Y(),{isOpen:h,toggle:g}=e.q(),{isOpen:_,toggle:v}=e.Z(),y=(0,r.useCallback)(()=>{if(i){i();return}if(!c||c.length===0)return;let e=s.getSelectedRowModel().flatRows;l(e.length>0?e.map(e=>c[e.index]).filter(Boolean):c,u||f)},[i,c,u,s,f]),b=!!(i||c&&c.length>0);return(0,a.jsxs)(`div`,{className:`flex [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none`,children:[(0,a.jsx)(d,{disabled:!t,onClick:e=>{t?.(),e.stopPropagation(),e.preventDefault()},children:(0,a.jsx)(n.CirclePlus,{})}),(0,a.jsx)(d,{disabled:!o,onClick:e=>{o?.(),e.stopPropagation(),e.preventDefault()},children:(0,a.jsx)(n.RefreshCwIcon,{})}),(0,a.jsx)(d,{disabled:!b,onClick:e=>{y(),e.stopPropagation(),e.preventDefault()},children:(0,a.jsx)(n.DownloadIcon,{})}),m&&m.length>0&&(0,a.jsx)(d,{onClick:e=>{v(),e.stopPropagation(),e.preventDefault()},"aria-pressed":_,"aria-label":_?`Ẩn tổng quan`:`Hiện tổng quan`,className:_?`bg-muted-muted text-text-positive`:void 0,children:(0,a.jsx)(n.LayoutDashboardIcon,{})}),p&&(0,a.jsx)(d,{onClick:e=>{g(),e.stopPropagation(),e.preventDefault()},"aria-pressed":h,className:h?`bg-muted-muted text-text-positive`:void 0,children:(0,a.jsx)(n.BarChart2Icon,{})})]})},p=({children:t})=>{let{title:n,description:r,headerActions:i}=e.Y();return(0,a.jsxs)(`div`,{"data-slot":`table-tooltip`,className:`relative flex w-full flex-col gap-2 px-2 py-0 text-sm`,children:[(0,a.jsxs)(`div`,{className:`flex w-full items-start justify-between gap-4`,children:[(0,a.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,a.jsx)(`h3`,{className:`font-semibold text-base text-text-positive`,children:n}),r&&(0,a.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:r})]}),i&&(0,a.jsx)(`div`,{className:`flex items-center gap-2 shrink-0`,children:i})]}),(0,a.jsx)(`div`,{className:`flex w-full flex-1 justify-between gap-x-2`,children:t})]})};p.displayName=`UITableTooltip`,exports.UITableTooltip=p,exports.UITableTooltipActions=f,exports.UITableTooltipFilter=u;
|
|
4
|
-
//# sourceMappingURL=tooltip-BcQG6Zw9.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip-BcQG6Zw9.cjs","names":["Input","SearchIcon","ArrowRightIcon","useUITableContext","useUITableAnalysisContext","useUITableSummaryContext","CirclePlus","RefreshCwIcon","DownloadIcon","LayoutDashboardIcon","BarChart2Icon"],"sources":["../packages/components/features/tables/utils/csv.ts","../packages/components/features/tables/components/table/tooltip.tsx"],"sourcesContent":["'use client';\n\nimport type { CsvCell } from '../types';\n\nfunction formatCell(value: CsvCell['value']): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'number') return String(value);\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n const str = String(value);\n if (str.includes(',') || str.includes('\"') || str.includes('\\n') || str.includes('\\r')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n}\n\nexport function buildCsvContent(rows: CsvCell[][]): string {\n if (rows.length === 0) return '';\n const headers = rows[0].map(cell => formatCell(cell.label));\n const dataRows = rows.map(row => row.map(cell => formatCell(cell.value)).join(','));\n return [headers.join(','), ...dataRows].join('\\n');\n}\n\nexport function downloadCsv(rows: CsvCell[][], fileName: string): void {\n const content = buildCsvContent(rows);\n if (!content) return;\n const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${fileName}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n","/**\n * @file tooltip.tsx\n * Toolbar components rendered above the table: a debounced search input,\n * an action button group (create / refresh / download), and the outer\n * toolbar shell that displays the table title.\n */\nimport { useCallback } from 'react';\n\nimport { ArrowRightIcon, BarChart2Icon, CirclePlus, DownloadIcon, LayoutDashboardIcon, RefreshCwIcon, SearchIcon } from 'lucide-react';\n\nimport { useDebounceCallback } from '@customafk/react-toolkit/hooks/useDebounceCallback';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\n\nimport { useUITableAnalysisContext, useUITableContext, useUITableSummaryContext } from '../../hooks/use-context';\nimport { downloadCsv } from '../../utils/csv';\n\n/**\n * Debounced search input rendered inside the table toolbar.\n *\n * Fires `onSearch` 500 ms after the user stops typing and delegates all other\n * native input events via the spread `props`.\n *\n * @example\n * ```tsx\n * import { UITableTooltipFilter } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltipFilter\n * placeholder=\"Search users…\"\n * onSearch={value => setQuery(value)}\n * />\n * ```\n */\nexport const UITableTooltipFilter: React.FC<\n Omit<React.ComponentProps<typeof Input>, 'className'> & {\n onSearch?: (value: string) => void;\n }\n> = ({ onSearch, onChange, ...props }) => {\n const debouncedSearch = useDebounceCallback((value: string) => {\n onSearch?.(value);\n }, 500);\n return (\n <div className=\"relative w-full max-w-80 flex-1\">\n <Input\n {...props}\n size=\"lg\"\n type=\"search\"\n placeholder=\"Tìm kiếm...\"\n className=\"flex-1 ps-9 pe-9\"\n onChange={e => {\n onChange?.(e);\n debouncedSearch(e.target.value ?? '');\n }}\n />\n <div className=\"pointer-events-none absolute inset-y-0 inset-s-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50\">\n <SearchIcon size={16} />\n </div>\n <button\n className=\"absolute inset-y-0 inset-e-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Submit search\"\n type=\"submit\"\n >\n <ArrowRightIcon size={16} aria-hidden=\"true\" />\n </button>\n </div>\n );\n};\n\nconst ActionButton: React.FC<React.PropsWithChildren<React.ComponentProps<'button'>>> = ({ children, disabled, onClick, className, ...props }) => {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'flex cursor-pointer items-center gap-x-1 rounded-sm border border-border bg-background p-2.5 text-sm text-text-positive-weak outline-none transition-all hover:shadow-card focus:border-border-emphasis focus:bg-muted-muted active:border-border-emphasis active:bg-muted-muted active:text-text-positive disabled:pointer-events-none disabled:cursor-default disabled:opacity-60 [&_svg]:size-3.5',\n className\n )}\n onClick={onClick}\n {...props}\n >\n {children}\n </button>\n );\n};\n\n/**\n * Grouped action buttons (create, refresh, download) displayed in the table\n * toolbar.\n *\n * Each button is disabled automatically when the corresponding handler prop is\n * omitted, so only the actions relevant to a given table need to be provided.\n * A toggle for `UITableSummaryBar` appears automatically when `summary` is\n * non-empty, and a toggle for `UITableAnalysisPanel` appears when\n * `showAnalysisPanel` is `true` (both set on `UITableProvider`).\n *\n * @example\n * ```tsx\n * import { UITableTooltipActions } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltipActions\n * onCreate={() => setOpenCreate(true)}\n * onRefresh={() => refetch()}\n * />\n * ```\n */\nexport const UITableTooltipActions: React.FC<{\n onCreate?: () => void;\n onRefresh?: () => void;\n onDownload?: () => void;\n}> = ({ onCreate, onDownload, onRefresh }) => {\n const { table, csvData, csvFileName, title, showAnalysisPanel, summary } = useUITableContext();\n const { isOpen: isAnalysisOpen, toggle: toggleAnalysis } = useUITableAnalysisContext();\n const { isOpen: isSummaryOpen, toggle: toggleSummary } = useUITableSummaryContext();\n\n const handleDownload = useCallback(() => {\n if (onDownload) {\n onDownload();\n return;\n }\n if (!csvData || csvData.length === 0) return;\n const selectedRows = table.getSelectedRowModel().flatRows;\n const rows = selectedRows.length > 0 ? selectedRows.map(row => csvData[row.index]).filter(Boolean) : csvData;\n downloadCsv(rows, csvFileName || title);\n }, [onDownload, csvData, csvFileName, table, title]);\n\n const isDownloadEnabled = !!(onDownload || (csvData && csvData.length > 0));\n\n return (\n <div className=\"flex [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\">\n <ActionButton\n disabled={!onCreate}\n onClick={e => {\n onCreate?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <CirclePlus />\n </ActionButton>\n <ActionButton\n disabled={!onRefresh}\n onClick={e => {\n onRefresh?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <RefreshCwIcon />\n </ActionButton>\n <ActionButton\n disabled={!isDownloadEnabled}\n onClick={e => {\n handleDownload();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <DownloadIcon />\n </ActionButton>\n {summary && summary.length > 0 && (\n <ActionButton\n onClick={e => {\n toggleSummary();\n e.stopPropagation();\n e.preventDefault();\n }}\n aria-pressed={isSummaryOpen}\n aria-label={isSummaryOpen ? 'Ẩn tổng quan' : 'Hiện tổng quan'}\n className={isSummaryOpen ? 'bg-muted-muted text-text-positive' : undefined}\n >\n <LayoutDashboardIcon />\n </ActionButton>\n )}\n {showAnalysisPanel && (\n <ActionButton\n onClick={e => {\n toggleAnalysis();\n e.stopPropagation();\n e.preventDefault();\n }}\n aria-pressed={isAnalysisOpen}\n className={isAnalysisOpen ? 'bg-muted-muted text-text-positive' : undefined}\n >\n <BarChart2Icon />\n </ActionButton>\n )}\n </div>\n );\n};\n\n/**\n * Outer toolbar shell for the UITable component.\n *\n * Reads the table `title` from `UITableContext` and renders it as a heading\n * above the `children` slot, which typically contains a\n * `UITableTooltipFilter` and/or `UITableTooltipActions`.\n *\n * @example\n * ```tsx\n * import {\n * UITableTooltip,\n * UITableTooltipFilter,\n * UITableTooltipActions,\n * } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltip>\n * <UITableTooltipFilter onSearch={setQuery} />\n * <UITableTooltipActions onCreate={handleCreate} onRefresh={refetch} />\n * </UITableTooltip>\n * ```\n */\nexport const UITableTooltip: React.FC<React.PropsWithChildren> = ({ children }) => {\n const { title, description, headerActions } = useUITableContext();\n return (\n <div data-slot=\"table-tooltip\" className=\"relative flex w-full flex-col gap-2 px-2 py-0 text-sm\">\n <div className=\"flex w-full items-start justify-between gap-4\">\n <div className=\"flex flex-col gap-0.5\">\n <h3 className=\"font-semibold text-base text-text-positive\">{title}</h3>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {headerActions && <div className=\"flex items-center gap-2 shrink-0\">{headerActions}</div>}\n </div>\n <div className=\"flex w-full flex-1 justify-between gap-x-2\">{children}</div>\n </div>\n );\n};\nUITableTooltip.displayName = 'UITableTooltip';\n"],"mappings":"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"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{Y as e,Z as t,q as n}from"./tables-7_KgoyS-.mjs";import{Input as r}from"./ui/input.mjs";import{ArrowRightIcon as i,BarChart2Icon as a,CirclePlus as o,DownloadIcon as s,LayoutDashboardIcon as c,RefreshCwIcon as l,SearchIcon as u}from"lucide-react";import{useCallback as d}from"react";import{cn as f}from"@customafk/react-toolkit/utils";import{jsx as p,jsxs as m}from"react/jsx-runtime";import{useDebounceCallback as h}from"@customafk/react-toolkit/hooks/useDebounceCallback";function g(e){if(e==null)return``;if(typeof e==`number`)return String(e);if(typeof e==`boolean`)return e?`true`:`false`;let t=String(e);return t.includes(`,`)||t.includes(`"`)||t.includes(`
|
|
2
|
-
`)||t.includes(`\r`)?`"${t.replace(/"/g,`""`)}"`:t}function _(e){if(e.length===0)return``;let t=e[0].map(e=>g(e.label)),n=e.map(e=>e.map(e=>g(e.value)).join(`,`));return[t.join(`,`),...n].join(`
|
|
3
|
-
`)}function v(e,t){let n=_(e);if(!n)return;let r=new Blob([n],{type:`text/csv;charset=utf-8;`}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=`${t}.csv`,a.click(),URL.revokeObjectURL(i)}const y=({onSearch:e,onChange:t,...n})=>{let a=h(t=>{e?.(t)},500);return m(`div`,{className:`relative w-full max-w-80 flex-1`,children:[p(r,{...n,size:`lg`,type:`search`,placeholder:`Tìm kiếm...`,className:`flex-1 ps-9 pe-9`,onChange:e=>{t?.(e),a(e.target.value??``)}}),p(`div`,{className:`pointer-events-none absolute inset-y-0 inset-s-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50`,children:p(u,{size:16})}),p(`button`,{className:`absolute inset-y-0 inset-e-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50`,"aria-label":`Submit search`,type:`submit`,children:p(i,{size:16,"aria-hidden":`true`})})]})},b=({children:e,disabled:t,onClick:n,className:r,...i})=>p(`button`,{type:`button`,disabled:t,className:f(`flex cursor-pointer items-center gap-x-1 rounded-sm border border-border bg-background p-2.5 text-sm text-text-positive-weak outline-none transition-all hover:shadow-card focus:border-border-emphasis focus:bg-muted-muted active:border-border-emphasis active:bg-muted-muted active:text-text-positive disabled:pointer-events-none disabled:cursor-default disabled:opacity-60 [&_svg]:size-3.5`,r),onClick:n,...i,children:e}),x=({onCreate:r,onDownload:i,onRefresh:u})=>{let{table:f,csvData:h,csvFileName:g,title:_,showAnalysisPanel:y,summary:x}=e(),{isOpen:S,toggle:C}=n(),{isOpen:w,toggle:T}=t(),E=d(()=>{if(i){i();return}if(!h||h.length===0)return;let e=f.getSelectedRowModel().flatRows;v(e.length>0?e.map(e=>h[e.index]).filter(Boolean):h,g||_)},[i,h,g,f,_]),D=!!(i||h&&h.length>0);return m(`div`,{className:`flex [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none`,children:[p(b,{disabled:!r,onClick:e=>{r?.(),e.stopPropagation(),e.preventDefault()},children:p(o,{})}),p(b,{disabled:!u,onClick:e=>{u?.(),e.stopPropagation(),e.preventDefault()},children:p(l,{})}),p(b,{disabled:!D,onClick:e=>{E(),e.stopPropagation(),e.preventDefault()},children:p(s,{})}),x&&x.length>0&&p(b,{onClick:e=>{T(),e.stopPropagation(),e.preventDefault()},"aria-pressed":w,"aria-label":w?`Ẩn tổng quan`:`Hiện tổng quan`,className:w?`bg-muted-muted text-text-positive`:void 0,children:p(c,{})}),y&&p(b,{onClick:e=>{C(),e.stopPropagation(),e.preventDefault()},"aria-pressed":S,className:S?`bg-muted-muted text-text-positive`:void 0,children:p(a,{})})]})},S=({children:t})=>{let{title:n,description:r,headerActions:i}=e();return m(`div`,{"data-slot":`table-tooltip`,className:`relative flex w-full flex-col gap-2 px-2 py-0 text-sm`,children:[m(`div`,{className:`flex w-full items-start justify-between gap-4`,children:[m(`div`,{className:`flex flex-col gap-0.5`,children:[p(`h3`,{className:`font-semibold text-base text-text-positive`,children:n}),r&&p(`p`,{className:`text-sm text-muted-foreground`,children:r})]}),i&&p(`div`,{className:`flex items-center gap-2 shrink-0`,children:i})]}),p(`div`,{className:`flex w-full flex-1 justify-between gap-x-2`,children:t})]})};S.displayName=`UITableTooltip`;export{S as UITableTooltip,x as UITableTooltipActions,y as UITableTooltipFilter};
|
|
4
|
-
//# sourceMappingURL=tooltip-C6flMQgc.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip-C6flMQgc.mjs","names":[],"sources":["../packages/components/features/tables/utils/csv.ts","../packages/components/features/tables/components/table/tooltip.tsx"],"sourcesContent":["'use client';\n\nimport type { CsvCell } from '../types';\n\nfunction formatCell(value: CsvCell['value']): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'number') return String(value);\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n const str = String(value);\n if (str.includes(',') || str.includes('\"') || str.includes('\\n') || str.includes('\\r')) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n}\n\nexport function buildCsvContent(rows: CsvCell[][]): string {\n if (rows.length === 0) return '';\n const headers = rows[0].map(cell => formatCell(cell.label));\n const dataRows = rows.map(row => row.map(cell => formatCell(cell.value)).join(','));\n return [headers.join(','), ...dataRows].join('\\n');\n}\n\nexport function downloadCsv(rows: CsvCell[][], fileName: string): void {\n const content = buildCsvContent(rows);\n if (!content) return;\n const blob = new Blob([content], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = `${fileName}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n","/**\n * @file tooltip.tsx\n * Toolbar components rendered above the table: a debounced search input,\n * an action button group (create / refresh / download), and the outer\n * toolbar shell that displays the table title.\n */\nimport { useCallback } from 'react';\n\nimport { ArrowRightIcon, BarChart2Icon, CirclePlus, DownloadIcon, LayoutDashboardIcon, RefreshCwIcon, SearchIcon } from 'lucide-react';\n\nimport { useDebounceCallback } from '@customafk/react-toolkit/hooks/useDebounceCallback';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Input } from '@/components/ui/input';\n\nimport { useUITableAnalysisContext, useUITableContext, useUITableSummaryContext } from '../../hooks/use-context';\nimport { downloadCsv } from '../../utils/csv';\n\n/**\n * Debounced search input rendered inside the table toolbar.\n *\n * Fires `onSearch` 500 ms after the user stops typing and delegates all other\n * native input events via the spread `props`.\n *\n * @example\n * ```tsx\n * import { UITableTooltipFilter } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltipFilter\n * placeholder=\"Search users…\"\n * onSearch={value => setQuery(value)}\n * />\n * ```\n */\nexport const UITableTooltipFilter: React.FC<\n Omit<React.ComponentProps<typeof Input>, 'className'> & {\n onSearch?: (value: string) => void;\n }\n> = ({ onSearch, onChange, ...props }) => {\n const debouncedSearch = useDebounceCallback((value: string) => {\n onSearch?.(value);\n }, 500);\n return (\n <div className=\"relative w-full max-w-80 flex-1\">\n <Input\n {...props}\n size=\"lg\"\n type=\"search\"\n placeholder=\"Tìm kiếm...\"\n className=\"flex-1 ps-9 pe-9\"\n onChange={e => {\n onChange?.(e);\n debouncedSearch(e.target.value ?? '');\n }}\n />\n <div className=\"pointer-events-none absolute inset-y-0 inset-s-0 flex items-center justify-center ps-3 text-text-positive-weak peer-disabled:opacity-50\">\n <SearchIcon size={16} />\n </div>\n <button\n className=\"absolute inset-y-0 inset-e-0 flex h-full w-9 items-center justify-center rounded-e-md text-text-positive-weak outline-none transition-[color,box-shadow] hover:text-text-positive focus:z-10 focus-visible:border focus-visible:border-primary-strong focus-visible:ring-[3px] focus-visible:ring-primary-weak disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Submit search\"\n type=\"submit\"\n >\n <ArrowRightIcon size={16} aria-hidden=\"true\" />\n </button>\n </div>\n );\n};\n\nconst ActionButton: React.FC<React.PropsWithChildren<React.ComponentProps<'button'>>> = ({ children, disabled, onClick, className, ...props }) => {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n className={cn(\n 'flex cursor-pointer items-center gap-x-1 rounded-sm border border-border bg-background p-2.5 text-sm text-text-positive-weak outline-none transition-all hover:shadow-card focus:border-border-emphasis focus:bg-muted-muted active:border-border-emphasis active:bg-muted-muted active:text-text-positive disabled:pointer-events-none disabled:cursor-default disabled:opacity-60 [&_svg]:size-3.5',\n className\n )}\n onClick={onClick}\n {...props}\n >\n {children}\n </button>\n );\n};\n\n/**\n * Grouped action buttons (create, refresh, download) displayed in the table\n * toolbar.\n *\n * Each button is disabled automatically when the corresponding handler prop is\n * omitted, so only the actions relevant to a given table need to be provided.\n * A toggle for `UITableSummaryBar` appears automatically when `summary` is\n * non-empty, and a toggle for `UITableAnalysisPanel` appears when\n * `showAnalysisPanel` is `true` (both set on `UITableProvider`).\n *\n * @example\n * ```tsx\n * import { UITableTooltipActions } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltipActions\n * onCreate={() => setOpenCreate(true)}\n * onRefresh={() => refetch()}\n * />\n * ```\n */\nexport const UITableTooltipActions: React.FC<{\n onCreate?: () => void;\n onRefresh?: () => void;\n onDownload?: () => void;\n}> = ({ onCreate, onDownload, onRefresh }) => {\n const { table, csvData, csvFileName, title, showAnalysisPanel, summary } = useUITableContext();\n const { isOpen: isAnalysisOpen, toggle: toggleAnalysis } = useUITableAnalysisContext();\n const { isOpen: isSummaryOpen, toggle: toggleSummary } = useUITableSummaryContext();\n\n const handleDownload = useCallback(() => {\n if (onDownload) {\n onDownload();\n return;\n }\n if (!csvData || csvData.length === 0) return;\n const selectedRows = table.getSelectedRowModel().flatRows;\n const rows = selectedRows.length > 0 ? selectedRows.map(row => csvData[row.index]).filter(Boolean) : csvData;\n downloadCsv(rows, csvFileName || title);\n }, [onDownload, csvData, csvFileName, table, title]);\n\n const isDownloadEnabled = !!(onDownload || (csvData && csvData.length > 0));\n\n return (\n <div className=\"flex [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\">\n <ActionButton\n disabled={!onCreate}\n onClick={e => {\n onCreate?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <CirclePlus />\n </ActionButton>\n <ActionButton\n disabled={!onRefresh}\n onClick={e => {\n onRefresh?.();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <RefreshCwIcon />\n </ActionButton>\n <ActionButton\n disabled={!isDownloadEnabled}\n onClick={e => {\n handleDownload();\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n <DownloadIcon />\n </ActionButton>\n {summary && summary.length > 0 && (\n <ActionButton\n onClick={e => {\n toggleSummary();\n e.stopPropagation();\n e.preventDefault();\n }}\n aria-pressed={isSummaryOpen}\n aria-label={isSummaryOpen ? 'Ẩn tổng quan' : 'Hiện tổng quan'}\n className={isSummaryOpen ? 'bg-muted-muted text-text-positive' : undefined}\n >\n <LayoutDashboardIcon />\n </ActionButton>\n )}\n {showAnalysisPanel && (\n <ActionButton\n onClick={e => {\n toggleAnalysis();\n e.stopPropagation();\n e.preventDefault();\n }}\n aria-pressed={isAnalysisOpen}\n className={isAnalysisOpen ? 'bg-muted-muted text-text-positive' : undefined}\n >\n <BarChart2Icon />\n </ActionButton>\n )}\n </div>\n );\n};\n\n/**\n * Outer toolbar shell for the UITable component.\n *\n * Reads the table `title` from `UITableContext` and renders it as a heading\n * above the `children` slot, which typically contains a\n * `UITableTooltipFilter` and/or `UITableTooltipActions`.\n *\n * @example\n * ```tsx\n * import {\n * UITableTooltip,\n * UITableTooltipFilter,\n * UITableTooltipActions,\n * } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableTooltip>\n * <UITableTooltipFilter onSearch={setQuery} />\n * <UITableTooltipActions onCreate={handleCreate} onRefresh={refetch} />\n * </UITableTooltip>\n * ```\n */\nexport const UITableTooltip: React.FC<React.PropsWithChildren> = ({ children }) => {\n const { title, description, headerActions } = useUITableContext();\n return (\n <div data-slot=\"table-tooltip\" className=\"relative flex w-full flex-col gap-2 px-2 py-0 text-sm\">\n <div className=\"flex w-full items-start justify-between gap-4\">\n <div className=\"flex flex-col gap-0.5\">\n <h3 className=\"font-semibold text-base text-text-positive\">{title}</h3>\n {description && <p className=\"text-sm text-muted-foreground\">{description}</p>}\n </div>\n {headerActions && <div className=\"flex items-center gap-2 shrink-0\">{headerActions}</div>}\n </div>\n <div className=\"flex w-full flex-1 justify-between gap-x-2\">{children}</div>\n </div>\n );\n};\nUITableTooltip.displayName = 'UITableTooltip';\n"],"mappings":"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"}
|