@customafk/lunas-ui 0.2.77 → 0.2.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/{analysis-panel-CQZ0hmfN.cjs → analysis-panel-Bg0lCfWv.cjs} +2 -2
  2. package/dist/{analysis-panel-CQZ0hmfN.cjs.map → analysis-panel-Bg0lCfWv.cjs.map} +1 -1
  3. package/dist/{analysis-panel-BqZmOU58.mjs → analysis-panel-Cop-l4lx.mjs} +2 -2
  4. package/dist/{analysis-panel-BqZmOU58.mjs.map → analysis-panel-Cop-l4lx.mjs.map} +1 -1
  5. package/dist/{badge-display-RP5VTE10.mjs → badge-display-B0BKsU9T.mjs} +2 -2
  6. package/dist/{badge-display-RP5VTE10.mjs.map → badge-display-B0BKsU9T.mjs.map} +1 -1
  7. package/dist/{badge-display-DmCKpGk9.cjs → badge-display-Dv2UTvzp.cjs} +2 -2
  8. package/dist/{badge-display-DmCKpGk9.cjs.map → badge-display-Dv2UTvzp.cjs.map} +1 -1
  9. package/dist/{boolean-display-B9qxrF5f.mjs → boolean-display-CMX5AupA.mjs} +2 -2
  10. package/dist/{boolean-display-B9qxrF5f.mjs.map → boolean-display-CMX5AupA.mjs.map} +1 -1
  11. package/dist/{boolean-display-BwB-l9k0.cjs → boolean-display-CPX7H39m.cjs} +2 -2
  12. package/dist/{boolean-display-BwB-l9k0.cjs.map → boolean-display-CPX7H39m.cjs.map} +1 -1
  13. package/dist/{button-BnoPktln.d.cts → button-DQLIL8K2.d.cts} +2 -2
  14. package/dist/{button-BnoPktln.d.mts → button-DQLIL8K2.d.mts} +2 -2
  15. package/dist/{calendar-BkV5hTX2.d.mts → calendar-5VVBPn4F.d.mts} +2 -2
  16. package/dist/{calendar-iDMPT1kI.d.cts → calendar-DHcoDDIc.d.cts} +2 -2
  17. package/dist/{carousel-D7VXWJ3S.d.mts → carousel-D0jTbSoW.d.cts} +2 -2
  18. package/dist/{carousel-bBvM31sh.d.cts → carousel-qH6YsFKK.d.mts} +2 -2
  19. package/dist/cms-layout-Ba_5wSnr.mjs +2 -0
  20. package/dist/cms-layout-Ba_5wSnr.mjs.map +1 -0
  21. package/dist/cms-layout-DCJhB-GY.cjs +2 -0
  22. package/dist/cms-layout-DCJhB-GY.cjs.map +1 -0
  23. package/dist/{currency-display-CEg_HRYv.mjs → currency-display-CanjOswc.mjs} +2 -2
  24. package/dist/{currency-display-CEg_HRYv.mjs.map → currency-display-CanjOswc.mjs.map} +1 -1
  25. package/dist/{currency-display-Buxc6Ph5.cjs → currency-display-xxK62yo4.cjs} +2 -2
  26. package/dist/{currency-display-Buxc6Ph5.cjs.map → currency-display-xxK62yo4.cjs.map} +1 -1
  27. package/dist/data-display/statistic.cjs +1 -1
  28. package/dist/data-display/statistic.cjs.map +1 -1
  29. package/dist/data-display/statistic.mjs +1 -1
  30. package/dist/data-display/statistic.mjs.map +1 -1
  31. package/dist/date-display-DMPhFq8v.cjs +2 -0
  32. package/dist/date-display-DMPhFq8v.cjs.map +1 -0
  33. package/dist/date-display-YE8NIIrl.mjs +2 -0
  34. package/dist/date-display-YE8NIIrl.mjs.map +1 -0
  35. package/dist/{description-display-CW0g3aJa.mjs → description-display-B4KoH6ql.mjs} +2 -2
  36. package/dist/{description-display-CW0g3aJa.mjs.map → description-display-B4KoH6ql.mjs.map} +1 -1
  37. package/dist/{description-display-BR8nXqc_.cjs → description-display-jmAaeMBD.cjs} +2 -2
  38. package/dist/{description-display-BR8nXqc_.cjs.map → description-display-jmAaeMBD.cjs.map} +1 -1
  39. package/dist/dialogs/detail-dialog/components/sidebar.d.cts +2 -2
  40. package/dist/dialogs/detail-dialog/components/sidebar.d.mts +2 -2
  41. package/dist/{email-display-DqKYq0iM.cjs → email-display-CzvqQMhG.cjs} +2 -2
  42. package/dist/{email-display-DqKYq0iM.cjs.map → email-display-CzvqQMhG.cjs.map} +1 -1
  43. package/dist/{email-display-BKcoWmPK.mjs → email-display-D_k7AUmp.mjs} +2 -2
  44. package/dist/{email-display-BKcoWmPK.mjs.map → email-display-D_k7AUmp.mjs.map} +1 -1
  45. package/dist/features/descriptions/index.cjs +1 -1
  46. package/dist/features/descriptions/index.cjs.map +1 -1
  47. package/dist/features/descriptions/index.mjs +1 -1
  48. package/dist/features/descriptions/index.mjs.map +1 -1
  49. package/dist/features/tables/index.cjs +1 -1
  50. package/dist/features/tables/index.d.cts +1 -1
  51. package/dist/features/tables/index.d.mts +1 -1
  52. package/dist/features/tables/index.mjs +1 -1
  53. package/dist/{filter-DqedvThM.cjs → filter-B5EnnL9I.cjs} +2 -2
  54. package/dist/{filter-DqedvThM.cjs.map → filter-B5EnnL9I.cjs.map} +1 -1
  55. package/dist/{filter-CWuRGTl4.mjs → filter-BCNjqiBx.mjs} +2 -2
  56. package/dist/{filter-CWuRGTl4.mjs.map → filter-BCNjqiBx.mjs.map} +1 -1
  57. package/dist/{flex-BTPF2-F6.d.cts → flex-CWo0w9K1.d.cts} +4 -4
  58. package/dist/{flex-BTPF2-F6.d.mts → flex-CWo0w9K1.d.mts} +4 -4
  59. package/dist/{index-C9JAujMq.d.cts → index-BapooVnN.d.cts} +12 -12
  60. package/dist/{index-DnHoBjv7.d.mts → index-CFgFCg9H.d.mts} +12 -12
  61. package/dist/index.cjs +1 -1
  62. package/dist/index.d.cts +12 -12
  63. package/dist/index.d.mts +12 -12
  64. package/dist/index.mjs +1 -1
  65. package/dist/{input-D73TrUof.d.cts → input-DxNK7Wo6.d.cts} +2 -2
  66. package/dist/{input-D73TrUof.d.mts → input-DxNK7Wo6.d.mts} +2 -2
  67. package/dist/{item-ChW41yKF.d.mts → item-Brbp9t6f.d.mts} +2 -2
  68. package/dist/{item-BxUBO7Hd.d.cts → item-CtLZgUB6.d.cts} +2 -2
  69. package/dist/layouts/cms-layout/index.cjs +1 -1
  70. package/dist/layouts/cms-layout/index.mjs +1 -1
  71. package/dist/layouts/flex.d.cts +1 -1
  72. package/dist/layouts/flex.d.mts +1 -1
  73. package/dist/list-display-DPxZ_Jbf.cjs +2 -0
  74. package/dist/list-display-DPxZ_Jbf.cjs.map +1 -0
  75. package/dist/list-display-M43N3kle.mjs +2 -0
  76. package/dist/list-display-M43N3kle.mjs.map +1 -0
  77. package/dist/{name-display-B-FtblLL.cjs → name-display-BJ1wPUnS.cjs} +2 -2
  78. package/dist/{name-display-B-FtblLL.cjs.map → name-display-BJ1wPUnS.cjs.map} +1 -1
  79. package/dist/{name-display-CB9XAhXP.mjs → name-display-pWhLLS05.mjs} +2 -2
  80. package/dist/{name-display-CB9XAhXP.mjs.map → name-display-pWhLLS05.mjs.map} +1 -1
  81. package/dist/{pagination-BRw-yZBY.d.cts → pagination-BVA_yrBO.d.mts} +2 -2
  82. package/dist/{pagination-BlLiOvY9.d.mts → pagination-DqJlXNY0.d.cts} +2 -2
  83. package/dist/{permalink-I-INEarM.mjs → permalink-BaMvnKIz.mjs} +2 -2
  84. package/dist/{permalink-I-INEarM.mjs.map → permalink-BaMvnKIz.mjs.map} +1 -1
  85. package/dist/{permalink-CUIKG9VA.cjs → permalink-CMcI__V4.cjs} +2 -2
  86. package/dist/{permalink-CUIKG9VA.cjs.map → permalink-CMcI__V4.cjs.map} +1 -1
  87. package/dist/{phone-number-DJvfJg1b.cjs → phone-number-F9I9sNLK.cjs} +2 -2
  88. package/dist/{phone-number-DJvfJg1b.cjs.map → phone-number-F9I9sNLK.cjs.map} +1 -1
  89. package/dist/{phone-number-Cu7Mnl6J.mjs → phone-number-ao2oCmrO.mjs} +2 -2
  90. package/dist/{phone-number-Cu7Mnl6J.mjs.map → phone-number-ao2oCmrO.mjs.map} +1 -1
  91. package/dist/{progress-display-DbfN7U8m.cjs → progress-display-F8xXJ3T1.cjs} +2 -2
  92. package/dist/{progress-display-DbfN7U8m.cjs.map → progress-display-F8xXJ3T1.cjs.map} +1 -1
  93. package/dist/{progress-display-qgvclwy9.mjs → progress-display-atwRFD6e.mjs} +2 -2
  94. package/dist/{progress-display-qgvclwy9.mjs.map → progress-display-atwRFD6e.mjs.map} +1 -1
  95. package/dist/{resizable-CWmitx5U.d.cts → resizable-B61Fbl57.d.cts} +2 -2
  96. package/dist/{resizable-CWmitx5U.d.mts → resizable-B61Fbl57.d.mts} +2 -2
  97. package/dist/{search-input-DEvYI6Rm.d.mts → search-input-C8feOKe2.d.cts} +2 -2
  98. package/dist/{search-input-h_3MoMqK.d.cts → search-input-CoqwakbI.d.mts} +2 -2
  99. package/dist/{statistic-LL4uHlRb.cjs → statistic-B9OqfhOl.cjs} +2 -2
  100. package/dist/{statistic-LL4uHlRb.cjs.map → statistic-B9OqfhOl.cjs.map} +1 -1
  101. package/dist/{statistic-ClkqqDfk.mjs → statistic-CJVc9sNs.mjs} +2 -2
  102. package/dist/{statistic-ClkqqDfk.mjs.map → statistic-CJVc9sNs.mjs.map} +1 -1
  103. package/dist/{status-display-BUphOF18.mjs → status-display-DInGGgiP.mjs} +2 -2
  104. package/dist/{status-display-BUphOF18.mjs.map → status-display-DInGGgiP.mjs.map} +1 -1
  105. package/dist/{status-display-o9inMVvb.cjs → status-display-DpKsYvZJ.cjs} +2 -2
  106. package/dist/{status-display-o9inMVvb.cjs.map → status-display-DpKsYvZJ.cjs.map} +1 -1
  107. package/dist/{summary-bar-Mb1B9Dnf.cjs → summary-bar-DKZh-VSB.cjs} +2 -2
  108. package/dist/{summary-bar-Mb1B9Dnf.cjs.map → summary-bar-DKZh-VSB.cjs.map} +1 -1
  109. package/dist/{summary-bar-CYfgdxrQ.mjs → summary-bar-DX_sOiuL.mjs} +2 -2
  110. package/dist/{summary-bar-CYfgdxrQ.mjs.map → summary-bar-DX_sOiuL.mjs.map} +1 -1
  111. package/dist/{tables-BGzwkdFO.mjs → tables-7_KgoyS-.mjs} +2 -2
  112. package/dist/{tables-BGzwkdFO.mjs.map → tables-7_KgoyS-.mjs.map} +1 -1
  113. package/dist/{tables-078i-X0d.cjs → tables-CS3NhgTc.cjs} +2 -2
  114. package/dist/{tables-078i-X0d.cjs.map → tables-CS3NhgTc.cjs.map} +1 -1
  115. package/dist/{toggle-group--bJylFDV.d.cts → toggle-group-DM5tS0Kt.d.cts} +2 -2
  116. package/dist/{toggle-group-l_Mi7NRg.d.mts → toggle-group-_PBz44Im.d.mts} +2 -2
  117. package/dist/{toggle-CqTmiPDi.d.cts → toggle-v1PgAvdG.d.cts} +2 -2
  118. package/dist/{toggle-CqTmiPDi.d.mts → toggle-v1PgAvdG.d.mts} +2 -2
  119. package/dist/{tooltip-BcfELg8e.cjs → tooltip-BcQG6Zw9.cjs} +2 -2
  120. package/dist/{tooltip-BcfELg8e.cjs.map → tooltip-BcQG6Zw9.cjs.map} +1 -1
  121. package/dist/{tooltip-TGmzPdoR.mjs → tooltip-C6flMQgc.mjs} +2 -2
  122. package/dist/{tooltip-TGmzPdoR.mjs.map → tooltip-C6flMQgc.mjs.map} +1 -1
  123. package/dist/ui/button.d.cts +1 -1
  124. package/dist/ui/button.d.mts +1 -1
  125. package/dist/ui/calendar.d.cts +1 -1
  126. package/dist/ui/calendar.d.mts +1 -1
  127. package/dist/ui/carousel.d.cts +1 -1
  128. package/dist/ui/carousel.d.mts +1 -1
  129. package/dist/ui/input.d.cts +1 -1
  130. package/dist/ui/input.d.mts +1 -1
  131. package/dist/ui/inputs/search-input.d.cts +1 -1
  132. package/dist/ui/inputs/search-input.d.mts +1 -1
  133. package/dist/ui/item.d.cts +1 -1
  134. package/dist/ui/item.d.mts +1 -1
  135. package/dist/ui/pagination.d.cts +1 -1
  136. package/dist/ui/pagination.d.mts +1 -1
  137. package/dist/ui/resizable.d.cts +1 -1
  138. package/dist/ui/resizable.d.mts +1 -1
  139. package/dist/ui/status.d.cts +1 -1
  140. package/dist/ui/status.d.mts +1 -1
  141. package/dist/ui/toggle-group.d.cts +1 -1
  142. package/dist/ui/toggle-group.d.mts +1 -1
  143. package/dist/ui/toggle.d.cts +1 -1
  144. package/dist/ui/toggle.d.mts +1 -1
  145. package/package.json +1 -1
  146. package/dist/cms-layout-BXd2ncAV.cjs +0 -2
  147. package/dist/cms-layout-BXd2ncAV.cjs.map +0 -1
  148. package/dist/cms-layout-COIo9HiP.mjs +0 -2
  149. package/dist/cms-layout-COIo9HiP.mjs.map +0 -1
  150. package/dist/date-display-BgI7Wjqf.cjs +0 -2
  151. package/dist/date-display-BgI7Wjqf.cjs.map +0 -1
  152. package/dist/date-display-DGfHQhpu.mjs +0 -2
  153. package/dist/date-display-DGfHQhpu.mjs.map +0 -1
  154. package/dist/list-display-BRJVmji0.cjs +0 -2
  155. package/dist/list-display-BRJVmji0.cjs.map +0 -1
  156. package/dist/list-display-Co94sV4H.mjs +0 -2
  157. package/dist/list-display-Co94sV4H.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-layout-DCJhB-GY.cjs","names":["TooltipProvider","Input","Separator","Slot","Tooltip","TooltipTrigger","TooltipContent","colorHashLight","Button","MenuIcon","LunasLogo","DropdownMenu","DropdownMenuTrigger","Avatar","AvatarImage","AvatarFallback","UserRoundIcon","DropdownMenuContent","DropdownMenuSeparator","DropdownMenuGroup","DropdownMenuItem","LogOutIcon","EarthIcon","LogOutIcon"],"sources":["../packages/components/layouts/cms-layout/components/sidebar.tsx","../packages/components/layouts/cms-layout/components/header.tsx","../packages/components/layouts/cms-layout/index.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { PanelLeftIcon } from 'lucide-react';\n\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n return context;\n}\n\nfunction CMSLayoutProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}) {\n const [_open, _setOpen] = useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n // biome-ignore lint/suspicious/noDocumentCookie: persists sidebar state across page loads\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open]\n );\n\n const toggleSidebar = useCallback(() => {\n setOpen(open => !open);\n }, [setOpen]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = useMemo<SidebarContextProps>(() => ({ state, open, setOpen, toggleSidebar }), [state, open, setOpen, toggleSidebar]);\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div data-slot=\"layout-scroll-container\" className=\"h-dvh w-full overflow-auto bg-sidebar\">\n <section\n data-slot=\"layout-wrapper\"\n style={{ '--sidebar-width': SIDEBAR_WIDTH, '--sidebar-width-icon': SIDEBAR_WIDTH_ICON, ...style } as React.CSSProperties}\n className={cn(\n 'group/sidebar-wrapper relative grid',\n 'h-dvh min-h-160 w-full min-w-264 max-w-svw',\n 'grid-cols-[auto_1fr] grid-rows-[auto_1fr]',\n className\n )}\n {...props}\n >\n {children}\n </section>\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\nconst CMSLayoutSidebar = memo(\n ({\n side = 'left',\n className,\n children,\n ...props\n }: React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n }) => {\n const { state } = useSidebar();\n\n return (\n <div\n className=\"group peer relative col-start-1 row-start-2 block bg-card text-sidebar-foreground\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? 'icon' : ''}\n data-side={side}\n data-slot=\"sidebar\"\n >\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',\n 'group-data-[side=right]:rotate-180',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'absolute inset-y-0 z-10 flex w-(--sidebar-width) p-2 shadow-nav',\n 'transition-[left,right,width] duration-200 ease-linear',\n 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]',\n side === 'left' ? 'left-0' : 'right-0',\n className\n )}\n {...props}\n >\n <div data-sidebar=\"sidebar\" data-slot=\"sidebar-inner\" className=\"relative flex size-full flex-col\">\n {children}\n </div>\n </div>\n </div>\n );\n }\n);\nCMSLayoutSidebar.displayName = 'CMSLayoutSidebar';\n\nfunction SidebarTrigger({ className, onClick, ...props }: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={event => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-0.5 hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'group-data-[collapsible=offcanvas]:translate-x-0 hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className\n )}\n {...props}\n />\n );\n}\n\nconst CMSLayoutMain = memo(({ className, children, ...props }: React.ComponentProps<'main'>) => {\n return (\n <main data-slot=\"sidebar-inset\" className={cn('col-start-2 row-start-2 grid min-h-0 min-w-0 grid-rows-1', className)} {...props}>\n <div className=\"relative grid min-h-0 grid-cols-1 overflow-auto\">{children}</div>\n </main>\n );\n});\nCMSLayoutMain.displayName = 'CMSLayoutMain';\n\nconst SidebarInput = memo(({ className, ...props }: React.ComponentProps<typeof Input>) => {\n return <Input data-slot=\"sidebar-input\" data-sidebar=\"input\" className={cn('h-8 w-full bg-background shadow-none', className)} {...props} />;\n});\nSidebarInput.displayName = 'SidebarInput';\n\nconst SidebarHeader = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-header\" data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />;\n});\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarFooter = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-footer\" data-sidebar=\"footer\" className={cn('flex flex-col gap-2', className)} {...props} />;\n});\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarSeparator = memo(({ className, ...props }: React.ComponentProps<typeof Separator>) => {\n return <Separator data-slot=\"sidebar-separator\" data-sidebar=\"separator\" className={cn('mx-2 w-auto bg-sidebar-border', className)} {...props} />;\n});\nSidebarSeparator.displayName = 'SidebarSeparator';\n\nconst SidebarContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn('flex flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden', className)}\n {...props}\n />\n );\n});\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarGroup = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group\" data-sidebar=\"group\" className={cn('relative flex w-full flex-col', className)} {...props} />;\n});\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = memo(({ className, asChild = false, ...props }: React.ComponentProps<'div'> & { asChild?: boolean }) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 font-medium text-sidebar-foreground/70 text-xs outline-hidden ring-sidebar-ring transition-[margin,opacity,color] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className\n )}\n {...props}\n />\n );\n});\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nfunction SidebarGroupAction({ className, asChild = false, ...props }: React.ComponentProps<'button'> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,transform] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2',\n '[&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nconst SidebarGroupContent = memo(({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"sidebar-group-content\" data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />;\n});\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst SidebarMenu = memo(({ className, ...props }: React.ComponentProps<'ul'>) => {\n return <ul data-slot=\"sidebar-menu\" data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />;\n});\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = memo(({ className, ...props }: React.ComponentProps<'li'>) => {\n return <li data-slot=\"sidebar-menu-item\" data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />;\n});\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst sidebarMenuButtonVariants = cva(\n [\n 'peer/menu-button',\n 'cursor-pointer',\n 'flex w-full items-center gap-2',\n 'overflow-hidden rounded-md p-2 outline-hidden',\n 'truncate text-left font-normal',\n 'transition-[color,background-color,width,height,padding]',\n 'active:bg-sidebar-accent active:text-sidebar-accent-foreground',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'group-has-data-[sidebar=menu-action]/menu-item:pr-8',\n 'aria-disabled:pointer-events-none aria-disabled:opacity-50',\n 'data-[active=true]:bg-sidebar-primary-muted data-[active=true]:text-sidebar-primary',\n 'data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground',\n 'group-data-[collapsible=icon]:size-12! group-data-[collapsible=icon]:p-3! group-data-[collapsible=icon]:gap-3!',\n '[&>svg]:size-6 [&>svg]:shrink-0',\n '[&>span:last-child]:truncate',\n ],\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-10 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nconst SidebarMenuButton = memo(\n ({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n }: React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n } & VariantProps<typeof sidebarMenuButtonVariants>) => {\n const Comp = asChild ? Slot : 'button';\n const { state } = useSidebar();\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n );\n\n if (!tooltip) return button;\n\n if (typeof tooltip === 'string') {\n tooltip = { children: tooltip };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed'} {...tooltip} />\n </Tooltip>\n );\n }\n);\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n}) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n 'absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color,opacity] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuBadge({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 font-medium text-sidebar-foreground text-xs tabular-nums transition-colors',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<'div'> & {\n showIcon?: boolean;\n}) {\n const width = useMemo(() => `${Math.floor(Math.random() * 40) + 50}%`, []);\n\n return (\n <div data-slot=\"sidebar-menu-skeleton\" data-sidebar=\"menu-skeleton\" className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)} {...props}>\n {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={{ '--skeleton-width': width } as React.CSSProperties}\n />\n </div>\n );\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nfunction SidebarMenuSubItem({ className, ...props }: React.ComponentProps<'li'>) {\n return <li data-slot=\"sidebar-menu-sub-item\" data-sidebar=\"menu-sub-item\" className={cn('group/menu-sub-item relative', className)} {...props} />;\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n}) {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-[background-color,color] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n // biome-ignore lint/style/useComponentExportOnlyModules: true\n useSidebar,\n};\n","'use client';\n\nimport { useCallback } from 'react';\n\nimport { EarthIcon, LogOutIcon, MenuIcon, UserRoundIcon } from 'lucide-react';\n\nimport { colorHashLight } from '@customafk/react-toolkit/color-hash';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { LunasLogo } from '@/components/features/logo';\n\nimport { useSidebar } from './sidebar';\n\nexport type CMSLayoutUser = {\n /** Display name shown in the header and user dropdown. */\n name: string;\n /** Email address shown below the name in the dropdown. */\n email?: string;\n /** Role or position shown as a muted label in the dropdown. */\n role?: string;\n /** Optional avatar image URL; falls back to a color-hashed icon. */\n avatarUrl?: string;\n};\n\nexport const CMSLayoutHeader: React.FC<{\n i18nText?: string;\n onChangeToEnLocale?: () => void;\n onChangeToViLocale?: () => void;\n user?: CMSLayoutUser;\n onLogout?: () => void;\n logoutLabel?: string;\n logo?: React.ReactNode;\n}> = ({ i18nText, onChangeToEnLocale, onChangeToViLocale, user, onLogout, logoutLabel = 'Log out', logo }) => {\n const { toggleSidebar } = useSidebar();\n\n const handleToggleSidebar = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n toggleSidebar();\n },\n [toggleSidebar]\n );\n\n const handleEnLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToEnLocale?.();\n },\n [onChangeToEnLocale]\n );\n\n const handleViLocale = useCallback(\n (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n onChangeToViLocale?.();\n },\n [onChangeToViLocale]\n );\n\n const avatarBg = user ? colorHashLight.hex(user.name) : undefined;\n\n return (\n <header\n data-slot=\"cms-layout-header\"\n className={cn(\n 'bg-card',\n 'h-(--header-height)',\n 'sm:h-(--header-height) sm:px-4 sm:pr-6',\n 'col-span-2 row-start-1 z-20 gap-2 px-2 pr-4.5',\n 'flex items-center shadow-nav',\n 'transition-[height] ease-linear'\n )}\n >\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n color=\"muted\"\n size=\"icon\"\n className=\"size-10 rounded-full transition-all hover:text-text-positive\"\n onClick={handleToggleSidebar}\n >\n <MenuIcon className=\"size-6!\" />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n\n <div className=\"flex flex-1 items-center sm:ml-2.5\">{logo ?? <LunasLogo variant=\"horizontal\" size=\"xs\" />}</div>\n\n <div className=\"flex items-center gap-1\">\n {user && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" color=\"muted\" className=\"h-9 gap-2.5 rounded-full px-2 transition-all\">\n <Avatar className=\"size-7 shrink-0\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={14} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"hidden flex-col items-start sm:flex\">\n <span className=\"max-w-36 truncate text-xs font-semibold leading-tight text-text-positive\">{user.name}</span>\n {user.email && <span className=\"max-w-36 truncate text-xs leading-tight text-text-positive-weak\">{user.email}</span>}\n </div>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-60\">\n <div className=\"flex flex-col items-center gap-2 px-4 py-4 text-center\">\n <Avatar className=\"size-12\">\n <AvatarImage src={user.avatarUrl} alt={user.name} />\n <AvatarFallback style={{ backgroundColor: avatarBg }}>\n <UserRoundIcon size={22} className=\"text-white\" />\n </AvatarFallback>\n </Avatar>\n <div className=\"flex min-w-0 w-full flex-col items-center gap-0.5\">\n <p className=\"truncate text-sm font-semibold text-text-positive\">{user.name}</p>\n {user.email && <p className=\"truncate text-xs text-text-positive-weak\">{user.email}</p>}\n {user.role && (\n <span className=\"mt-1 w-fit rounded-sm border border-border bg-secondary-muted px-2 py-0.5 text-xs font-medium text-text-positive-weak\">\n {user.role}\n </span>\n )}\n </div>\n </div>\n {onLogout && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem className=\"text-danger focus:text-danger\" onClick={onLogout}>\n <LogOutIcon className=\"size-4\" />\n {logoutLabel}\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {user && (onChangeToEnLocale || onChangeToViLocale) && <div className=\"mx-1 h-5 w-px bg-border\" />}\n\n {(onChangeToEnLocale || onChangeToViLocale) && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button data-slot=\"locale-trigger\" variant=\"ghost\" color=\"muted\" className=\"gap-x-1 rounded-full transition-all hover:text-text-positive\">\n <EarthIcon className=\"size-6!\" />\n {i18nText}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuGroup>\n <DropdownMenuItem onClick={handleEnLocale}>EN - English</DropdownMenuItem>\n <DropdownMenuItem onClick={handleViLocale}>VI - Vietnamese</DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n </header>\n );\n};\n","'use client';\n\nimport { memo } from 'react';\n\nimport { LogOutIcon } from 'lucide-react';\n\nimport { CMSLayoutHeader, type CMSLayoutUser } from './components/header';\nimport {\n CMSLayoutMain,\n CMSLayoutProvider,\n CMSLayoutSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from './components/sidebar';\n\ntype NavItem = {\n /** Unique identifier for the nav item, used as React key and for active-state comparison. */\n id: string;\n /** Human-readable label rendered inside the sidebar button. */\n label: string;\n /** Optional icon element rendered to the left of the label. */\n icon?: React.ReactNode;\n /** Callback fired when the sidebar button is clicked. Use for simple programmatic navigation. */\n onClick?: () => void;\n /**\n * Renders the button as a custom element using the Radix Slot (asChild) pattern.\n * Return a single element (e.g. a TanStack Router `<Link>`) wrapping the icon + label content.\n *\n * @example\n * ```tsx\n * renderAs: ({ icon, label }) => <Link to=\"/dashboard\">{icon}{label}</Link>\n * ```\n */\n renderAs?: (content: { icon?: React.ReactNode; label: string }) => React.ReactElement;\n};\n\ntype NavGroup = {\n /** Unique identifier for the group, used as React key. */\n id: string;\n /** Optional section heading rendered above the group's items. */\n label?: string;\n /** Navigation items that belong to this group. */\n items: NavItem[];\n};\n\nexport type { CMSLayoutUser };\n\nexport type CMSLayoutProps = {\n /** Text label used by the header for language-toggle or i18n display. */\n i18nText?: string;\n /** ID of the currently active navigation item; matched against `NavItem.id` to highlight the active button. */\n activeNavItemId?: string;\n /** Sidebar navigation definition; omitting this prop renders an empty sidebar. */\n sidebar?: { groupcontent: NavGroup[] };\n /** Callback fired when the logout button is clicked. */\n onLogout?: () => void;\n /** Callback fired when the user switches the UI locale to English. */\n onChangeToEnLocale?: () => void;\n /** Callback fired when the user switches the UI locale to Vietnamese. */\n onChangeToViLocale?: () => void;\n /**\n * Label displayed on the logout button.\n * @default 'Log out'\n */\n logoutLabel?: string;\n /**\n * Copyright string shown at the bottom of the sidebar.\n * @default `Copyright © <current year>, Lunas.`\n */\n copyright?: string;\n /** Authenticated user shown in the header avatar dropdown. Omit to hide the user menu. */\n user?: CMSLayoutUser;\n};\n\nconst SidebarContentGroupItem = memo<NavItem & { activeNavItemId?: string }>(({ id, label, icon, activeNavItemId, onClick, renderAs }) => (\n <SidebarMenuItem>\n {renderAs ? (\n <SidebarMenuButton asChild isActive={id === activeNavItemId}>\n {renderAs({ icon, label })}\n </SidebarMenuButton>\n ) : (\n <SidebarMenuButton isActive={id === activeNavItemId} onClick={onClick}>\n {icon}\n {label}\n </SidebarMenuButton>\n )}\n </SidebarMenuItem>\n));\nSidebarContentGroupItem.displayName = 'SidebarContentGroupItem';\n\nconst SidebarContentGroup = memo<React.PropsWithChildren<Omit<NavGroup, 'items'>>>(({ id, label, children }) => (\n <SidebarGroup>\n <SidebarGroupLabel>{label}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>{children}</SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n));\nSidebarContentGroup.displayName = 'SidebarContentGroup';\n\n/**\n * Full-page CMS application shell with a collapsible inset sidebar, header, and main content area.\n *\n * @example\n * ```tsx\n * import { CMSLayout } from '@customafk/lunas-ui/layouts/cms-layout';\n * import { LayoutDashboardIcon } from 'lucide-react';\n *\n * <CMSLayout\n * activeNavItemId=\"dashboard\"\n * sidebar={{\n * groupcontent: [\n * {\n * id: 'main',\n * label: 'Main',\n * items: [\n * {\n * id: 'dashboard',\n * label: 'Dashboard',\n * icon: <LayoutDashboardIcon />,\n * // Option A — TanStack Router Link (asChild/Slot pattern):\n * renderAs: ({ icon, label }) => <Link to=\"/\">{icon}{label}</Link>,\n * // Option B — simple click handler:\n * // onClick: () => router.navigate({ to: '/' }),\n * },\n * ],\n * },\n * ],\n * }}\n * onLogout={() => signOut()}\n * >\n * <DashboardPage />\n * </CMSLayout>\n * ```\n */\nexport const CMSLayout: React.FC<React.PropsWithChildren<CMSLayoutProps>> = ({\n i18nText,\n activeNavItemId,\n sidebar,\n children,\n onChangeToEnLocale,\n onChangeToViLocale,\n onLogout,\n logoutLabel = 'Log out',\n copyright = `Copyright © ${new Date().getFullYear()}, Lunas.`,\n user,\n}) => {\n const groups = sidebar?.groupcontent ?? [];\n\n return (\n <CMSLayoutProvider>\n <CMSLayoutHeader\n i18nText={i18nText}\n onChangeToEnLocale={onChangeToEnLocale}\n onChangeToViLocale={onChangeToViLocale}\n user={user}\n onLogout={onLogout}\n logoutLabel={logoutLabel}\n />\n <CMSLayoutSidebar>\n <SidebarContent>\n {groups.map(group => (\n <SidebarContentGroup key={group.id} id={group.id} label={group.label}>\n {group.items.map(item => (\n <SidebarContentGroupItem\n key={item.id}\n id={item.id}\n activeNavItemId={activeNavItemId}\n label={item.label}\n icon={item.icon}\n renderAs={item.renderAs}\n onClick={item.onClick}\n />\n ))}\n </SidebarContentGroup>\n ))}\n </SidebarContent>\n <SidebarFooter>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"border border-border\" onClick={onLogout}>\n <LogOutIcon className=\"text-text-positive-weak\" />\n {logoutLabel}\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem className=\"mt-2 border-t border-t-border\">\n <p className=\"pt-2 text-center text-xs text-text-positive-subtle\">{copyright}</p>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarFooter>\n </CMSLayoutSidebar>\n <CMSLayoutMain>{children}</CMSLayoutMain>\n </CMSLayoutProvider>\n );\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{Q as e}from"./tables-BGzwkdFO.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})=>{let u=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:2,maximumFractionDigits:2}).format(e)},[t,a,o,s]),d=n(()=>{let e=typeof t==`string`?Number(t.trim()):t;return typeof e==`number`&&e<0},[t]);return u?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`,!l&&`text-text-positive`,l&&d&&`text-danger-strong`,l&&!d&&`text-success-strong`),children:u}):i(e,{})});a.displayName=`UITableCurrencyDisplay`;export{a as UITableCurrencyDisplay};
2
- //# sourceMappingURL=currency-display-CEg_HRYv.mjs.map
1
+ import{Q as e}from"./tables-7_KgoyS-.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})=>{let u=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]),d=n(()=>{let e=typeof t==`string`?Number(t.trim()):t;return typeof e==`number`&&e<0},[t]);return u?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`,!l&&`text-text-positive`,l&&d&&`text-danger-strong`,l&&!d&&`text-success-strong`),children:u}):i(e,{})});a.displayName=`UITableCurrencyDisplay`;export{a as UITableCurrencyDisplay};
2
+ //# sourceMappingURL=currency-display-CanjOswc.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"currency-display-CEg_HRYv.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`, applies a green tint for positive and red tint for negative values. */\n colorize?: boolean;\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 */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false }: 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: 2,\n maximumFractionDigits: 2,\n }).format(num);\n }, [value, currency, locale, display]);\n\n const isNegative = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n return typeof num === 'number' && num < 0;\n }, [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 !colorize && 'text-text-positive',\n colorize && isNegative && 'text-danger-strong',\n colorize && !isNegative && 'text-success-strong'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"gLAsCA,MAAa,EAAyB,GAAM,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,MAAmB,CACtJ,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,EAAa,MAAc,CAC/B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC/D,OAAO,OAAO,GAAQ,UAAY,EAAM,CAC1C,EAAG,CAAC,CAAK,CAAC,EAIV,OAFK,EAGH,EAAC,IAAD,CACE,UAAW,EACT,2BACA,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,YACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,CAAC,GAAY,qBACb,GAAY,GAAc,qBAC1B,GAAY,CAAC,GAAc,qBAC7B,EAEC,SAAA,CACA,CAAA,EAjBkB,EAAC,EAAD,CAAe,CAAA,CAmBxC,CAAC,EACD,EAAuB,YAAc"}
1
+ {"version":3,"file":"currency-display-CanjOswc.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`, applies a green tint for positive and red tint for negative values. */\n colorize?: boolean;\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 */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false }: 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 isNegative = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n return typeof num === 'number' && num < 0;\n }, [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 !colorize && 'text-text-positive',\n colorize && isNegative && 'text-danger-strong',\n colorize && !isNegative && 'text-success-strong'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"gLAsCA,MAAa,EAAyB,GAAM,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,MAAmB,CACtJ,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,EAAa,MAAc,CAC/B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC/D,OAAO,OAAO,GAAQ,UAAY,EAAM,CAC1C,EAAG,CAAC,CAAK,CAAC,EAIV,OAFK,EAGH,EAAC,IAAD,CACE,UAAW,EACT,2BACA,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,YACjB,IAAS,MAAQ,UACjB,IAAS,MAAQ,UACjB,CAAC,GAAY,qBACb,GAAY,GAAc,qBAC1B,GAAY,CAAC,GAAc,qBAC7B,EAEC,SAAA,CACA,CAAA,EAjBkB,EAAC,EAAD,CAAe,CAAA,CAmBxC,CAAC,EACD,EAAuB,YAAc"}
@@ -1,2 +1,2 @@
1
- const e=require("./tables-078i-X0d.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})=>{let u=(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:2,maximumFractionDigits:2}).format(e)},[i,a,o,s]),d=(0,t.useMemo)(()=>{let e=typeof i==`string`?Number(i.trim()):i;return typeof e==`number`&&e<0},[i]);return u?(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`,!l&&`text-text-positive`,l&&d&&`text-danger-strong`,l&&!d&&`text-success-strong`),children:u}):(0,r.jsx)(e.Q,{})});i.displayName=`UITableCurrencyDisplay`,exports.UITableCurrencyDisplay=i;
2
- //# sourceMappingURL=currency-display-Buxc6Ph5.cjs.map
1
+ const e=require("./tables-CS3NhgTc.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})=>{let u=(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]),d=(0,t.useMemo)(()=>{let e=typeof i==`string`?Number(i.trim()):i;return typeof e==`number`&&e<0},[i]);return u?(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`,!l&&`text-text-positive`,l&&d&&`text-danger-strong`,l&&!d&&`text-success-strong`),children:u}):(0,r.jsx)(e.Q,{})});i.displayName=`UITableCurrencyDisplay`,exports.UITableCurrencyDisplay=i;
2
+ //# sourceMappingURL=currency-display-xxK62yo4.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"currency-display-Buxc6Ph5.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`, applies a green tint for positive and red tint for negative values. */\n colorize?: boolean;\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 */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false }: 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: 2,\n maximumFractionDigits: 2,\n }).format(num);\n }, [value, currency, locale, display]);\n\n const isNegative = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n return typeof num === 'number' && num < 0;\n }, [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 !colorize && 'text-text-positive',\n colorize && isNegative && 'text-danger-strong',\n colorize && !isNegative && 'text-success-strong'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"2IAsCA,MAAa,GAAA,EAAA,EAAA,KAAA,EAA+B,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,MAAmB,CACtJ,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,KAA2B,CAC/B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC/D,OAAO,OAAO,GAAQ,UAAY,EAAM,CAC1C,EAAG,CAAC,CAAK,CAAC,EAIV,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,GAAY,qBACb,GAAY,GAAc,qBAC1B,GAAY,CAAC,GAAc,qBAC7B,EAEC,SAAA,CACA,CAAA,GAjBkB,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,CAmBxC,CAAC,EACD,EAAuB,YAAc"}
1
+ {"version":3,"file":"currency-display-xxK62yo4.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`, applies a green tint for positive and red tint for negative values. */\n colorize?: boolean;\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 */\nexport const UITableCurrencyDisplay = memo(({ value, currency = 'USD', locale = 'en-US', display = 'symbol', size = 'md', colorize = false }: 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 isNegative = useMemo(() => {\n const num = typeof value === 'string' ? Number(value.trim()) : value;\n return typeof num === 'number' && num < 0;\n }, [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 !colorize && 'text-text-positive',\n colorize && isNegative && 'text-danger-strong',\n colorize && !isNegative && 'text-success-strong'\n )}\n >\n {formatted}\n </p>\n );\n});\nUITableCurrencyDisplay.displayName = 'UITableCurrencyDisplay';\n"],"mappings":"2IAsCA,MAAa,GAAA,EAAA,EAAA,KAAA,EAA+B,CAAE,QAAO,WAAW,MAAO,SAAS,QAAS,UAAU,SAAU,OAAO,KAAM,WAAW,MAAmB,CACtJ,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,KAA2B,CAC/B,IAAM,EAAM,OAAO,GAAU,SAAW,OAAO,EAAM,KAAK,CAAC,EAAI,EAC/D,OAAO,OAAO,GAAQ,UAAY,EAAM,CAC1C,EAAG,CAAC,CAAK,CAAC,EAIV,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,GAAY,qBACb,GAAY,GAAc,qBAC1B,GAAY,CAAC,GAAc,qBAC7B,EAEC,SAAA,CACA,CAAA,GAjBkB,EAAA,EAAA,IAAA,CAACA,EAAAA,EAAD,CAAe,CAAA,CAmBxC,CAAC,EACD,EAAuB,YAAc"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("react"),t=require("@customafk/react-toolkit/utils"),n=require("class-variance-authority"),r=require("react/jsx-runtime");const i=(0,n.cva)(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive-strong`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`lg`,trend:`neutral`}}),a=(0,e.memo)(({decimalSeparator:n=`.`,groupSeparator:a=`,`,prefix:o,suffix:s,precision:c,roundingMode:l=`round`,showTrailingZeros:u=!1,size:d=`lg`,trend:f=`neutral`,value:p,className:m})=>{let h=(0,e.useCallback)((e,t)=>{let n=10**t;switch(l){case`floor`:return Math.floor(e*n)/n;case`ceil`:return Math.ceil(e*n)/n;default:return Math.round(e*n)/n}},[l]),g=(0,e.useMemo)(()=>{let e={};return typeof c==`number`&&c>=0&&(u&&(e.minimumFractionDigits=c),e.maximumFractionDigits=c),e},[c,u]),_=(0,e.useCallback)(e=>{let t=e;return typeof c==`number`&&c>=0&&(t=h(e,c)),t.toLocaleString(`en-US`,g)},[h,g,c]),v=(0,e.useMemo)(()=>{if(typeof p==`number`)return Number.isNaN(p)||!Number.isFinite(p)?`N/A`:_(p);if(typeof p==`string`){let e=p.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:_(t)}return`N/A`},[p,_]),y=(0,e.useMemo)(()=>n===`.`&&a===`,`?v:v.replace(/,/g,a).replace(/\./g,n),[v,n,a]);return(0,r.jsxs)(`div`,{"data-slot":`statistic`,className:(0,t.cn)(i({size:d,trend:f}),m),children:[o&&(0,r.jsx)(`span`,{"data-slot":`statistic-prefix`,children:o}),(0,r.jsx)(`p`,{"data-slot":`statistic-value`,children:y}),s&&(0,r.jsx)(`span`,{"data-slot":`statistic-suffix`,children:s})]})});a.displayName=`Statistic`,exports.Statistic=a;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("react"),t=require("@customafk/react-toolkit/utils"),n=require("class-variance-authority"),r=require("react/jsx-runtime");const i=(0,n.cva)(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive-strong`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`lg`,trend:`neutral`}}),a=(0,e.memo)(({decimalSeparator:n=`.`,groupSeparator:a=`,`,prefix:o,suffix:s,precision:c,roundingMode:l=`round`,showTrailingZeros:u=!1,size:d=`lg`,trend:f=`neutral`,value:p,className:m})=>{let h=(0,e.useCallback)((e,t)=>{let n=10**t;switch(l){case`floor`:return Math.floor(e*n)/n;case`ceil`:return Math.ceil(e*n)/n;default:return Math.round(e*n)/n}},[l]),g=(0,e.useMemo)(()=>{let e={};return typeof c==`number`&&c>=0&&(u&&(e.minimumFractionDigits=c),e.maximumFractionDigits=c),e},[c,u]),_=(0,e.useCallback)(e=>{let t=e;return typeof c==`number`&&c>=0&&(t=h(e,c)),t.toLocaleString(`vi-VN`,g)},[h,g,c]),v=(0,e.useMemo)(()=>{if(typeof p==`number`)return Number.isNaN(p)||!Number.isFinite(p)?`N/A`:_(p);if(typeof p==`string`){let e=p.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:_(t)}return`N/A`},[p,_]),y=(0,e.useMemo)(()=>n===`.`&&a===`,`?v:v.replace(/,/g,a).replace(/\./g,n),[v,n,a]);return(0,r.jsxs)(`div`,{"data-slot":`statistic`,className:(0,t.cn)(i({size:d,trend:f}),m),children:[o&&(0,r.jsx)(`span`,{"data-slot":`statistic-prefix`,children:o}),(0,r.jsx)(`p`,{"data-slot":`statistic-value`,children:y}),s&&(0,r.jsx)(`span`,{"data-slot":`statistic-suffix`,children:s})]})});a.displayName=`Statistic`,exports.Statistic=a;
2
2
  //# sourceMappingURL=statistic.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"statistic.cjs","names":[],"sources":["../../packages/components/data-display/statistic.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useCallback, useMemo } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nconst statisticVariants = cva('inline-flex items-center gap-1 font-number tabular-nums transition-colors', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n },\n trend: {\n neutral: 'text-text-positive-strong',\n up: 'text-success',\n down: 'text-danger',\n },\n },\n defaultVariants: {\n size: 'lg',\n trend: 'neutral',\n },\n});\n\nexport type StatisticProps = VariantProps<typeof statisticVariants> & {\n /** Character used to separate the decimal part. Defaults to `'.'`. */\n decimalSeparator?: string;\n /** Character used to separate thousands groups. Defaults to `','`. */\n groupSeparator?: string;\n /** Optional node rendered before the numeric value (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the numeric value (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display; omit to show all significant digits. */\n precision?: number;\n /** Rounding strategy applied before formatting. Defaults to `'round'`. */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the decimal part with trailing zeros up to `precision`. Defaults to `false`. */\n showTrailingZeros?: boolean;\n /** The numeric (or numeric-string) value to format and display. */\n value: number | string;\n /** Additional CSS classes applied to the wrapper element. */\n className?: string;\n /** Colour trend indicator: `'neutral'` (default), `'up'` (green), or `'down'` (red). */\n trend?: 'neutral' | 'up' | 'down';\n};\n\n/**\n * A memoised numeric display component with locale-aware formatting, optional prefix/suffix, trend colouring, and configurable rounding.\n *\n * @example\n * ```tsx\n * import { Statistic } from '@customafk/lunas-ui/data-display/statistic';\n *\n * <Statistic value={1234567.89} precision={2} prefix=\"$\" trend=\"up\" size=\"lg\" />\n * ```\n */\nexport const Statistic = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n trend = 'neutral',\n value,\n className,\n }: StatisticProps) => {\n const applyRounding = useCallback(\n (num: number, precisionValue: number): number => {\n const multiplier = 10 ** precisionValue;\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n },\n [roundingMode]\n );\n\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n if (typeof precision === 'number' && precision >= 0) {\n if (showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n }\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision);\n }\n return processedNum.toLocaleString('en-US', formatOptions);\n },\n [applyRounding, formatOptions, precision]\n );\n\n const processedValue = useMemo((): string => {\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) return 'N/A';\n return formatNumber(value);\n }\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n if (!trimmedValue) return 'N/A';\n const numValue = Number(trimmedValue);\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) return 'N/A';\n return formatNumber(numValue);\n }\n return 'N/A';\n }, [value, formatNumber]);\n\n const finalFormattedValue = useMemo((): string => {\n if (decimalSeparator === '.' && groupSeparator === ',') return processedValue;\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n return (\n <div data-slot=\"statistic\" className={cn(statisticVariants({ size, trend }), className)}>\n {Prefix && <span data-slot=\"statistic-prefix\">{Prefix}</span>}\n <p data-slot=\"statistic-value\">{finalFormattedValue}</p>\n {Suffix && <span data-slot=\"statistic-suffix\">{Suffix}</span>}\n </div>\n );\n }\n);\nStatistic.displayName = 'Statistic';\n"],"mappings":"wNAMA,MAAM,GAAA,EAAA,EAAA,IAAA,CAAwB,4EAA6E,CACzG,SAAU,CACR,KAAM,CACJ,GAAI,UACJ,GAAI,UACJ,GAAI,YACJ,GAAI,UACJ,GAAI,SACN,EACA,MAAO,CACL,QAAS,4BACT,GAAI,eACJ,KAAM,aACR,CACF,EACA,gBAAiB,CACf,KAAM,KACN,MAAO,SACT,CACF,CAAC,EAmCY,GAAA,EAAA,EAAA,KAAA,EACV,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,UACR,QACA,eACoB,CACpB,IAAM,GAAA,EAAA,EAAA,YAAA,EACH,EAAa,IAAmC,CAC/C,IAAM,EAAa,IAAM,EACzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EACA,CAAC,CAAY,CACf,EAEM,GAAA,EAAA,EAAA,QAAA,KAAwD,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OARI,OAAO,GAAc,UAAY,GAAa,IAC5C,IACF,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,GAG7B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,GAAA,EAAA,EAAA,YAAA,CACH,GAAwB,CACvB,IAAI,EAAe,EAInB,OAHI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,CAAS,GAEtC,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAe,EAAe,CAAS,CAC1C,EAEM,GAAA,EAAA,EAAA,QAAA,KAAuC,CAC3C,GAAI,OAAO,GAAU,SAEnB,OADI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EAAU,MACpD,EAAa,CAAK,EAE3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAChC,GAAI,CAAC,EAAc,MAAO,MAC1B,IAAM,EAAW,OAAO,CAAY,EAEpC,OADI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAAU,MAC1D,EAAa,CAAQ,CAC9B,CACA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAElB,GAAA,EAAA,EAAA,QAAA,KACA,IAAqB,KAAO,IAAmB,IAAY,EACxD,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAErD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,YAAU,YAAY,WAAA,EAAA,EAAA,GAAA,CAAc,EAAkB,CAAE,OAAM,OAAM,CAAC,EAAG,CAAS,EAAtF,SAAA,CACG,IAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,GAC5D,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,YAAU,kBAAmB,SAAA,CAAuB,CAAA,EACtD,IAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,CACzD,GAET,CACF,EACA,EAAU,YAAc"}
1
+ {"version":3,"file":"statistic.cjs","names":[],"sources":["../../packages/components/data-display/statistic.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useCallback, useMemo } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nconst statisticVariants = cva('inline-flex items-center gap-1 font-number tabular-nums transition-colors', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n },\n trend: {\n neutral: 'text-text-positive-strong',\n up: 'text-success',\n down: 'text-danger',\n },\n },\n defaultVariants: {\n size: 'lg',\n trend: 'neutral',\n },\n});\n\nexport type StatisticProps = VariantProps<typeof statisticVariants> & {\n /** Character used to separate the decimal part. Defaults to `'.'`. */\n decimalSeparator?: string;\n /** Character used to separate thousands groups. Defaults to `','`. */\n groupSeparator?: string;\n /** Optional node rendered before the numeric value (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the numeric value (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display; omit to show all significant digits. */\n precision?: number;\n /** Rounding strategy applied before formatting. Defaults to `'round'`. */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the decimal part with trailing zeros up to `precision`. Defaults to `false`. */\n showTrailingZeros?: boolean;\n /** The numeric (or numeric-string) value to format and display. */\n value: number | string;\n /** Additional CSS classes applied to the wrapper element. */\n className?: string;\n /** Colour trend indicator: `'neutral'` (default), `'up'` (green), or `'down'` (red). */\n trend?: 'neutral' | 'up' | 'down';\n};\n\n/**\n * A memoised numeric display component with locale-aware formatting, optional prefix/suffix, trend colouring, and configurable rounding.\n *\n * @example\n * ```tsx\n * import { Statistic } from '@customafk/lunas-ui/data-display/statistic';\n *\n * <Statistic value={1234567.89} precision={2} prefix=\"$\" trend=\"up\" size=\"lg\" />\n * ```\n */\nexport const Statistic = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n trend = 'neutral',\n value,\n className,\n }: StatisticProps) => {\n const applyRounding = useCallback(\n (num: number, precisionValue: number): number => {\n const multiplier = 10 ** precisionValue;\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n },\n [roundingMode]\n );\n\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n if (typeof precision === 'number' && precision >= 0) {\n if (showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n }\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision);\n }\n return processedNum.toLocaleString('vi-VN', formatOptions);\n },\n [applyRounding, formatOptions, precision]\n );\n\n const processedValue = useMemo((): string => {\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) return 'N/A';\n return formatNumber(value);\n }\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n if (!trimmedValue) return 'N/A';\n const numValue = Number(trimmedValue);\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) return 'N/A';\n return formatNumber(numValue);\n }\n return 'N/A';\n }, [value, formatNumber]);\n\n const finalFormattedValue = useMemo((): string => {\n if (decimalSeparator === '.' && groupSeparator === ',') return processedValue;\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n return (\n <div data-slot=\"statistic\" className={cn(statisticVariants({ size, trend }), className)}>\n {Prefix && <span data-slot=\"statistic-prefix\">{Prefix}</span>}\n <p data-slot=\"statistic-value\">{finalFormattedValue}</p>\n {Suffix && <span data-slot=\"statistic-suffix\">{Suffix}</span>}\n </div>\n );\n }\n);\nStatistic.displayName = 'Statistic';\n"],"mappings":"wNAMA,MAAM,GAAA,EAAA,EAAA,IAAA,CAAwB,4EAA6E,CACzG,SAAU,CACR,KAAM,CACJ,GAAI,UACJ,GAAI,UACJ,GAAI,YACJ,GAAI,UACJ,GAAI,SACN,EACA,MAAO,CACL,QAAS,4BACT,GAAI,eACJ,KAAM,aACR,CACF,EACA,gBAAiB,CACf,KAAM,KACN,MAAO,SACT,CACF,CAAC,EAmCY,GAAA,EAAA,EAAA,KAAA,EACV,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,UACR,QACA,eACoB,CACpB,IAAM,GAAA,EAAA,EAAA,YAAA,EACH,EAAa,IAAmC,CAC/C,IAAM,EAAa,IAAM,EACzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EACA,CAAC,CAAY,CACf,EAEM,GAAA,EAAA,EAAA,QAAA,KAAwD,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OARI,OAAO,GAAc,UAAY,GAAa,IAC5C,IACF,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,GAG7B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,GAAA,EAAA,EAAA,YAAA,CACH,GAAwB,CACvB,IAAI,EAAe,EAInB,OAHI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,CAAS,GAEtC,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAe,EAAe,CAAS,CAC1C,EAEM,GAAA,EAAA,EAAA,QAAA,KAAuC,CAC3C,GAAI,OAAO,GAAU,SAEnB,OADI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EAAU,MACpD,EAAa,CAAK,EAE3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAChC,GAAI,CAAC,EAAc,MAAO,MAC1B,IAAM,EAAW,OAAO,CAAY,EAEpC,OADI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAAU,MAC1D,EAAa,CAAQ,CAC9B,CACA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAElB,GAAA,EAAA,EAAA,QAAA,KACA,IAAqB,KAAO,IAAmB,IAAY,EACxD,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAErD,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,YAAU,YAAY,WAAA,EAAA,EAAA,GAAA,CAAc,EAAkB,CAAE,OAAM,OAAM,CAAC,EAAG,CAAS,EAAtF,SAAA,CACG,IAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,GAC5D,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,YAAU,kBAAmB,SAAA,CAAuB,CAAA,EACtD,IAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,CACzD,GAET,CACF,EACA,EAAU,YAAc"}
@@ -1,2 +1,2 @@
1
- "use client";import{memo as e,useCallback as t,useMemo as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{cva as i}from"class-variance-authority";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=i(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive-strong`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`lg`,trend:`neutral`}}),c=e(({decimalSeparator:e=`.`,groupSeparator:i=`,`,prefix:c,suffix:l,precision:u,roundingMode:d=`round`,showTrailingZeros:f=!1,size:p=`lg`,trend:m=`neutral`,value:h,className:g})=>{let _=t((e,t)=>{let n=10**t;switch(d){case`floor`:return Math.floor(e*n)/n;case`ceil`:return Math.ceil(e*n)/n;default:return Math.round(e*n)/n}},[d]),v=n(()=>{let e={};return typeof u==`number`&&u>=0&&(f&&(e.minimumFractionDigits=u),e.maximumFractionDigits=u),e},[u,f]),y=t(e=>{let t=e;return typeof u==`number`&&u>=0&&(t=_(e,u)),t.toLocaleString(`en-US`,v)},[_,v,u]),b=n(()=>{if(typeof h==`number`)return Number.isNaN(h)||!Number.isFinite(h)?`N/A`:y(h);if(typeof h==`string`){let e=h.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:y(t)}return`N/A`},[h,y]),x=n(()=>e===`.`&&i===`,`?b:b.replace(/,/g,i).replace(/\./g,e),[b,e,i]);return o(`div`,{"data-slot":`statistic`,className:r(s({size:p,trend:m}),g),children:[c&&a(`span`,{"data-slot":`statistic-prefix`,children:c}),a(`p`,{"data-slot":`statistic-value`,children:x}),l&&a(`span`,{"data-slot":`statistic-suffix`,children:l})]})});c.displayName=`Statistic`;export{c as Statistic};
1
+ "use client";import{memo as e,useCallback as t,useMemo as n}from"react";import{cn as r}from"@customafk/react-toolkit/utils";import{cva as i}from"class-variance-authority";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=i(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive-strong`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`lg`,trend:`neutral`}}),c=e(({decimalSeparator:e=`.`,groupSeparator:i=`,`,prefix:c,suffix:l,precision:u,roundingMode:d=`round`,showTrailingZeros:f=!1,size:p=`lg`,trend:m=`neutral`,value:h,className:g})=>{let _=t((e,t)=>{let n=10**t;switch(d){case`floor`:return Math.floor(e*n)/n;case`ceil`:return Math.ceil(e*n)/n;default:return Math.round(e*n)/n}},[d]),v=n(()=>{let e={};return typeof u==`number`&&u>=0&&(f&&(e.minimumFractionDigits=u),e.maximumFractionDigits=u),e},[u,f]),y=t(e=>{let t=e;return typeof u==`number`&&u>=0&&(t=_(e,u)),t.toLocaleString(`vi-VN`,v)},[_,v,u]),b=n(()=>{if(typeof h==`number`)return Number.isNaN(h)||!Number.isFinite(h)?`N/A`:y(h);if(typeof h==`string`){let e=h.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:y(t)}return`N/A`},[h,y]),x=n(()=>e===`.`&&i===`,`?b:b.replace(/,/g,i).replace(/\./g,e),[b,e,i]);return o(`div`,{"data-slot":`statistic`,className:r(s({size:p,trend:m}),g),children:[c&&a(`span`,{"data-slot":`statistic-prefix`,children:c}),a(`p`,{"data-slot":`statistic-value`,children:x}),l&&a(`span`,{"data-slot":`statistic-suffix`,children:l})]})});c.displayName=`Statistic`;export{c as Statistic};
2
2
  //# sourceMappingURL=statistic.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"statistic.mjs","names":[],"sources":["../../packages/components/data-display/statistic.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useCallback, useMemo } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nconst statisticVariants = cva('inline-flex items-center gap-1 font-number tabular-nums transition-colors', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n },\n trend: {\n neutral: 'text-text-positive-strong',\n up: 'text-success',\n down: 'text-danger',\n },\n },\n defaultVariants: {\n size: 'lg',\n trend: 'neutral',\n },\n});\n\nexport type StatisticProps = VariantProps<typeof statisticVariants> & {\n /** Character used to separate the decimal part. Defaults to `'.'`. */\n decimalSeparator?: string;\n /** Character used to separate thousands groups. Defaults to `','`. */\n groupSeparator?: string;\n /** Optional node rendered before the numeric value (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the numeric value (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display; omit to show all significant digits. */\n precision?: number;\n /** Rounding strategy applied before formatting. Defaults to `'round'`. */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the decimal part with trailing zeros up to `precision`. Defaults to `false`. */\n showTrailingZeros?: boolean;\n /** The numeric (or numeric-string) value to format and display. */\n value: number | string;\n /** Additional CSS classes applied to the wrapper element. */\n className?: string;\n /** Colour trend indicator: `'neutral'` (default), `'up'` (green), or `'down'` (red). */\n trend?: 'neutral' | 'up' | 'down';\n};\n\n/**\n * A memoised numeric display component with locale-aware formatting, optional prefix/suffix, trend colouring, and configurable rounding.\n *\n * @example\n * ```tsx\n * import { Statistic } from '@customafk/lunas-ui/data-display/statistic';\n *\n * <Statistic value={1234567.89} precision={2} prefix=\"$\" trend=\"up\" size=\"lg\" />\n * ```\n */\nexport const Statistic = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n trend = 'neutral',\n value,\n className,\n }: StatisticProps) => {\n const applyRounding = useCallback(\n (num: number, precisionValue: number): number => {\n const multiplier = 10 ** precisionValue;\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n },\n [roundingMode]\n );\n\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n if (typeof precision === 'number' && precision >= 0) {\n if (showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n }\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision);\n }\n return processedNum.toLocaleString('en-US', formatOptions);\n },\n [applyRounding, formatOptions, precision]\n );\n\n const processedValue = useMemo((): string => {\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) return 'N/A';\n return formatNumber(value);\n }\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n if (!trimmedValue) return 'N/A';\n const numValue = Number(trimmedValue);\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) return 'N/A';\n return formatNumber(numValue);\n }\n return 'N/A';\n }, [value, formatNumber]);\n\n const finalFormattedValue = useMemo((): string => {\n if (decimalSeparator === '.' && groupSeparator === ',') return processedValue;\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n return (\n <div data-slot=\"statistic\" className={cn(statisticVariants({ size, trend }), className)}>\n {Prefix && <span data-slot=\"statistic-prefix\">{Prefix}</span>}\n <p data-slot=\"statistic-value\">{finalFormattedValue}</p>\n {Suffix && <span data-slot=\"statistic-suffix\">{Suffix}</span>}\n </div>\n );\n }\n);\nStatistic.displayName = 'Statistic';\n"],"mappings":"6NAMA,MAAM,EAAoB,EAAI,4EAA6E,CACzG,SAAU,CACR,KAAM,CACJ,GAAI,UACJ,GAAI,UACJ,GAAI,YACJ,GAAI,UACJ,GAAI,SACN,EACA,MAAO,CACL,QAAS,4BACT,GAAI,eACJ,KAAM,aACR,CACF,EACA,gBAAiB,CACf,KAAM,KACN,MAAO,SACT,CACF,CAAC,EAmCY,EAAY,GACtB,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,UACR,QACA,eACoB,CACpB,IAAM,EAAgB,GACnB,EAAa,IAAmC,CAC/C,IAAM,EAAa,IAAM,EACzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EACA,CAAC,CAAY,CACf,EAEM,EAAgB,MAAwC,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OARI,OAAO,GAAc,UAAY,GAAa,IAC5C,IACF,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,GAG7B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,EAAe,EAClB,GAAwB,CACvB,IAAI,EAAe,EAInB,OAHI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,CAAS,GAEtC,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAe,EAAe,CAAS,CAC1C,EAEM,EAAiB,MAAsB,CAC3C,GAAI,OAAO,GAAU,SAEnB,OADI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EAAU,MACpD,EAAa,CAAK,EAE3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAChC,GAAI,CAAC,EAAc,MAAO,MAC1B,IAAM,EAAW,OAAO,CAAY,EAEpC,OADI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAAU,MAC1D,EAAa,CAAQ,CAC9B,CACA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAElB,EAAsB,MACtB,IAAqB,KAAO,IAAmB,IAAY,EACxD,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAErD,OACE,EAAC,MAAD,CAAK,YAAU,YAAY,UAAW,EAAG,EAAkB,CAAE,OAAM,OAAM,CAAC,EAAG,CAAS,EAAtF,SAAA,CACG,GAAU,EAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,EAC5D,EAAC,IAAD,CAAG,YAAU,kBAAmB,SAAA,CAAuB,CAAA,EACtD,GAAU,EAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,CACzD,GAET,CACF,EACA,EAAU,YAAc"}
1
+ {"version":3,"file":"statistic.mjs","names":[],"sources":["../../packages/components/data-display/statistic.tsx"],"sourcesContent":["'use client';\n\nimport { memo, useCallback, useMemo } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@customafk/react-toolkit/utils';\n\nconst statisticVariants = cva('inline-flex items-center gap-1 font-number tabular-nums transition-colors', {\n variants: {\n size: {\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n },\n trend: {\n neutral: 'text-text-positive-strong',\n up: 'text-success',\n down: 'text-danger',\n },\n },\n defaultVariants: {\n size: 'lg',\n trend: 'neutral',\n },\n});\n\nexport type StatisticProps = VariantProps<typeof statisticVariants> & {\n /** Character used to separate the decimal part. Defaults to `'.'`. */\n decimalSeparator?: string;\n /** Character used to separate thousands groups. Defaults to `','`. */\n groupSeparator?: string;\n /** Optional node rendered before the numeric value (e.g. a currency symbol). */\n prefix?: React.ReactNode;\n /** Optional node rendered after the numeric value (e.g. a unit label). */\n suffix?: React.ReactNode;\n /** Number of decimal digits to display; omit to show all significant digits. */\n precision?: number;\n /** Rounding strategy applied before formatting. Defaults to `'round'`. */\n roundingMode?: 'round' | 'floor' | 'ceil';\n /** When `true`, pads the decimal part with trailing zeros up to `precision`. Defaults to `false`. */\n showTrailingZeros?: boolean;\n /** The numeric (or numeric-string) value to format and display. */\n value: number | string;\n /** Additional CSS classes applied to the wrapper element. */\n className?: string;\n /** Colour trend indicator: `'neutral'` (default), `'up'` (green), or `'down'` (red). */\n trend?: 'neutral' | 'up' | 'down';\n};\n\n/**\n * A memoised numeric display component with locale-aware formatting, optional prefix/suffix, trend colouring, and configurable rounding.\n *\n * @example\n * ```tsx\n * import { Statistic } from '@customafk/lunas-ui/data-display/statistic';\n *\n * <Statistic value={1234567.89} precision={2} prefix=\"$\" trend=\"up\" size=\"lg\" />\n * ```\n */\nexport const Statistic = memo(\n ({\n decimalSeparator = '.',\n groupSeparator = ',',\n prefix: Prefix,\n suffix: Suffix,\n precision,\n roundingMode = 'round',\n showTrailingZeros = false,\n size = 'lg',\n trend = 'neutral',\n value,\n className,\n }: StatisticProps) => {\n const applyRounding = useCallback(\n (num: number, precisionValue: number): number => {\n const multiplier = 10 ** precisionValue;\n switch (roundingMode) {\n case 'floor':\n return Math.floor(num * multiplier) / multiplier;\n case 'ceil':\n return Math.ceil(num * multiplier) / multiplier;\n default:\n return Math.round(num * multiplier) / multiplier;\n }\n },\n [roundingMode]\n );\n\n const formatOptions = useMemo((): Intl.NumberFormatOptions => {\n const options: Intl.NumberFormatOptions = {};\n if (typeof precision === 'number' && precision >= 0) {\n if (showTrailingZeros) {\n options.minimumFractionDigits = precision;\n options.maximumFractionDigits = precision;\n } else {\n options.maximumFractionDigits = precision;\n }\n }\n return options;\n }, [precision, showTrailingZeros]);\n\n const formatNumber = useCallback(\n (num: number): string => {\n let processedNum = num;\n if (typeof precision === 'number' && precision >= 0) {\n processedNum = applyRounding(num, precision);\n }\n return processedNum.toLocaleString('vi-VN', formatOptions);\n },\n [applyRounding, formatOptions, precision]\n );\n\n const processedValue = useMemo((): string => {\n if (typeof value === 'number') {\n if (Number.isNaN(value) || !Number.isFinite(value)) return 'N/A';\n return formatNumber(value);\n }\n if (typeof value === 'string') {\n const trimmedValue = value.trim();\n if (!trimmedValue) return 'N/A';\n const numValue = Number(trimmedValue);\n if (Number.isNaN(numValue) || !Number.isFinite(numValue)) return 'N/A';\n return formatNumber(numValue);\n }\n return 'N/A';\n }, [value, formatNumber]);\n\n const finalFormattedValue = useMemo((): string => {\n if (decimalSeparator === '.' && groupSeparator === ',') return processedValue;\n return processedValue.replace(/,/g, groupSeparator).replace(/\\./g, decimalSeparator);\n }, [processedValue, decimalSeparator, groupSeparator]);\n\n return (\n <div data-slot=\"statistic\" className={cn(statisticVariants({ size, trend }), className)}>\n {Prefix && <span data-slot=\"statistic-prefix\">{Prefix}</span>}\n <p data-slot=\"statistic-value\">{finalFormattedValue}</p>\n {Suffix && <span data-slot=\"statistic-suffix\">{Suffix}</span>}\n </div>\n );\n }\n);\nStatistic.displayName = 'Statistic';\n"],"mappings":"6NAMA,MAAM,EAAoB,EAAI,4EAA6E,CACzG,SAAU,CACR,KAAM,CACJ,GAAI,UACJ,GAAI,UACJ,GAAI,YACJ,GAAI,UACJ,GAAI,SACN,EACA,MAAO,CACL,QAAS,4BACT,GAAI,eACJ,KAAM,aACR,CACF,EACA,gBAAiB,CACf,KAAM,KACN,MAAO,SACT,CACF,CAAC,EAmCY,EAAY,GACtB,CACC,mBAAmB,IACnB,iBAAiB,IACjB,OAAQ,EACR,OAAQ,EACR,YACA,eAAe,QACf,oBAAoB,GACpB,OAAO,KACP,QAAQ,UACR,QACA,eACoB,CACpB,IAAM,EAAgB,GACnB,EAAa,IAAmC,CAC/C,IAAM,EAAa,IAAM,EACzB,OAAQ,EAAR,CACE,IAAK,QACH,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,EACxC,IAAK,OACH,OAAO,KAAK,KAAK,EAAM,CAAU,EAAI,EACvC,QACE,OAAO,KAAK,MAAM,EAAM,CAAU,EAAI,CAC1C,CACF,EACA,CAAC,CAAY,CACf,EAEM,EAAgB,MAAwC,CAC5D,IAAM,EAAoC,CAAC,EAS3C,OARI,OAAO,GAAc,UAAY,GAAa,IAC5C,IACF,EAAQ,sBAAwB,GAGhC,EAAQ,sBAAwB,GAG7B,CACT,EAAG,CAAC,EAAW,CAAiB,CAAC,EAE3B,EAAe,EAClB,GAAwB,CACvB,IAAI,EAAe,EAInB,OAHI,OAAO,GAAc,UAAY,GAAa,IAChD,EAAe,EAAc,EAAK,CAAS,GAEtC,EAAa,eAAe,QAAS,CAAa,CAC3D,EACA,CAAC,EAAe,EAAe,CAAS,CAC1C,EAEM,EAAiB,MAAsB,CAC3C,GAAI,OAAO,GAAU,SAEnB,OADI,OAAO,MAAM,CAAK,GAAK,CAAC,OAAO,SAAS,CAAK,EAAU,MACpD,EAAa,CAAK,EAE3B,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAe,EAAM,KAAK,EAChC,GAAI,CAAC,EAAc,MAAO,MAC1B,IAAM,EAAW,OAAO,CAAY,EAEpC,OADI,OAAO,MAAM,CAAQ,GAAK,CAAC,OAAO,SAAS,CAAQ,EAAU,MAC1D,EAAa,CAAQ,CAC9B,CACA,MAAO,KACT,EAAG,CAAC,EAAO,CAAY,CAAC,EAElB,EAAsB,MACtB,IAAqB,KAAO,IAAmB,IAAY,EACxD,EAAe,QAAQ,KAAM,CAAc,CAAC,CAAC,QAAQ,MAAO,CAAgB,EAClF,CAAC,EAAgB,EAAkB,CAAc,CAAC,EAErD,OACE,EAAC,MAAD,CAAK,YAAU,YAAY,UAAW,EAAG,EAAkB,CAAE,OAAM,OAAM,CAAC,EAAG,CAAS,EAAtF,SAAA,CACG,GAAU,EAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,EAC5D,EAAC,IAAD,CAAG,YAAU,kBAAmB,SAAA,CAAuB,CAAA,EACtD,GAAU,EAAC,OAAD,CAAM,YAAU,mBAAoB,SAAA,CAAa,CAAA,CACzD,GAET,CACF,EACA,EAAU,YAAc"}
@@ -0,0 +1,2 @@
1
+ const e=require("./date-B3cozmfV.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-CS3NhgTc.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-DMPhFq8v.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-display-DMPhFq8v.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"}
@@ -0,0 +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-7_KgoyS-.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-YE8NIIrl.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-display-YE8NIIrl.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
- 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-BGzwkdFO.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-CW0g3aJa.mjs.map
1
+ import{Paragraph as e}from"./typography/paragraph.mjs";import{Tooltip as t,TooltipContent as n,TooltipTrigger as r}from"./ui/tooltip.mjs";import{Q as i}from"./tables-7_KgoyS-.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-B4KoH6ql.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"description-display-CW0g3aJa.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
+ {"version":3,"file":"description-display-B4KoH6ql.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-078i-X0d.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-BR8nXqc_.cjs.map
1
+ const e=require("./typography/paragraph.cjs"),t=require("./ui/tooltip.cjs"),n=require("./tables-CS3NhgTc.cjs");let r=require("react/jsx-runtime");const i=({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-jmAaeMBD.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"description-display-BR8nXqc_.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
+ {"version":3,"file":"description-display-jmAaeMBD.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-BnoPktln.cjs";
1
+ import { t as Button } from "../../../button-DQLIL8K2.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";
@@ -91,7 +91,7 @@ declare function DetailDialogSidebarMenu({ className, ...props }: React.Componen
91
91
  declare function DetailDialogSidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>): import("react").JSX.Element;
92
92
  declare const sidebarMenuButtonVariants: (props?: ({
93
93
  variant?: "default" | "outline" | null | undefined;
94
- size?: "sm" | "lg" | "default" | null | undefined;
94
+ size?: "default" | "sm" | "lg" | null | undefined;
95
95
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
96
96
  declare function DetailDialogSidebarMenuButton({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<'button'> & {
97
97
  asChild?: boolean;
@@ -1,4 +1,4 @@
1
- import { t as Button } from "../../../button-BnoPktln.mjs";
1
+ import { t as Button } from "../../../button-DQLIL8K2.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";
@@ -91,7 +91,7 @@ declare function DetailDialogSidebarMenu({ className, ...props }: React.Componen
91
91
  declare function DetailDialogSidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>): import("react").JSX.Element;
92
92
  declare const sidebarMenuButtonVariants: (props?: ({
93
93
  variant?: "default" | "outline" | null | undefined;
94
- size?: "sm" | "lg" | "default" | null | undefined;
94
+ size?: "default" | "sm" | "lg" | null | undefined;
95
95
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
96
96
  declare function DetailDialogSidebarMenuButton({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<'button'> & {
97
97
  asChild?: boolean;
@@ -1,2 +1,2 @@
1
- const e=require("./ui/tooltip.cjs"),t=require("./tables-078i-X0d.cjs");let n=require("lucide-react"),r=require("react"),i=require("react/jsx-runtime");const a=({email:a,linkable:o=!0})=>{let[s,c]=(0,r.useState)(!1),l=(0,r.useRef)(null);return(0,r.useEffect)(()=>()=>{l.current&&clearTimeout(l.current)},[]),a?(0,i.jsx)(e.TooltipProvider,{children:(0,i.jsxs)(`div`,{className:`group flex items-center gap-x-1.5`,children:[(0,i.jsx)(n.MailIcon,{size:13,className:`shrink-0 text-text-positive-weak`}),o?(0,i.jsx)(`a`,{href:`mailto:${a}`,className:`truncate text-primary text-sm underline-offset-2 hover:underline`,onClick:e=>e.stopPropagation(),children:a}):(0,i.jsx)(`span`,{className:`truncate text-text-positive text-sm`,children:a}),(0,i.jsxs)(e.Tooltip,{children:[(0,i.jsx)(e.TooltipTrigger,{asChild:!0,children:(0,i.jsx)(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),navigator.clipboard.writeText(a).then(()=>{c(!0),l.current=setTimeout(()=>c(!1),1500)})},className:`shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive`,children:s?(0,i.jsx)(n.CheckIcon,{size:13,className:`text-success-strong`}):(0,i.jsx)(n.CopyIcon,{size:13})})}),(0,i.jsx)(e.TooltipContent,{children:s?`Copied!`:`Copy email`})]})]})}):(0,i.jsx)(t.Q,{})};exports.UITableEmailDisplay=a;
2
- //# sourceMappingURL=email-display-DqKYq0iM.cjs.map
1
+ const e=require("./ui/tooltip.cjs"),t=require("./tables-CS3NhgTc.cjs");let n=require("lucide-react"),r=require("react"),i=require("react/jsx-runtime");const a=({email:a,linkable:o=!0})=>{let[s,c]=(0,r.useState)(!1),l=(0,r.useRef)(null);return(0,r.useEffect)(()=>()=>{l.current&&clearTimeout(l.current)},[]),a?(0,i.jsx)(e.TooltipProvider,{children:(0,i.jsxs)(`div`,{className:`group flex items-center gap-x-1.5`,children:[(0,i.jsx)(n.MailIcon,{size:13,className:`shrink-0 text-text-positive-weak`}),o?(0,i.jsx)(`a`,{href:`mailto:${a}`,className:`truncate text-primary text-sm underline-offset-2 hover:underline`,onClick:e=>e.stopPropagation(),children:a}):(0,i.jsx)(`span`,{className:`truncate text-text-positive text-sm`,children:a}),(0,i.jsxs)(e.Tooltip,{children:[(0,i.jsx)(e.TooltipTrigger,{asChild:!0,children:(0,i.jsx)(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),navigator.clipboard.writeText(a).then(()=>{c(!0),l.current=setTimeout(()=>c(!1),1500)})},className:`shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive`,children:s?(0,i.jsx)(n.CheckIcon,{size:13,className:`text-success-strong`}):(0,i.jsx)(n.CopyIcon,{size:13})})}),(0,i.jsx)(e.TooltipContent,{children:s?`Copied!`:`Copy email`})]})]})}):(0,i.jsx)(t.Q,{})};exports.UITableEmailDisplay=a;
2
+ //# sourceMappingURL=email-display-CzvqQMhG.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"email-display-DqKYq0iM.cjs","names":["UITableEmpty","TooltipProvider","MailIcon","Tooltip","TooltipTrigger","CheckIcon","CopyIcon","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/email-display.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { CheckIcon, CopyIcon, MailIcon } from 'lucide-react';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableEmailDisplay} component. */\ntype Props = {\n /** The email address to display; `null`/`undefined`/empty renders an empty state. */\n email: string | null | undefined;\n /** When `true`, a `mailto:` anchor wraps the address (default: `true`). */\n linkable?: boolean;\n};\n\n/**\n * Displays an email address in a table cell with a copy-to-clipboard button.\n * Shows a brief checkmark confirmation after copying. Optionally wraps the\n * address in a `mailto:` link. Renders {@link UITableEmpty} when `email` is\n * absent.\n *\n * @example\n * import { UITableEmailDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableEmailDisplay email=\"jane@example.com\" />\n */\nexport const UITableEmailDisplay: React.FC<Props> = ({ email, linkable = true }) => {\n const [copied, setCopied] = useState(false);\n const copiedTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (copiedTimeoutRef.current) clearTimeout(copiedTimeoutRef.current);\n };\n }, []);\n\n if (!email) return <UITableEmpty />;\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard.writeText(email).then(() => {\n setCopied(true);\n copiedTimeoutRef.current = setTimeout(() => setCopied(false), 1500);\n });\n };\n\n return (\n <TooltipProvider>\n <div className=\"group flex items-center gap-x-1.5\">\n <MailIcon size={13} className=\"shrink-0 text-text-positive-weak\" />\n\n {linkable ? (\n <a href={`mailto:${email}`} className=\"truncate text-primary text-sm underline-offset-2 hover:underline\" onClick={e => e.stopPropagation()}>\n {email}\n </a>\n ) : (\n <span className=\"truncate text-text-positive text-sm\">{email}</span>\n )}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={handleCopy}\n className=\"shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive\"\n >\n {copied ? <CheckIcon size={13} className=\"text-success-strong\" /> : <CopyIcon size={13} />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied!' : 'Copy email'}</TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"uJA6BA,MAAa,GAAwC,CAAE,QAAO,WAAW,MAAW,CAClF,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAsB,EAAK,EACpC,GAAA,EAAA,EAAA,OAAA,CAAgE,IAAI,EAmB1E,OAjBA,EAAA,EAAA,UAAA,SACe,CACP,EAAiB,SAAS,aAAa,EAAiB,OAAO,CACrE,EACC,CAAC,CAAC,EAEA,GAYH,EAAA,EAAA,IAAA,CAACC,EAAAA,gBAAD,CAAA,UACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oCAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,KAAM,GAAI,UAAU,kCAAoC,CAAA,EAEjE,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,KAAM,UAAU,IAAS,UAAU,mEAAmE,QAAS,GAAK,EAAE,gBAAgB,EACtI,SAAA,CACA,CAAA,GAEH,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,sCAAuC,SAAA,CAAY,CAAA,GAGrE,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GACd,UAAA,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,QAzBQ,GAAwB,CAC1C,EAAE,gBAAgB,EAClB,EAAE,eAAe,EACjB,UAAU,UAAU,UAAU,CAAK,CAAC,CAAC,SAAW,CAC9C,EAAU,EAAI,EACd,EAAiB,QAAU,eAAiB,EAAU,EAAK,EAAG,IAAI,CACpE,CAAC,CACH,EAmBY,UAAU,gIAET,SAAA,GAAS,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,KAAM,GAAI,UAAU,qBAAuB,CAAA,GAAI,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,KAAM,EAAK,CAAA,CACnF,CAAA,CACM,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAA,SAAiB,EAAS,UAAY,YAA6B,CAAA,CAC5D,CAAA,CAAA,CACN,CACU,CAAA,CAAA,CAAA,GApCA,EAAA,EAAA,IAAA,CAACP,EAAAA,EAAD,CAAe,CAAA,CAsCpC"}
1
+ {"version":3,"file":"email-display-CzvqQMhG.cjs","names":["UITableEmpty","TooltipProvider","MailIcon","Tooltip","TooltipTrigger","CheckIcon","CopyIcon","TooltipContent"],"sources":["../packages/components/features/tables/components/atoms/email-display.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { CheckIcon, CopyIcon, MailIcon } from 'lucide-react';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableEmailDisplay} component. */\ntype Props = {\n /** The email address to display; `null`/`undefined`/empty renders an empty state. */\n email: string | null | undefined;\n /** When `true`, a `mailto:` anchor wraps the address (default: `true`). */\n linkable?: boolean;\n};\n\n/**\n * Displays an email address in a table cell with a copy-to-clipboard button.\n * Shows a brief checkmark confirmation after copying. Optionally wraps the\n * address in a `mailto:` link. Renders {@link UITableEmpty} when `email` is\n * absent.\n *\n * @example\n * import { UITableEmailDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableEmailDisplay email=\"jane@example.com\" />\n */\nexport const UITableEmailDisplay: React.FC<Props> = ({ email, linkable = true }) => {\n const [copied, setCopied] = useState(false);\n const copiedTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (copiedTimeoutRef.current) clearTimeout(copiedTimeoutRef.current);\n };\n }, []);\n\n if (!email) return <UITableEmpty />;\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard.writeText(email).then(() => {\n setCopied(true);\n copiedTimeoutRef.current = setTimeout(() => setCopied(false), 1500);\n });\n };\n\n return (\n <TooltipProvider>\n <div className=\"group flex items-center gap-x-1.5\">\n <MailIcon size={13} className=\"shrink-0 text-text-positive-weak\" />\n\n {linkable ? (\n <a href={`mailto:${email}`} className=\"truncate text-primary text-sm underline-offset-2 hover:underline\" onClick={e => e.stopPropagation()}>\n {email}\n </a>\n ) : (\n <span className=\"truncate text-text-positive text-sm\">{email}</span>\n )}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={handleCopy}\n className=\"shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive\"\n >\n {copied ? <CheckIcon size={13} className=\"text-success-strong\" /> : <CopyIcon size={13} />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied!' : 'Copy email'}</TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"uJA6BA,MAAa,GAAwC,CAAE,QAAO,WAAW,MAAW,CAClF,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAsB,EAAK,EACpC,GAAA,EAAA,EAAA,OAAA,CAAgE,IAAI,EAmB1E,OAjBA,EAAA,EAAA,UAAA,SACe,CACP,EAAiB,SAAS,aAAa,EAAiB,OAAO,CACrE,EACC,CAAC,CAAC,EAEA,GAYH,EAAA,EAAA,IAAA,CAACC,EAAAA,gBAAD,CAAA,UACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oCAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,KAAM,GAAI,UAAU,kCAAoC,CAAA,EAEjE,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,KAAM,UAAU,IAAS,UAAU,mEAAmE,QAAS,GAAK,EAAE,gBAAgB,EACtI,SAAA,CACA,CAAA,GAEH,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,sCAAuC,SAAA,CAAY,CAAA,GAGrE,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GACd,UAAA,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,QAzBQ,GAAwB,CAC1C,EAAE,gBAAgB,EAClB,EAAE,eAAe,EACjB,UAAU,UAAU,UAAU,CAAK,CAAC,CAAC,SAAW,CAC9C,EAAU,EAAI,EACd,EAAiB,QAAU,eAAiB,EAAU,EAAK,EAAG,IAAI,CACpE,CAAC,CACH,EAmBY,UAAU,gIAET,SAAA,GAAS,EAAA,EAAA,IAAA,CAACC,EAAAA,UAAD,CAAW,KAAM,GAAI,UAAU,qBAAuB,CAAA,GAAI,EAAA,EAAA,IAAA,CAACC,EAAAA,SAAD,CAAU,KAAM,EAAK,CAAA,CACnF,CAAA,CACM,CAAA,GAChB,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAA,SAAiB,EAAS,UAAY,YAA6B,CAAA,CAC5D,CAAA,CAAA,CACN,CACU,CAAA,CAAA,CAAA,GApCA,EAAA,EAAA,IAAA,CAACP,EAAAA,EAAD,CAAe,CAAA,CAsCpC"}
@@ -1,2 +1,2 @@
1
- import{Tooltip as e,TooltipContent as t,TooltipProvider as n,TooltipTrigger as r}from"./ui/tooltip.mjs";import{Q as i}from"./tables-BGzwkdFO.mjs";import{CheckIcon as a,CopyIcon as o,MailIcon as s}from"lucide-react";import{useEffect as c,useRef as l,useState as u}from"react";import{jsx as d,jsxs as f}from"react/jsx-runtime";const p=({email:p,linkable:m=!0})=>{let[h,g]=u(!1),_=l(null);return c(()=>()=>{_.current&&clearTimeout(_.current)},[]),p?d(n,{children:f(`div`,{className:`group flex items-center gap-x-1.5`,children:[d(s,{size:13,className:`shrink-0 text-text-positive-weak`}),m?d(`a`,{href:`mailto:${p}`,className:`truncate text-primary text-sm underline-offset-2 hover:underline`,onClick:e=>e.stopPropagation(),children:p}):d(`span`,{className:`truncate text-text-positive text-sm`,children:p}),f(e,{children:[d(r,{asChild:!0,children:d(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),navigator.clipboard.writeText(p).then(()=>{g(!0),_.current=setTimeout(()=>g(!1),1500)})},className:`shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive`,children:h?d(a,{size:13,className:`text-success-strong`}):d(o,{size:13})})}),d(t,{children:h?`Copied!`:`Copy email`})]})]})}):d(i,{})};export{p as UITableEmailDisplay};
2
- //# sourceMappingURL=email-display-BKcoWmPK.mjs.map
1
+ import{Tooltip as e,TooltipContent as t,TooltipProvider as n,TooltipTrigger as r}from"./ui/tooltip.mjs";import{Q as i}from"./tables-7_KgoyS-.mjs";import{CheckIcon as a,CopyIcon as o,MailIcon as s}from"lucide-react";import{useEffect as c,useRef as l,useState as u}from"react";import{jsx as d,jsxs as f}from"react/jsx-runtime";const p=({email:p,linkable:m=!0})=>{let[h,g]=u(!1),_=l(null);return c(()=>()=>{_.current&&clearTimeout(_.current)},[]),p?d(n,{children:f(`div`,{className:`group flex items-center gap-x-1.5`,children:[d(s,{size:13,className:`shrink-0 text-text-positive-weak`}),m?d(`a`,{href:`mailto:${p}`,className:`truncate text-primary text-sm underline-offset-2 hover:underline`,onClick:e=>e.stopPropagation(),children:p}):d(`span`,{className:`truncate text-text-positive text-sm`,children:p}),f(e,{children:[d(r,{asChild:!0,children:d(`button`,{onClick:e=>{e.stopPropagation(),e.preventDefault(),navigator.clipboard.writeText(p).then(()=>{g(!0),_.current=setTimeout(()=>g(!1),1500)})},className:`shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive`,children:h?d(a,{size:13,className:`text-success-strong`}):d(o,{size:13})})}),d(t,{children:h?`Copied!`:`Copy email`})]})]})}):d(i,{})};export{p as UITableEmailDisplay};
2
+ //# sourceMappingURL=email-display-D_k7AUmp.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"email-display-BKcoWmPK.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/email-display.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { CheckIcon, CopyIcon, MailIcon } from 'lucide-react';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableEmailDisplay} component. */\ntype Props = {\n /** The email address to display; `null`/`undefined`/empty renders an empty state. */\n email: string | null | undefined;\n /** When `true`, a `mailto:` anchor wraps the address (default: `true`). */\n linkable?: boolean;\n};\n\n/**\n * Displays an email address in a table cell with a copy-to-clipboard button.\n * Shows a brief checkmark confirmation after copying. Optionally wraps the\n * address in a `mailto:` link. Renders {@link UITableEmpty} when `email` is\n * absent.\n *\n * @example\n * import { UITableEmailDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableEmailDisplay email=\"jane@example.com\" />\n */\nexport const UITableEmailDisplay: React.FC<Props> = ({ email, linkable = true }) => {\n const [copied, setCopied] = useState(false);\n const copiedTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (copiedTimeoutRef.current) clearTimeout(copiedTimeoutRef.current);\n };\n }, []);\n\n if (!email) return <UITableEmpty />;\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard.writeText(email).then(() => {\n setCopied(true);\n copiedTimeoutRef.current = setTimeout(() => setCopied(false), 1500);\n });\n };\n\n return (\n <TooltipProvider>\n <div className=\"group flex items-center gap-x-1.5\">\n <MailIcon size={13} className=\"shrink-0 text-text-positive-weak\" />\n\n {linkable ? (\n <a href={`mailto:${email}`} className=\"truncate text-primary text-sm underline-offset-2 hover:underline\" onClick={e => e.stopPropagation()}>\n {email}\n </a>\n ) : (\n <span className=\"truncate text-text-positive text-sm\">{email}</span>\n )}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={handleCopy}\n className=\"shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive\"\n >\n {copied ? <CheckIcon size={13} className=\"text-success-strong\" /> : <CopyIcon size={13} />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied!' : 'Copy email'}</TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"qUA6BA,MAAa,GAAwC,CAAE,QAAO,WAAW,MAAW,CAClF,GAAM,CAAC,EAAQ,GAAa,EAAS,EAAK,EACpC,EAAmB,EAA6C,IAAI,EAmB1E,OAjBA,UACe,CACP,EAAiB,SAAS,aAAa,EAAiB,OAAO,CACrE,EACC,CAAC,CAAC,EAEA,EAYH,EAAC,EAAD,CAAA,SACE,EAAC,MAAD,CAAK,UAAU,oCAAf,SAAA,CACE,EAAC,EAAD,CAAU,KAAM,GAAI,UAAU,kCAAoC,CAAA,EAEjE,EACC,EAAC,IAAD,CAAG,KAAM,UAAU,IAAS,UAAU,mEAAmE,QAAS,GAAK,EAAE,gBAAgB,EACtI,SAAA,CACA,CAAA,EAEH,EAAC,OAAD,CAAM,UAAU,sCAAuC,SAAA,CAAY,CAAA,EAGrE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,SAAD,CACE,QAzBQ,GAAwB,CAC1C,EAAE,gBAAgB,EAClB,EAAE,eAAe,EACjB,UAAU,UAAU,UAAU,CAAK,CAAC,CAAC,SAAW,CAC9C,EAAU,EAAI,EACd,EAAiB,QAAU,eAAiB,EAAU,EAAK,EAAG,IAAI,CACpE,CAAC,CACH,EAmBY,UAAU,gIAET,SAAA,EAAS,EAAC,EAAD,CAAW,KAAM,GAAI,UAAU,qBAAuB,CAAA,EAAI,EAAC,EAAD,CAAU,KAAM,EAAK,CAAA,CACnF,CAAA,CACM,CAAA,EAChB,EAAC,EAAD,CAAA,SAAiB,EAAS,UAAY,YAA6B,CAAA,CAC5D,CAAA,CAAA,CACN,CACU,CAAA,CAAA,CAAA,EApCA,EAAC,EAAD,CAAe,CAAA,CAsCpC"}
1
+ {"version":3,"file":"email-display-D_k7AUmp.mjs","names":[],"sources":["../packages/components/features/tables/components/atoms/email-display.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nimport { CheckIcon, CopyIcon, MailIcon } from 'lucide-react';\n\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\n\nimport { UITableEmpty } from './empty';\n\n/** Props for the {@link UITableEmailDisplay} component. */\ntype Props = {\n /** The email address to display; `null`/`undefined`/empty renders an empty state. */\n email: string | null | undefined;\n /** When `true`, a `mailto:` anchor wraps the address (default: `true`). */\n linkable?: boolean;\n};\n\n/**\n * Displays an email address in a table cell with a copy-to-clipboard button.\n * Shows a brief checkmark confirmation after copying. Optionally wraps the\n * address in a `mailto:` link. Renders {@link UITableEmpty} when `email` is\n * absent.\n *\n * @example\n * import { UITableEmailDisplay } from '@customafk/lunas-ui/features/tables';\n *\n * <UITableEmailDisplay email=\"jane@example.com\" />\n */\nexport const UITableEmailDisplay: React.FC<Props> = ({ email, linkable = true }) => {\n const [copied, setCopied] = useState(false);\n const copiedTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (copiedTimeoutRef.current) clearTimeout(copiedTimeoutRef.current);\n };\n }, []);\n\n if (!email) return <UITableEmpty />;\n\n const handleCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n navigator.clipboard.writeText(email).then(() => {\n setCopied(true);\n copiedTimeoutRef.current = setTimeout(() => setCopied(false), 1500);\n });\n };\n\n return (\n <TooltipProvider>\n <div className=\"group flex items-center gap-x-1.5\">\n <MailIcon size={13} className=\"shrink-0 text-text-positive-weak\" />\n\n {linkable ? (\n <a href={`mailto:${email}`} className=\"truncate text-primary text-sm underline-offset-2 hover:underline\" onClick={e => e.stopPropagation()}>\n {email}\n </a>\n ) : (\n <span className=\"truncate text-text-positive text-sm\">{email}</span>\n )}\n\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n onClick={handleCopy}\n className=\"shrink-0 cursor-pointer text-text-positive-weak opacity-0 transition-opacity group-hover:opacity-100 hover:text-text-positive\"\n >\n {copied ? <CheckIcon size={13} className=\"text-success-strong\" /> : <CopyIcon size={13} />}\n </button>\n </TooltipTrigger>\n <TooltipContent>{copied ? 'Copied!' : 'Copy email'}</TooltipContent>\n </Tooltip>\n </div>\n </TooltipProvider>\n );\n};\n"],"mappings":"qUA6BA,MAAa,GAAwC,CAAE,QAAO,WAAW,MAAW,CAClF,GAAM,CAAC,EAAQ,GAAa,EAAS,EAAK,EACpC,EAAmB,EAA6C,IAAI,EAmB1E,OAjBA,UACe,CACP,EAAiB,SAAS,aAAa,EAAiB,OAAO,CACrE,EACC,CAAC,CAAC,EAEA,EAYH,EAAC,EAAD,CAAA,SACE,EAAC,MAAD,CAAK,UAAU,oCAAf,SAAA,CACE,EAAC,EAAD,CAAU,KAAM,GAAI,UAAU,kCAAoC,CAAA,EAEjE,EACC,EAAC,IAAD,CAAG,KAAM,UAAU,IAAS,UAAU,mEAAmE,QAAS,GAAK,EAAE,gBAAgB,EACtI,SAAA,CACA,CAAA,EAEH,EAAC,OAAD,CAAM,UAAU,sCAAuC,SAAA,CAAY,CAAA,EAGrE,EAAC,EAAD,CAAA,SAAA,CACE,EAAC,EAAD,CAAgB,QAAA,GACd,SAAA,EAAC,SAAD,CACE,QAzBQ,GAAwB,CAC1C,EAAE,gBAAgB,EAClB,EAAE,eAAe,EACjB,UAAU,UAAU,UAAU,CAAK,CAAC,CAAC,SAAW,CAC9C,EAAU,EAAI,EACd,EAAiB,QAAU,eAAiB,EAAU,EAAK,EAAG,IAAI,CACpE,CAAC,CACH,EAmBY,UAAU,gIAET,SAAA,EAAS,EAAC,EAAD,CAAW,KAAM,GAAI,UAAU,qBAAuB,CAAA,EAAI,EAAC,EAAD,CAAU,KAAM,EAAK,CAAA,CACnF,CAAA,CACM,CAAA,EAChB,EAAC,EAAD,CAAA,SAAiB,EAAS,UAAY,YAA6B,CAAA,CAC5D,CAAA,CAAA,CACN,CACU,CAAA,CAAA,CAAA,EApCA,EAAC,EAAD,CAAe,CAAA,CAsCpC"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../typography/paragraph.cjs"),t=require("../../ui/image.cjs"),n=require("../../date-B3cozmfV.cjs"),r=require("../../ui/badge.cjs"),i=require("../../ui/tooltip.cjs"),a=require("../../data-display/user.cjs");let o=require("lucide-react"),s=require("react"),c=require("@customafk/react-toolkit/utils"),l=require("class-variance-authority"),u=require("react/jsx-runtime");const d=()=>(0,u.jsx)(`span`,{"data-slot":`description-empty`,"aria-label":`Empty value`,className:`select-none font-medium text-sm text-text-positive-muted`,children:`—`}),f=({label:e,color:t=`secondary`,variant:n=`soft`,size:i=`sm`})=>e?(0,u.jsx)(r.Badge,{"data-slot":`description-badge`,color:t,variant:n,size:i,children:e}):(0,u.jsx)(d,{}),p=({value:e,trueLabel:t=`Yes`,falseLabel:n=`No`})=>e==null?(0,u.jsx)(d,{}):(0,u.jsx)(r.Badge,{"data-slot":`description-boolean`,variant:`soft`,color:e?`success`:`danger`,size:`sm`,children:e?t:n}),m=({value:e,truncate:t=!0})=>{let[n,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{e&&(await navigator.clipboard.writeText(e),r(!0),setTimeout(()=>r(!1),1500))},[e]);return e?(0,u.jsxs)(`button`,{type:`button`,"data-slot":`description-copy`,onClick:i,className:(0,c.cn)(`group inline-flex max-w-full cursor-pointer items-center gap-1.5 rounded-sm border border-border-weak bg-secondary-muted px-2 py-0.5 font-mono text-xs text-text-positive-weak transition-[border-color,color,box-shadow] hover:border-border hover:text-text-positive hover:shadow-xs`,t&&`min-w-0`),children:[(0,u.jsx)(`span`,{className:(0,c.cn)(`tabular-nums`,t&&`truncate`),children:e}),n?(0,u.jsx)(o.CheckIcon,{size:12,className:`shrink-0 text-success`}):(0,u.jsx)(o.CopyIcon,{size:12,className:`shrink-0 opacity-50 group-hover:opacity-100`})]}):(0,u.jsx)(d,{})},h=({date:e})=>e==null?(0,u.jsx)(d,{}):(0,u.jsx)(i.TooltipProvider,{children:(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(n.t,{"data-slot":`description-date`,date:e,format:`medium`,className:`cursor-help`})}),(0,u.jsx)(i.TooltipContent,{children:(0,u.jsx)(n.t,{date:e,format:`full`,showTime:!0,className:`text-xs font-medium`})})]})}),g=({images:e})=>{if(!e?.length)return(0,u.jsx)(d,{});let n=e.length===1;return(0,u.jsx)(`div`,{"data-slot":`description-images`,className:`flex flex-wrap gap-4`,children:e.map(e=>(0,u.jsx)(`div`,{className:n?`group relative size-42 overflow-hidden rounded border border-border shadow-xs transition-shadow hover:shadow-card`:`group relative size-20 overflow-hidden rounded border border-border shadow-xs transition-shadow hover:shadow-card`,children:(0,u.jsx)(t.Image,{src:e.src,alt:e.alt,width:`100%`,height:`100%`,className:`transition-transform duration-200 group-hover:scale-105`})},e.id))})},_=({href:e,label:t,external:n=!0,className:r})=>e?(0,u.jsxs)(`a`,{"data-slot":`description-link`,href:e,target:n?`_blank`:void 0,rel:n?`noopener noreferrer`:void 0,className:(0,c.cn)(`inline-flex max-w-full items-center gap-1 text-sm text-primary underline decoration-dashed underline-offset-2 transition-colors hover:text-primary-strong hover:decoration-solid`,r),children:[!n&&(0,u.jsx)(o.LinkIcon,{size:12,className:`shrink-0 opacity-70`}),(0,u.jsx)(`span`,{className:`truncate`,children:t??e}),n&&(0,u.jsx)(o.ExternalLinkIcon,{size:12,className:`shrink-0 opacity-70`})]}):(0,u.jsx)(d,{}),v=({content:t})=>t==null?(0,u.jsx)(d,{}):(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(e.Paragraph,{"data-slot":`description-longtext`,variant:`sm`,className:`line-clamp-2 cursor-pointer whitespace-pre-line break-all text-start text-sm hover:text-text-positive transition-colors`,children:t})}),(0,u.jsx)(i.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,u.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,u.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:t}),(0,u.jsxs)(`p`,{className:`w-full text-end text-text-positive-subtle`,children:[t.toString().length,` chars`]})]})})]}),y=({name:t})=>t?(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(e.Paragraph,{"data-slot":`description-name`,variant:`sm`,className:`line-clamp-2 w-full cursor-pointer truncate hover:text-text-positive transition-colors`,children:t})}),(0,u.jsx)(i.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,u.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,u.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:t}),(0,u.jsxs)(`p`,{className:`w-full text-end text-text-positive-subtle`,children:[t.length,` chars`]})]})})]}):(0,u.jsx)(d,{}),b=({value:t})=>(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{"data-slot":`description-phone`,children:(0,u.jsx)(e.Paragraph,{variant:`sm`,className:`tabular-nums transition-colors`,children:t.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),(0,u.jsx)(i.TooltipContent,{align:`start`,children:(0,u.jsx)(`p`,{className:`tabular-nums`,children:t.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`(00) (+84) ($1) $2-$3`)})})]}),x=(e,t,n)=>{let r=10**t;switch(n){case`floor`:return Math.floor(e*r)/r;case`ceil`:return Math.ceil(e*r)/r;default:return Math.round(e*r)/r}},S=(0,l.cva)(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`sm`,trend:`neutral`}}),C=(0,s.memo)(({decimalSeparator:e=`.`,groupSeparator:t=`,`,prefix:n,suffix:r,precision:i,roundingMode:a=`round`,showTrailingZeros:o=!1,size:l=`sm`,trend:f=`neutral`,value:p=0,className:m})=>{let h=(0,s.useMemo)(()=>{let e={};return typeof i==`number`&&i>=0&&(o&&(e.minimumFractionDigits=i),e.maximumFractionDigits=i),e},[i,o]),g=(0,s.useCallback)(e=>{let t=e;return typeof i==`number`&&i>=0&&(t=x(e,i,a)),t.toLocaleString(`en-US`,h)},[a,h,i]),_=(0,s.useMemo)(()=>{if(typeof p==`number`)return Number.isNaN(p)||!Number.isFinite(p)?`N/A`:g(p);if(typeof p==`string`){let e=p.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:g(t)}return`N/A`},[p,g]),v=(0,s.useMemo)(()=>e===`.`&&t===`,`?_:_.replace(/,/g,t).replace(/\./g,e),[_,e,t]);return v===`0`||v===`N/A`||!v?(0,u.jsx)(d,{}):(0,u.jsxs)(`div`,{"data-slot":`description-statistic`,className:(0,c.cn)(S({size:l,trend:f}),m),children:[n&&(0,u.jsx)(`span`,{"data-slot":`description-statistic-prefix`,children:n}),(0,u.jsx)(`p`,{"data-slot":`description-statistic-value`,children:v}),r&&(0,u.jsx)(`span`,{"data-slot":`description-statistic-suffix`,children:r})]})});C.displayName=`DescriptionStatistic`;const w={primary:`bg-primary`,secondary:`bg-secondary`,muted:`bg-muted`,accent:`bg-accent`,info:`bg-info`,success:`bg-success`,warning:`bg-warning`,danger:`bg-danger`},T=({label:e,color:t=`info`,dot:n=!0})=>e?(0,u.jsxs)(r.Badge,{"data-slot":`description-status`,variant:`soft`,color:t,size:`sm`,className:`gap-1.5`,children:[n&&(0,u.jsx)(`span`,{className:(0,c.cn)(`inline-block size-1.5 shrink-0 rounded-full`,w[t])}),e]}):(0,u.jsx)(d,{}),E=({tags:e,max:t=5,color:n=`secondary`,variant:i=`soft`})=>{if(!e?.length)return(0,u.jsx)(d,{});let a=e.slice(0,t),o=e.length-a.length;return(0,u.jsxs)(`div`,{"data-slot":`description-tag-list`,className:`flex flex-wrap gap-1`,children:[a.map((e,t)=>(0,u.jsx)(r.Badge,{variant:i,color:n,size:`sm`,children:e},t)),o>0&&(0,u.jsxs)(r.Badge,{variant:`outline`,color:`muted`,size:`sm`,children:[`+`,o]})]})},D=({uuid:e,username:t,email:n})=>!e||!t||!n?(0,u.jsx)(d,{}):(0,u.jsx)(a.UserDataDisplay,{uuid:e,username:t,email:n}),O=(0,s.createContext)(!1),k=({label:e,labelColSpan:t=3,orientation:n=`horizontal`,action:r,labelAlign:i=`start`,children:a})=>n===`vertical`?(0,u.jsxs)(`div`,{"data-slot":`description-item`,className:`flex flex-col border-b border-b-border last:border-b-0`,children:[(0,u.jsxs)(`div`,{"data-slot":`description-item-label`,className:(0,c.cn)(`flex items-center border-b border-b-border bg-secondary-muted py-2 pr-2 pl-4 font-medium text-sm text-text-positive-weak`,i===`end`?`justify-end`:`justify-between`),children:[(0,u.jsx)(`span`,{children:e}),r&&(0,u.jsx)(`div`,{className:`shrink-0`,children:r})]}),(0,u.jsx)(`div`,{"data-slot":`description-item-value`,className:`flex flex-wrap items-center gap-2 py-3 pr-2 pl-4 text-sm text-text-positive`,children:a})]}):(0,u.jsxs)(`div`,{"data-slot":`description-item`,style:{display:`grid`,gridTemplateColumns:`repeat(12, minmax(0, 1fr))`},className:`grid border-b border-b-border last:border-b-0`,children:[(0,u.jsxs)(`div`,{"data-slot":`description-item-label`,style:{gridColumn:`span ${t} / span ${t}`},className:(0,c.cn)(`flex min-w-full items-center overflow-x-hidden text-wrap break-all border-r border-r-border bg-secondary-muted py-3 pr-2 pl-4 font-medium text-sm text-text-positive-weak tabular-nums`,i===`end`?`justify-end`:`justify-between`),children:[(0,u.jsx)(`span`,{children:e}),r&&(0,u.jsx)(`div`,{className:`shrink-0 pr-1`,children:r})]}),(0,u.jsx)(`div`,{"data-slot":`description-item-value`,style:{gridColumn:`span ${12-t} / span ${12-t}`},className:`flex flex-wrap items-center gap-2 py-3 pr-2 pl-4 text-sm text-text-positive`,children:a})]}),A=({title:e,description:t,extra:n,className:r})=>(0,u.jsxs)(`div`,{"data-slot":`description-header`,className:(0,c.cn)(`sticky top-0 z-10 flex items-center justify-between gap-4 border-b border-b-border bg-card px-4 py-3`,r),children:[(0,u.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,u.jsx)(`p`,{className:`text-sm font-semibold text-text-positive`,children:e}),t&&(0,u.jsx)(`p`,{className:`text-xs text-text-positive-muted`,children:t})]}),n&&(0,u.jsx)(`div`,{className:`shrink-0`,children:n})]}),j=({title:e,className:t})=>(0,u.jsxs)(`div`,{"data-slot":`description-section`,className:(0,c.cn)(`flex items-center gap-3 border-b border-b-border px-4 py-2.5`,t),children:[e&&(0,u.jsx)(`p`,{className:`shrink-0 text-xs font-semibold uppercase tracking-widest text-text-positive-muted`,children:e}),(0,u.jsx)(`div`,{className:`h-px flex-1 bg-border`})]}),M=({rows:e})=>(0,u.jsxs)(`div`,{"data-slot":`description-loading`,className:`animate-pulse`,children:[(0,u.jsxs)(`div`,{className:`flex items-center justify-between border-b border-b-border px-4 py-3`,children:[(0,u.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,u.jsx)(`div`,{className:`h-3.5 w-36 rounded bg-border`}),(0,u.jsx)(`div`,{className:`h-2.5 w-24 rounded bg-border-weak`})]}),(0,u.jsx)(`div`,{className:`h-5 w-16 rounded bg-border-weak`})]}),Array.from({length:e}).map((e,t)=>(0,u.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(12, minmax(0, 1fr))`},className:`grid border-b border-b-border last:border-b-0`,children:[(0,u.jsx)(`div`,{style:{gridColumn:`span 3 / span 3`},className:`flex items-center border-r border-r-border bg-secondary-muted py-3 pl-4 pr-2`,children:(0,u.jsx)(`div`,{className:`h-3 w-20 rounded bg-border`})}),(0,u.jsx)(`div`,{style:{gridColumn:`span 9 / span 9`},className:`flex items-center py-3 pl-4 pr-2`,children:(0,u.jsx)(`div`,{className:`h-3 w-28 rounded bg-border-weak`})})]},t))]}),N=({children:e,className:t,nested:n=!1,loading:r=!1,loadingRows:i=4})=>(0,u.jsx)(`div`,{"data-slot":`description`,className:(0,c.cn)(`relative flex flex-col bg-card`,(0,s.useContext)(O)?`border-b border-b-border last:border-b-0`:n?`w-full overflow-hidden rounded-md border border-border`:`size-full overflow-y-auto rounded-lg border border-border shadow-card ring-1 ring-border-weak`,t),children:r?(0,u.jsx)(M,{rows:i}):e}),P=({children:e,className:t})=>(0,u.jsx)(O.Provider,{value:!0,children:(0,u.jsx)(`div`,{"data-slot":`description-group`,className:(0,c.cn)(`relative size-full overflow-y-auto rounded-lg border border-border bg-card shadow-card ring-1 ring-border-weak`,t),children:e})});exports.Description=N,exports.DescriptionBadge=f,exports.DescriptionBoolean=p,exports.DescriptionCopy=m,exports.DescriptionDate=h,exports.DescriptionEmpty=d,exports.DescriptionGroup=P,exports.DescriptionHeader=A,exports.DescriptionImages=g,exports.DescriptionItem=k,exports.DescriptionLink=_,exports.DescriptionLongText=v,exports.DescriptionName=y,exports.DescriptionNumberPhone=b,exports.DescriptionSection=j,exports.DescriptionStatistic=C,exports.DescriptionStatus=T,exports.DescriptionTagList=E,exports.DescriptionUser=D;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../typography/paragraph.cjs"),t=require("../../ui/image.cjs"),n=require("../../date-B3cozmfV.cjs"),r=require("../../ui/badge.cjs"),i=require("../../ui/tooltip.cjs"),a=require("../../data-display/user.cjs");let o=require("lucide-react"),s=require("react"),c=require("@customafk/react-toolkit/utils"),l=require("class-variance-authority"),u=require("react/jsx-runtime");const d=()=>(0,u.jsx)(`span`,{"data-slot":`description-empty`,"aria-label":`Empty value`,className:`select-none font-medium text-sm text-text-positive-muted`,children:`—`}),f=({label:e,color:t=`secondary`,variant:n=`soft`,size:i=`sm`})=>e?(0,u.jsx)(r.Badge,{"data-slot":`description-badge`,color:t,variant:n,size:i,children:e}):(0,u.jsx)(d,{}),p=({value:e,trueLabel:t=`Yes`,falseLabel:n=`No`})=>e==null?(0,u.jsx)(d,{}):(0,u.jsx)(r.Badge,{"data-slot":`description-boolean`,variant:`soft`,color:e?`success`:`danger`,size:`sm`,children:e?t:n}),m=({value:e,truncate:t=!0})=>{let[n,r]=(0,s.useState)(!1),i=(0,s.useCallback)(async()=>{e&&(await navigator.clipboard.writeText(e),r(!0),setTimeout(()=>r(!1),1500))},[e]);return e?(0,u.jsxs)(`button`,{type:`button`,"data-slot":`description-copy`,onClick:i,className:(0,c.cn)(`group inline-flex max-w-full cursor-pointer items-center gap-1.5 rounded-sm border border-border-weak bg-secondary-muted px-2 py-0.5 font-mono text-xs text-text-positive-weak transition-[border-color,color,box-shadow] hover:border-border hover:text-text-positive hover:shadow-xs`,t&&`min-w-0`),children:[(0,u.jsx)(`span`,{className:(0,c.cn)(`tabular-nums`,t&&`truncate`),children:e}),n?(0,u.jsx)(o.CheckIcon,{size:12,className:`shrink-0 text-success`}):(0,u.jsx)(o.CopyIcon,{size:12,className:`shrink-0 opacity-50 group-hover:opacity-100`})]}):(0,u.jsx)(d,{})},h=({date:e})=>e==null?(0,u.jsx)(d,{}):(0,u.jsx)(i.TooltipProvider,{children:(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(n.t,{"data-slot":`description-date`,date:e,format:`medium`,className:`cursor-help`})}),(0,u.jsx)(i.TooltipContent,{children:(0,u.jsx)(n.t,{date:e,format:`full`,showTime:!0,className:`text-xs font-medium`})})]})}),g=({images:e})=>{if(!e?.length)return(0,u.jsx)(d,{});let n=e.length===1;return(0,u.jsx)(`div`,{"data-slot":`description-images`,className:`flex flex-wrap gap-4`,children:e.map(e=>(0,u.jsx)(`div`,{className:n?`group relative size-42 overflow-hidden rounded border border-border shadow-xs transition-shadow hover:shadow-card`:`group relative size-20 overflow-hidden rounded border border-border shadow-xs transition-shadow hover:shadow-card`,children:(0,u.jsx)(t.Image,{src:e.src,alt:e.alt,width:`100%`,height:`100%`,className:`transition-transform duration-200 group-hover:scale-105`})},e.id))})},_=({href:e,label:t,external:n=!0,className:r})=>e?(0,u.jsxs)(`a`,{"data-slot":`description-link`,href:e,target:n?`_blank`:void 0,rel:n?`noopener noreferrer`:void 0,className:(0,c.cn)(`inline-flex max-w-full items-center gap-1 text-sm text-primary underline decoration-dashed underline-offset-2 transition-colors hover:text-primary-strong hover:decoration-solid`,r),children:[!n&&(0,u.jsx)(o.LinkIcon,{size:12,className:`shrink-0 opacity-70`}),(0,u.jsx)(`span`,{className:`truncate`,children:t??e}),n&&(0,u.jsx)(o.ExternalLinkIcon,{size:12,className:`shrink-0 opacity-70`})]}):(0,u.jsx)(d,{}),v=({content:t})=>t==null?(0,u.jsx)(d,{}):(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(e.Paragraph,{"data-slot":`description-longtext`,variant:`sm`,className:`line-clamp-2 cursor-pointer whitespace-pre-line break-all text-start text-sm hover:text-text-positive transition-colors`,children:t})}),(0,u.jsx)(i.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,u.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,u.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:t}),(0,u.jsxs)(`p`,{className:`w-full text-end text-text-positive-subtle`,children:[t.toString().length,` chars`]})]})})]}),y=({name:t})=>t?(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{asChild:!0,children:(0,u.jsx)(e.Paragraph,{"data-slot":`description-name`,variant:`sm`,className:`line-clamp-2 w-full cursor-pointer truncate hover:text-text-positive transition-colors`,children:t})}),(0,u.jsx)(i.TooltipContent,{align:`start`,className:`h-fit min-w-48 max-w-80 pt-4`,children:(0,u.jsxs)(`div`,{className:`flex flex-col gap-y-2`,children:[(0,u.jsx)(`p`,{className:`whitespace-pre-line text-wrap break-keep`,children:t}),(0,u.jsxs)(`p`,{className:`w-full text-end text-text-positive-subtle`,children:[t.length,` chars`]})]})})]}):(0,u.jsx)(d,{}),b=({value:t})=>(0,u.jsxs)(i.Tooltip,{children:[(0,u.jsx)(i.TooltipTrigger,{"data-slot":`description-phone`,children:(0,u.jsx)(e.Paragraph,{variant:`sm`,className:`tabular-nums transition-colors`,children:t.replace(/(\d{3})(\d{3})(\d{4})/,`($1) $2-$3`)})}),(0,u.jsx)(i.TooltipContent,{align:`start`,children:(0,u.jsx)(`p`,{className:`tabular-nums`,children:t.slice(1).replace(/(\d{2})(\d{3})(\d{4})/,`(00) (+84) ($1) $2-$3`)})})]}),x=(e,t,n)=>{let r=10**t;switch(n){case`floor`:return Math.floor(e*r)/r;case`ceil`:return Math.ceil(e*r)/r;default:return Math.round(e*r)/r}},S=(0,l.cva)(`inline-flex items-center gap-1 font-number tabular-nums transition-colors`,{variants:{size:{xs:`text-xs`,sm:`text-sm`,md:`text-base`,lg:`text-lg`,xl:`text-xl`},trend:{neutral:`text-text-positive`,up:`text-success`,down:`text-danger`}},defaultVariants:{size:`sm`,trend:`neutral`}}),C=(0,s.memo)(({decimalSeparator:e=`.`,groupSeparator:t=`,`,prefix:n,suffix:r,precision:i,roundingMode:a=`round`,showTrailingZeros:o=!1,size:l=`sm`,trend:f=`neutral`,value:p=0,className:m})=>{let h=(0,s.useMemo)(()=>{let e={};return typeof i==`number`&&i>=0&&(o&&(e.minimumFractionDigits=i),e.maximumFractionDigits=i),e},[i,o]),g=(0,s.useCallback)(e=>{let t=e;return typeof i==`number`&&i>=0&&(t=x(e,i,a)),t.toLocaleString(`vi-VN`,h)},[a,h,i]),_=(0,s.useMemo)(()=>{if(typeof p==`number`)return Number.isNaN(p)||!Number.isFinite(p)?`N/A`:g(p);if(typeof p==`string`){let e=p.trim();if(!e)return`N/A`;let t=Number(e);return Number.isNaN(t)||!Number.isFinite(t)?`N/A`:g(t)}return`N/A`},[p,g]),v=(0,s.useMemo)(()=>e===`.`&&t===`,`?_:_.replace(/,/g,t).replace(/\./g,e),[_,e,t]);return v===`0`||v===`N/A`||!v?(0,u.jsx)(d,{}):(0,u.jsxs)(`div`,{"data-slot":`description-statistic`,className:(0,c.cn)(S({size:l,trend:f}),m),children:[!!n&&(0,u.jsx)(`span`,{"data-slot":`description-statistic-prefix`,children:n}),(0,u.jsx)(`p`,{"data-slot":`description-statistic-value`,children:v}),!!r&&(0,u.jsx)(`span`,{"data-slot":`description-statistic-suffix`,children:r})]})});C.displayName=`DescriptionStatistic`;const w={primary:`bg-primary`,secondary:`bg-secondary`,muted:`bg-muted`,accent:`bg-accent`,info:`bg-info`,success:`bg-success`,warning:`bg-warning`,danger:`bg-danger`},T=({label:e,color:t=`info`,dot:n=!0})=>e?(0,u.jsxs)(r.Badge,{"data-slot":`description-status`,variant:`soft`,color:t,size:`sm`,className:`gap-1.5`,children:[n&&(0,u.jsx)(`span`,{className:(0,c.cn)(`inline-block size-1.5 shrink-0 rounded-full`,w[t])}),e]}):(0,u.jsx)(d,{}),E=({tags:e,max:t=5,color:n=`secondary`,variant:i=`soft`})=>{if(!e?.length)return(0,u.jsx)(d,{});let a=e.slice(0,t),o=e.length-a.length;return(0,u.jsxs)(`div`,{"data-slot":`description-tag-list`,className:`flex flex-wrap gap-1`,children:[a.map((e,t)=>(0,u.jsx)(r.Badge,{variant:i,color:n,size:`sm`,children:e},t)),o>0&&(0,u.jsxs)(r.Badge,{variant:`outline`,color:`muted`,size:`sm`,children:[`+`,o]})]})},D=({uuid:e,username:t,email:n})=>!e||!t||!n?(0,u.jsx)(d,{}):(0,u.jsx)(a.UserDataDisplay,{uuid:e,username:t,email:n}),O=(0,s.createContext)(!1),k=({label:e,labelColSpan:t=3,orientation:n=`horizontal`,action:r,labelAlign:i=`start`,children:a})=>n===`vertical`?(0,u.jsxs)(`div`,{"data-slot":`description-item`,className:`flex flex-col border-b border-b-border last:border-b-0`,children:[(0,u.jsxs)(`div`,{"data-slot":`description-item-label`,className:(0,c.cn)(`flex items-center border-b border-b-border bg-secondary-muted py-2 pr-2 pl-4 font-medium text-sm text-text-positive-weak`,i===`end`?`justify-end`:`justify-between`),children:[(0,u.jsx)(`span`,{children:e}),!!r&&(0,u.jsx)(`div`,{className:`shrink-0`,children:r})]}),(0,u.jsx)(`div`,{"data-slot":`description-item-value`,className:`flex flex-wrap items-center gap-2 py-3 pr-2 pl-4 text-sm text-text-positive`,children:a})]}):(0,u.jsxs)(`div`,{"data-slot":`description-item`,style:{display:`grid`,gridTemplateColumns:`repeat(12, minmax(0, 1fr))`},className:`grid border-b border-b-border last:border-b-0`,children:[(0,u.jsxs)(`div`,{"data-slot":`description-item-label`,style:{gridColumn:`span ${t} / span ${t}`},className:(0,c.cn)(`flex min-w-full items-center overflow-x-hidden text-wrap break-all border-r border-r-border bg-secondary-muted py-3 pr-2 pl-4 font-medium text-sm text-text-positive-weak tabular-nums`,i===`end`?`justify-end`:`justify-between`),children:[(0,u.jsx)(`span`,{children:e}),!!r&&(0,u.jsx)(`div`,{className:`shrink-0 pr-1`,children:r})]}),(0,u.jsx)(`div`,{"data-slot":`description-item-value`,style:{gridColumn:`span ${12-t} / span ${12-t}`},className:`flex flex-wrap items-center gap-2 py-3 pr-2 pl-4 text-sm text-text-positive`,children:a})]}),A=({title:e,description:t,extra:n,className:r})=>(0,u.jsxs)(`div`,{"data-slot":`description-header`,className:(0,c.cn)(`sticky top-0 z-10 flex items-center justify-between gap-4 border-b border-b-border bg-card px-4 py-3`,r),children:[(0,u.jsxs)(`div`,{className:`flex flex-col gap-0.5`,children:[(0,u.jsx)(`p`,{className:`font-semibold text-sm text-text-positive`,children:e}),!!t&&(0,u.jsx)(`p`,{className:`text-text-positive-weak text-xs`,children:t})]}),!!n&&(0,u.jsx)(`div`,{className:`shrink-0`,children:n})]}),j=({title:e,className:t})=>(0,u.jsxs)(`div`,{"data-slot":`description-section`,className:(0,c.cn)(`flex items-center gap-3 border-b border-b-border px-4 py-2.5`,t),children:[!!e&&(0,u.jsx)(`p`,{className:`shrink-0 font-semibold text-text-positive-weak text-xs uppercase tracking-widest`,children:e}),(0,u.jsx)(`div`,{className:`h-px flex-1 bg-border`})]}),M=({rows:e})=>(0,u.jsxs)(`div`,{"data-slot":`description-loading`,className:`animate-pulse`,children:[(0,u.jsxs)(`div`,{className:`flex items-center justify-between border-b border-b-border px-4 py-3`,children:[(0,u.jsxs)(`div`,{className:`flex flex-col gap-1.5`,children:[(0,u.jsx)(`div`,{className:`h-3.5 w-36 rounded bg-border`}),(0,u.jsx)(`div`,{className:`h-2.5 w-24 rounded bg-border-weak`})]}),(0,u.jsx)(`div`,{className:`h-5 w-16 rounded bg-border-weak`})]}),Array.from({length:e}).map((e,t)=>(0,u.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(12, minmax(0, 1fr))`},className:`grid border-b border-b-border last:border-b-0`,children:[(0,u.jsx)(`div`,{style:{gridColumn:`span 3 / span 3`},className:`flex items-center border-r border-r-border bg-secondary-muted py-3 pr-2 pl-4`,children:(0,u.jsx)(`div`,{className:`h-3 w-20 rounded bg-border`})}),(0,u.jsx)(`div`,{style:{gridColumn:`span 9 / span 9`},className:`flex items-center py-3 pr-2 pl-4`,children:(0,u.jsx)(`div`,{className:`h-3 w-28 rounded bg-border-weak`})})]},`${t.toLocaleString()}`))]}),N=({children:e,className:t,nested:n=!1,loading:r=!1,loadingRows:i=4})=>(0,u.jsx)(`div`,{"data-slot":`description`,className:(0,c.cn)(`relative flex flex-col bg-card`,(0,s.useContext)(O)?`border-b border-b-border last:border-b-0`:n?`w-full overflow-hidden rounded-md border border-border`:`size-full overflow-y-auto rounded-lg border border-border shadow-card ring-1 ring-border-weak`,t),children:r?(0,u.jsx)(M,{rows:i}):e}),P=({children:e,className:t})=>(0,u.jsx)(O.Provider,{value:!0,children:(0,u.jsx)(`div`,{"data-slot":`description-group`,className:(0,c.cn)(`relative size-full overflow-y-auto rounded-lg border border-border bg-card shadow-card ring-1 ring-border-weak`,t),children:e})});exports.Description=N,exports.DescriptionBadge=f,exports.DescriptionBoolean=p,exports.DescriptionCopy=m,exports.DescriptionDate=h,exports.DescriptionEmpty=d,exports.DescriptionGroup=P,exports.DescriptionHeader=A,exports.DescriptionImages=g,exports.DescriptionItem=k,exports.DescriptionLink=_,exports.DescriptionLongText=v,exports.DescriptionName=y,exports.DescriptionNumberPhone=b,exports.DescriptionSection=j,exports.DescriptionStatistic=C,exports.DescriptionStatus=T,exports.DescriptionTagList=E,exports.DescriptionUser=D;
2
2
  //# sourceMappingURL=index.cjs.map