@photon-ai/pho-ui 2.15.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/chunks/IconArrowsMinimize-BfPUGuCB.js +75 -0
  2. package/dist/chunks/IconArrowsMinimize-BfPUGuCB.js.map +1 -0
  3. package/dist/chunks/IconChevronUp-CrpWSgIl.js +11 -0
  4. package/dist/chunks/IconChevronUp-CrpWSgIl.js.map +1 -0
  5. package/dist/chunks/{bar-chart-BJfr3eyd.js → bar-chart-DIALC2_z.js} +2 -2
  6. package/dist/chunks/bar-chart-DIALC2_z.js.map +1 -0
  7. package/dist/chunks/basic-page-CogcwGx3.js +1749 -0
  8. package/dist/chunks/basic-page-CogcwGx3.js.map +1 -0
  9. package/dist/chunks/card-DhDwtSi9.js +56 -0
  10. package/dist/chunks/card-DhDwtSi9.js.map +1 -0
  11. package/dist/chunks/code-block-BuDIo8Q0.js +197 -0
  12. package/dist/chunks/code-block-BuDIo8Q0.js.map +1 -0
  13. package/dist/chunks/collapsible-if7ncPbI.js +28 -0
  14. package/dist/chunks/collapsible-if7ncPbI.js.map +1 -0
  15. package/dist/chunks/{command-Ck8IAgV7.js → command-CTYrSz9a.js} +2 -2
  16. package/dist/chunks/{command-Ck8IAgV7.js.map → command-CTYrSz9a.js.map} +1 -1
  17. package/dist/chunks/data-table-DcwCgXJU.js +293 -0
  18. package/dist/chunks/data-table-DcwCgXJU.js.map +1 -0
  19. package/dist/chunks/date-range-picker-DwFDUNRL.js +88 -0
  20. package/dist/chunks/date-range-picker-DwFDUNRL.js.map +1 -0
  21. package/dist/chunks/{dialog-BxKACOj5.js → dialog-BwfUFn6B.js} +2 -2
  22. package/dist/chunks/{dialog-BxKACOj5.js.map → dialog-BwfUFn6B.js.map} +1 -1
  23. package/dist/chunks/{filter-bar-Cjjq38xo.js → filter-bar-BsvdXwzc.js} +2 -2
  24. package/dist/chunks/{filter-bar-Cjjq38xo.js.map → filter-bar-BsvdXwzc.js.map} +1 -1
  25. package/dist/chunks/ghost-search-BvBFa9su.js +25 -0
  26. package/dist/chunks/ghost-search-BvBFa9su.js.map +1 -0
  27. package/dist/chunks/{line-chart-CUR3AxrR.js → line-chart-VuMYKzW3.js} +2 -2
  28. package/dist/chunks/{line-chart-CUR3AxrR.js.map → line-chart-VuMYKzW3.js.map} +1 -1
  29. package/dist/chunks/{log-list-0AXnjFrk.js → log-list-BERiO4UJ.js} +2 -2
  30. package/dist/chunks/{log-list-0AXnjFrk.js.map → log-list-BERiO4UJ.js.map} +1 -1
  31. package/dist/chunks/scroll-area-Zik8t1Mk.js +168 -0
  32. package/dist/chunks/scroll-area-Zik8t1Mk.js.map +1 -0
  33. package/dist/chunks/sidebar-DRPe5CAh.js +306 -0
  34. package/dist/chunks/sidebar-DRPe5CAh.js.map +1 -0
  35. package/dist/chunks/{toast-iSf6NuAS.js → toast-72Wwlzg9.js} +2 -2
  36. package/dist/chunks/{toast-iSf6NuAS.js.map → toast-72Wwlzg9.js.map} +1 -1
  37. package/dist/chunks/trace-Ba1RMBfk.js +1645 -0
  38. package/dist/chunks/trace-Ba1RMBfk.js.map +1 -0
  39. package/dist/chunks/use-measure-C-i54AC6.js +629 -0
  40. package/dist/chunks/use-measure-C-i54AC6.js.map +1 -0
  41. package/dist/components/bar-chart.js +1 -1
  42. package/dist/components/card.js +1 -1
  43. package/dist/components/code-block.js +1 -1
  44. package/dist/components/collapsible.js +2 -25
  45. package/dist/components/command.js +1 -1
  46. package/dist/components/data-table.js +9 -8
  47. package/dist/components/date-range-picker.js +10 -0
  48. package/dist/components/dialog.js +1 -1
  49. package/dist/components/filter-bar.js +1 -1
  50. package/dist/components/line-chart.js +1 -1
  51. package/dist/components/log-list.js +1 -1
  52. package/dist/components/scroll-area.js +1 -1
  53. package/dist/components/toast.js +1 -1
  54. package/dist/components/trace.js +41 -6
  55. package/dist/index.js +166 -121
  56. package/dist/primitives.js +2 -2
  57. package/dist/sections/basic-page.js +5 -5
  58. package/dist/sections/sidebar.js +9 -6
  59. package/dist/src/components/card/card.d.ts +5 -1
  60. package/dist/src/components/chart/scale.d.ts +6 -1
  61. package/dist/src/components/code-block/code-block.d.ts +24 -5
  62. package/dist/src/components/code-block/index.d.ts +1 -1
  63. package/dist/src/components/data-table/data-table.d.ts +54 -13
  64. package/dist/src/components/date-range-picker/date-range-picker.d.ts +31 -0
  65. package/dist/src/components/date-range-picker/index.d.ts +1 -0
  66. package/dist/src/components/scroll-area/scroll-area.d.ts +9 -1
  67. package/dist/src/components/trace/decorations.d.ts +32 -0
  68. package/dist/src/components/trace/index.d.ts +5 -2
  69. package/dist/src/components/trace/layout.d.ts +57 -29
  70. package/dist/src/components/trace/span-primitive.d.ts +168 -0
  71. package/dist/src/components/trace/span-tree.d.ts +148 -0
  72. package/dist/src/components/trace/trace.d.ts +98 -16
  73. package/dist/src/index.d.ts +1 -0
  74. package/dist/src/sections/basic-page/basic-page.d.ts +139 -29
  75. package/dist/src/sections/basic-page/index.d.ts +1 -1
  76. package/dist/src/sections/sidebar/index.d.ts +1 -1
  77. package/dist/src/sections/sidebar/sidebar.d.ts +72 -0
  78. package/dist/src/utils/ghost-search.d.ts +11 -0
  79. package/package.json +5 -1
  80. package/dist/chunks/bar-chart-BJfr3eyd.js.map +0 -1
  81. package/dist/chunks/basic-page-CVZT_zaH.js +0 -1611
  82. package/dist/chunks/basic-page-CVZT_zaH.js.map +0 -1
  83. package/dist/chunks/card-DSW3Uhag.js +0 -56
  84. package/dist/chunks/card-DSW3Uhag.js.map +0 -1
  85. package/dist/chunks/code-block-CdozzaHM.js +0 -139
  86. package/dist/chunks/code-block-CdozzaHM.js.map +0 -1
  87. package/dist/chunks/data-table-CHLJfGkS.js +0 -279
  88. package/dist/chunks/data-table-CHLJfGkS.js.map +0 -1
  89. package/dist/chunks/scroll-area-BO-9PMM7.js +0 -167
  90. package/dist/chunks/scroll-area-BO-9PMM7.js.map +0 -1
  91. package/dist/chunks/sidebar-DVzZsCts.js +0 -223
  92. package/dist/chunks/sidebar-DVzZsCts.js.map +0 -1
  93. package/dist/chunks/trace-CbH0IohX.js +0 -314
  94. package/dist/chunks/trace-CbH0IohX.js.map +0 -1
  95. package/dist/chunks/use-measure-CMVgLouO.js +0 -616
  96. package/dist/chunks/use-measure-CMVgLouO.js.map +0 -1
  97. package/dist/components/collapsible.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"dialog-BxKACOj5.js","names":[],"sources":["../../src/components/dialog/dialog.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type ElementType,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from \"react\";\nimport { Dialog as BaseDialog } from \"@base-ui/react/dialog\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Button, type ButtonProps } from \"../button/button\";\nimport { CloseButton } from \"../button/close-button\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\n/* ========================== Async pending context ========================== */\n\n/** Imperative actions exposed by Base UI's `actionsRef`. */\ninterface RootActions {\n unmount: () => void;\n close: () => void;\n}\n\ninterface DialogPendingContextValue {\n /** True while a `Dialog.Action` promise is in flight. */\n pending: boolean;\n beginPending: () => void;\n endPending: () => void;\n /** Close the dialog imperatively (used by `Dialog.Action` on resolve). */\n close: () => void;\n}\n\nconst DialogPendingContext = createContext<DialogPendingContextValue | null>(\n null,\n);\n\n/**\n * Whether the surrounding dialog has a `Dialog.Action` promise in flight —\n * use it to disable secondary actions (Cancel etc.) while work is pending.\n * Returns `false` outside a `Dialog.Root`.\n */\nexport function useDialogPending(): boolean {\n return useContext(DialogPendingContext)?.pending ?? false;\n}\n\ntype RootProps = ComponentProps<typeof BaseDialog.Root>;\n\n/**\n * `Dialog.Root` with async awareness: while a `Dialog.Action` promise is\n * pending, every close request (outside press, Escape, `Dialog.Close`) is\n * cancelled so the dialog stays open until the work settles. Props pass\n * through to Base UI's `Dialog.Root` unchanged.\n */\nfunction Root({ onOpenChange, actionsRef, ...props }: RootProps) {\n const [pending, setPending] = useState(false);\n // Guard reads a ref so a resolve → close() in the same tick isn't blocked\n // by a not-yet-flushed state update.\n const pendingRef = useRef(false);\n const internalActionsRef = useRef<RootActions | null>(null);\n\n // Keep a caller-supplied actionsRef working alongside our internal one.\n useEffect(() => {\n if (!actionsRef) return;\n actionsRef.current = internalActionsRef.current;\n return () => {\n actionsRef.current = null;\n };\n }, [actionsRef]);\n\n const handleOpenChange = useCallback<NonNullable<RootProps[\"onOpenChange\"]>>(\n (open, eventDetails) => {\n if (!open && pendingRef.current) {\n eventDetails.cancel();\n return;\n }\n onOpenChange?.(open, eventDetails);\n },\n [onOpenChange],\n );\n\n const contextValue = useMemo<DialogPendingContextValue>(\n () => ({\n pending,\n beginPending: () => {\n pendingRef.current = true;\n setPending(true);\n },\n endPending: () => {\n pendingRef.current = false;\n setPending(false);\n },\n close: () => internalActionsRef.current?.close(),\n }),\n [pending],\n );\n\n return (\n <DialogPendingContext.Provider value={contextValue}>\n <BaseDialog.Root\n actionsRef={internalActionsRef}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </DialogPendingContext.Provider>\n );\n}\n\nconst Trigger = BaseDialog.Trigger;\nconst Portal = BaseDialog.Portal;\nconst Close = BaseDialog.Close;\n\n/* ============================== Dialog.Action ============================== */\n\nexport interface DialogActionProps extends Omit<ButtonProps, \"onClick\"> {\n /**\n * Confirm handler. Return a promise to keep the dialog open while it runs:\n * the button shows `loading`, all dismissal is locked, and the dialog\n * closes when the promise resolves. On rejection the dialog stays open —\n * surface errors inside the handler. A non-promise return closes\n * immediately, like `Dialog.Close`.\n */\n onClick?: (\n event: ReactMouseEvent<HTMLButtonElement>,\n ) => void | Promise<unknown>;\n}\n\nfunction isThenable(value: unknown): value is Promise<unknown> {\n return (\n value != null && typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * The confirm button of an action row, with native promise support — a\n * `Button` that runs its (possibly async) `onClick` and closes the dialog\n * when the work settles successfully.\n */\nfunction Action({ onClick, loading, disabled, ...props }: DialogActionProps) {\n const pendingContext = useContext(DialogPendingContext);\n const [busy, setBusy] = useState(false);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n function handleClick(event: ReactMouseEvent<HTMLButtonElement>) {\n if (busy || loading) return;\n const result = onClick?.(event);\n if (!isThenable(result)) {\n pendingContext?.close();\n return;\n }\n setBusy(true);\n pendingContext?.beginPending();\n result.then(\n () => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n pendingContext?.close();\n },\n (error: unknown) => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.error(\"Dialog.Action: async onClick rejected —\", error);\n }\n },\n );\n }\n\n const inert = busy || loading;\n return (\n <Button\n {...props}\n disabled={disabled || inert}\n loading={inert}\n onClick={handleClick}\n />\n );\n}\n\nfunction Backdrop({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Backdrop>) {\n return (\n <BaseDialog.Backdrop\n className={cn(\n \"bg-pho-overlay fixed inset-0 z-50 transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Popup({ className, ...props }: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n // Floating layer: bg-pho-primary + border-pho-secondary hairline, elevation kept.\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed top-1/2 left-1/2 z-50 w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border outline-none\",\n // Global height cap — the inset panel's footprint (inset-4 /\n // sm:inset-8). A flex column so the body region can shrink and\n // scroll while header and actions stay pinned.\n \"flex max-h-[calc(100dvh-2rem)] flex-col sm:max-h-[calc(100dvh-4rem)]\",\n // Opacity + scale only — leave translate centering alone (no transition-all).\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Title({ className, ...props }: StyledProps<typeof BaseDialog.Title>) {\n return (\n <BaseDialog.Title\n className={cn(\n \"text-pho-primary font-display text-display-sm font-medium text-balance\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Description({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Description>) {\n return (\n <BaseDialog.Description\n className={cn(\n \"text-pho-description text-display-xs font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Header icon chrome: secondary ink, a hair of extra air before the title.\n * Panel dialogs use 32px (`size-8`); fullscreen gates step up to 48px\n * (`size-12`) so the glyph reads at viewport scale.\n */\nfunction DialogHeaderIcon({\n children,\n size = \"md\",\n}: {\n children: ReactNode;\n size?: \"md\" | \"lg\";\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"text-pho-secondary mb-1\",\n size === \"lg\" ? \"[&>svg]:size-12\" : \"[&>svg]:size-8\",\n )}\n >\n {children}\n </span>\n );\n}\n\ninterface ContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — typically a Tabler outline icon.\n * Rendered aria-hidden in secondary ink at 32px (`[&>svg]:size-8`). Pass a\n * styled node to override the ink; the size is owned by the slot.\n */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Consequence bullets rendered as a list at the top of the body — one item\n * per outcome (what is deleted, what survives, who loses access). Use on\n * destructive confirms where the one-line description undersells the\n * impact; keep each item to a single short sentence. Wrap the load-bearing\n * figure in `<strong>` (\"<strong>3 members</strong> lose access\") — the\n * list styles it (secondary ink, medium weight); no classes needed.\n */\n consequences?: ReactNode[];\n /**\n * Final cautionary line under `consequences` — error ink at description\n * size (e.g. \"It cannot be undone. Please be certain.\"). Reserve it for\n * irreversible actions; keep it short.\n */\n warning?: ReactNode;\n /**\n * Footer action row (Cancel / Confirm, etc.). Iron rule: when `actions` is\n * set, the header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience panel: renders the portal, backdrop, and styled popup with an\n * optional header (title/description + close) and optional action row. For\n * full control, compose the parts directly (`Dialog.Portal` /\n * `Dialog.Backdrop` / `Dialog.Popup`).\n */\nfunction Content({\n icon,\n title,\n description,\n consequences,\n warning,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: ContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n const hasConsequences = consequences != null && consequences.length > 0;\n // The scrollable middle region — actions stay pinned below it.\n const hasScrollBody = hasConsequences || warning != null || children != null;\n\n return (\n <Portal>\n <Backdrop />\n <Popup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n // Title row height = title only. Close is out of flow, centered\n // on the row, and may paint outside it (no clip, no stretch).\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {hasScrollBody && (\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"flex flex-col gap-5 px-6 py-5\">\n {hasConsequences && (\n <ul className=\"text-pho-description text-md [&_strong]:text-pho-secondary space-y-1 [&_strong]:font-medium\">\n {consequences.map((item, index) => (\n // Hand-drawn marker: a 4px dot on the first line's center —\n // quieter than the browser disc, ink tracks the text.\n <li\n key={index}\n className=\"relative pl-4 before:absolute before:top-2.5 before:left-1 before:size-1 before:rounded-full before:bg-current\"\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n {warning != null && (\n <p className=\"text-pho-error text-display-xs font-medium\">\n {warning}\n </p>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n )}\n {actions != null && (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\",\n !hasScrollBody && \"pt-5\",\n )}\n >\n {actions}\n </div>\n )}\n </Popup>\n </Portal>\n );\n}\n\n/* =========================== Dialog.InsetContent =========================== */\n\n/**\n * Near-fullscreen popup — the viewport minus a breathing ring, floating over\n * a backdrop (the page stays visible through the gap, so it dims like any\n * floating layer). Still a card: border, elevation, rounded corners; the\n * scale gesture stays but shrinks to 98% — at this size 95% reads like a jump.\n */\nfunction InsetPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed inset-4 z-50 flex flex-col overflow-hidden rounded-lg border outline-none sm:inset-8\",\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface InsetContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /** Decorative icon above the title — same treatment as `Content`. */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Bottom action row. Iron rule as `Content`: when `actions` is set, the\n * header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience near-fullscreen panel: header pinned on top, body filling and\n * scrolling on its own, optional action row pinned at the bottom. Sits\n * between `Content` (a focused card) and `FullscreenContent` (a page\n * takeover): use it for roomy working surfaces — pickers, editors, previews —\n * that still want the page peeking through an edge.\n */\nfunction InsetContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: InsetContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n\n return (\n <Portal>\n <Backdrop />\n <InsetPopup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"px-6 py-5\">\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n {actions != null && (\n <div className=\"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\">\n {actions}\n </div>\n )}\n </InsetPopup>\n </Portal>\n );\n}\n\n/* ========================= Dialog.FullscreenContent ======================== */\n\n/**\n * Full-viewport popup — a page-surface takeover instead of a floating card.\n * No backdrop: the popup itself is the layer. Fade only; scale is a floating-\n * card gesture and reads wrong at viewport size.\n */\nfunction FullscreenPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"bg-pho-page fixed inset-0 z-50 overflow-y-auto outline-none\",\n \"transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface FullscreenContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — same chrome as `Content`, but 48px\n * (`size-12`) for viewport-scale gates.\n */\n icon?: ReactNode;\n /** Heading of the takeover. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Action row under the body. Iron rule as `Content`: when `actions` is set,\n * the corner close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Corner close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n /**\n * Classes on the viewport-centering frame (the `min-h-full` flex host).\n * Use to drop the default optical `pb-20` when the stack grows (e.g. a\n * captcha) so true center stays put: `frameClassName=\"pb-6\"`.\n */\n frameClassName?: string;\n children?: ReactNode;\n}\n\n/**\n * Convenience full-screen panel: the whole viewport becomes the dialog, with\n * a centered column at the standalone-flow width (28rem — the same measure as\n * onboarding / invite cards). Column height follows its content through\n * `AnimatedHeight` (same spring as the Card shell), so step swaps — phone →\n * OTP → captcha — glide instead of jumping. Use for gates the visitor must\n * deal with before the page behind makes sense (e.g. binding a phone number);\n * prefer `Content` for everything conversational.\n */\nfunction FullscreenContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n frameClassName,\n children,\n className,\n ...props\n}: FullscreenContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a corner X.\n const showCloseButton = actions == null && showClose;\n\n return (\n <Portal>\n <FullscreenPopup className={className} {...props}>\n {showCloseButton && (\n <Close\n render={<CloseButton className=\"fixed top-4 right-4 z-10\" />}\n />\n )}\n {/* Default `pb-20` optically lifts the column above true center. */}\n <div\n className={cn(\n \"flex min-h-full items-center justify-center px-6 pt-6 pb-20\",\n frameClassName,\n )}\n >\n {/* Width stays on the outer host; AnimatedHeight measures the\n section stack and springs its own height on content changes. */}\n <div className=\"w-full max-w-md\">\n <AnimatedHeight className=\"flex flex-col gap-5\">\n {(icon || title || description) && (\n <div className=\"flex flex-col gap-1\">\n {icon && (\n <DialogHeaderIcon size=\"lg\">{icon}</DialogHeaderIcon>\n )}\n {title && <Title>{title}</Title>}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {children}\n {actions != null && (\n <div className=\"flex items-center justify-end gap-2\">\n {actions}\n </div>\n )}\n </AnimatedHeight>\n </div>\n </div>\n </FullscreenPopup>\n </Portal>\n );\n}\n\n/**\n * Modal dialog built on Base UI `Dialog`. Controlled or uncontrolled via\n * `Dialog.Root` (`open` / `onOpenChange` / `defaultOpen`). `Dialog.Action`\n * adds native promise support: an async confirm keeps the dialog open and\n * undismissable until the work resolves.\n */\nexport const Dialog = {\n Root,\n Trigger,\n Portal,\n Backdrop,\n Popup,\n InsetPopup,\n FullscreenPopup,\n Title,\n Description,\n Close,\n Action,\n Content,\n InsetContent,\n FullscreenContent,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"dialog-BwfUFn6B.js","names":[],"sources":["../../src/components/dialog/dialog.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ComponentProps,\n type ElementType,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from \"react\";\nimport { Dialog as BaseDialog } from \"@base-ui/react/dialog\";\nimport { AnimatedHeight } from \"../../utils/animated-height\";\nimport { cn } from \"../../utils/cn\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Button, type ButtonProps } from \"../button/button\";\nimport { CloseButton } from \"../button/close-button\";\n\n/** Override Base UI's `string | (state) => string` className with plain string. */\ntype StyledProps<T extends ElementType> = Omit<\n ComponentProps<T>,\n \"className\"\n> & {\n className?: string;\n};\n\n/* ========================== Async pending context ========================== */\n\n/** Imperative actions exposed by Base UI's `actionsRef`. */\ninterface RootActions {\n unmount: () => void;\n close: () => void;\n}\n\ninterface DialogPendingContextValue {\n /** True while a `Dialog.Action` promise is in flight. */\n pending: boolean;\n beginPending: () => void;\n endPending: () => void;\n /** Close the dialog imperatively (used by `Dialog.Action` on resolve). */\n close: () => void;\n}\n\nconst DialogPendingContext = createContext<DialogPendingContextValue | null>(\n null,\n);\n\n/**\n * Whether the surrounding dialog has a `Dialog.Action` promise in flight —\n * use it to disable secondary actions (Cancel etc.) while work is pending.\n * Returns `false` outside a `Dialog.Root`.\n */\nexport function useDialogPending(): boolean {\n return useContext(DialogPendingContext)?.pending ?? false;\n}\n\ntype RootProps = ComponentProps<typeof BaseDialog.Root>;\n\n/**\n * `Dialog.Root` with async awareness: while a `Dialog.Action` promise is\n * pending, every close request (outside press, Escape, `Dialog.Close`) is\n * cancelled so the dialog stays open until the work settles. Props pass\n * through to Base UI's `Dialog.Root` unchanged.\n */\nfunction Root({ onOpenChange, actionsRef, ...props }: RootProps) {\n const [pending, setPending] = useState(false);\n // Guard reads a ref so a resolve → close() in the same tick isn't blocked\n // by a not-yet-flushed state update.\n const pendingRef = useRef(false);\n const internalActionsRef = useRef<RootActions | null>(null);\n\n // Keep a caller-supplied actionsRef working alongside our internal one.\n useEffect(() => {\n if (!actionsRef) return;\n actionsRef.current = internalActionsRef.current;\n return () => {\n actionsRef.current = null;\n };\n }, [actionsRef]);\n\n const handleOpenChange = useCallback<NonNullable<RootProps[\"onOpenChange\"]>>(\n (open, eventDetails) => {\n if (!open && pendingRef.current) {\n eventDetails.cancel();\n return;\n }\n onOpenChange?.(open, eventDetails);\n },\n [onOpenChange],\n );\n\n const contextValue = useMemo<DialogPendingContextValue>(\n () => ({\n pending,\n beginPending: () => {\n pendingRef.current = true;\n setPending(true);\n },\n endPending: () => {\n pendingRef.current = false;\n setPending(false);\n },\n close: () => internalActionsRef.current?.close(),\n }),\n [pending],\n );\n\n return (\n <DialogPendingContext.Provider value={contextValue}>\n <BaseDialog.Root\n actionsRef={internalActionsRef}\n onOpenChange={handleOpenChange}\n {...props}\n />\n </DialogPendingContext.Provider>\n );\n}\n\nconst Trigger = BaseDialog.Trigger;\nconst Portal = BaseDialog.Portal;\nconst Close = BaseDialog.Close;\n\n/* ============================== Dialog.Action ============================== */\n\nexport interface DialogActionProps extends Omit<ButtonProps, \"onClick\"> {\n /**\n * Confirm handler. Return a promise to keep the dialog open while it runs:\n * the button shows `loading`, all dismissal is locked, and the dialog\n * closes when the promise resolves. On rejection the dialog stays open —\n * surface errors inside the handler. A non-promise return closes\n * immediately, like `Dialog.Close`.\n */\n onClick?: (\n event: ReactMouseEvent<HTMLButtonElement>,\n ) => void | Promise<unknown>;\n}\n\nfunction isThenable(value: unknown): value is Promise<unknown> {\n return (\n value != null && typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * The confirm button of an action row, with native promise support — a\n * `Button` that runs its (possibly async) `onClick` and closes the dialog\n * when the work settles successfully.\n */\nfunction Action({ onClick, loading, disabled, ...props }: DialogActionProps) {\n const pendingContext = useContext(DialogPendingContext);\n const [busy, setBusy] = useState(false);\n const mountedRef = useRef(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n function handleClick(event: ReactMouseEvent<HTMLButtonElement>) {\n if (busy || loading) return;\n const result = onClick?.(event);\n if (!isThenable(result)) {\n pendingContext?.close();\n return;\n }\n setBusy(true);\n pendingContext?.beginPending();\n result.then(\n () => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n pendingContext?.close();\n },\n (error: unknown) => {\n pendingContext?.endPending();\n if (mountedRef.current) setBusy(false);\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.error(\"Dialog.Action: async onClick rejected —\", error);\n }\n },\n );\n }\n\n const inert = busy || loading;\n return (\n <Button\n {...props}\n disabled={disabled || inert}\n loading={inert}\n onClick={handleClick}\n />\n );\n}\n\nfunction Backdrop({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Backdrop>) {\n return (\n <BaseDialog.Backdrop\n className={cn(\n \"bg-pho-overlay fixed inset-0 z-50 transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Popup({ className, ...props }: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n // Floating layer: bg-pho-primary + border-pho-secondary hairline, elevation kept.\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed top-1/2 left-1/2 z-50 w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border outline-none\",\n // Global height cap — the inset panel's footprint (inset-4 /\n // sm:inset-8). A flex column so the body region can shrink and\n // scroll while header and actions stay pinned.\n \"flex max-h-[calc(100dvh-2rem)] flex-col sm:max-h-[calc(100dvh-4rem)]\",\n // Opacity + scale only — leave translate centering alone (no transition-all).\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Title({ className, ...props }: StyledProps<typeof BaseDialog.Title>) {\n return (\n <BaseDialog.Title\n className={cn(\n \"text-pho-primary font-display text-display-sm font-medium text-balance\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Description({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Description>) {\n return (\n <BaseDialog.Description\n className={cn(\n \"text-pho-description text-display-xs font-normal\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Header icon chrome: secondary ink, a hair of extra air before the title.\n * Panel dialogs use 32px (`size-8`); fullscreen gates step up to 48px\n * (`size-12`) so the glyph reads at viewport scale.\n */\nfunction DialogHeaderIcon({\n children,\n size = \"md\",\n}: {\n children: ReactNode;\n size?: \"md\" | \"lg\";\n}) {\n return (\n <span\n aria-hidden\n className={cn(\n \"text-pho-secondary mb-1\",\n size === \"lg\" ? \"[&>svg]:size-12\" : \"[&>svg]:size-8\",\n )}\n >\n {children}\n </span>\n );\n}\n\ninterface ContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — typically a Tabler outline icon.\n * Rendered aria-hidden in secondary ink at 32px (`[&>svg]:size-8`). Pass a\n * styled node to override the ink; the size is owned by the slot.\n */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Consequence bullets rendered as a list at the top of the body — one item\n * per outcome (what is deleted, what survives, who loses access). Use on\n * destructive confirms where the one-line description undersells the\n * impact; keep each item to a single short sentence. Wrap the load-bearing\n * figure in `<strong>` (\"<strong>3 members</strong> lose access\") — the\n * list styles it (secondary ink, medium weight); no classes needed.\n */\n consequences?: ReactNode[];\n /**\n * Final cautionary line under `consequences` — error ink at description\n * size (e.g. \"It cannot be undone. Please be certain.\"). Reserve it for\n * irreversible actions; keep it short.\n */\n warning?: ReactNode;\n /**\n * Footer action row (Cancel / Confirm, etc.). Iron rule: when `actions` is\n * set, the header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience panel: renders the portal, backdrop, and styled popup with an\n * optional header (title/description + close) and optional action row. For\n * full control, compose the parts directly (`Dialog.Portal` /\n * `Dialog.Backdrop` / `Dialog.Popup`).\n */\nfunction Content({\n icon,\n title,\n description,\n consequences,\n warning,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: ContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n const hasConsequences = consequences != null && consequences.length > 0;\n // The scrollable middle region — actions stay pinned below it.\n const hasScrollBody = hasConsequences || warning != null || children != null;\n\n return (\n <Portal>\n <Backdrop />\n <Popup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n // Title row height = title only. Close is out of flow, centered\n // on the row, and may paint outside it (no clip, no stretch).\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {hasScrollBody && (\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"flex flex-col gap-5 px-6 py-5\">\n {hasConsequences && (\n <ul className=\"text-pho-description text-md [&_strong]:text-pho-secondary space-y-1 [&_strong]:font-medium\">\n {consequences.map((item, index) => (\n // Hand-drawn marker: a 4px dot on the first line's center —\n // quieter than the browser disc, ink tracks the text.\n <li\n key={index}\n className=\"relative pl-4 before:absolute before:top-2.5 before:left-1 before:size-1 before:rounded-full before:bg-current\"\n >\n {item}\n </li>\n ))}\n </ul>\n )}\n {warning != null && (\n <p className=\"text-pho-error text-display-xs font-medium\">\n {warning}\n </p>\n )}\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n )}\n {actions != null && (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\",\n !hasScrollBody && \"pt-5\",\n )}\n >\n {actions}\n </div>\n )}\n </Popup>\n </Portal>\n );\n}\n\n/* =========================== Dialog.InsetContent =========================== */\n\n/**\n * Near-fullscreen popup — the viewport minus a breathing ring, floating over\n * a backdrop (the page stays visible through the gap, so it dims like any\n * floating layer). Still a card: border, elevation, rounded corners; the\n * scale gesture stays but shrinks to 98% — at this size 95% reads like a jump.\n */\nfunction InsetPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"border-pho-secondary bg-pho-primary shadow-pho-xl fixed inset-4 z-50 flex flex-col overflow-hidden rounded-lg border outline-none sm:inset-8\",\n \"transition-[opacity,scale] duration-200 ease-out\",\n \"data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[ending-style]:duration-150\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface InsetContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /** Decorative icon above the title — same treatment as `Content`. */\n icon?: ReactNode;\n /** Heading rendered in the panel header. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Bottom action row. Iron rule as `Content`: when `actions` is set, the\n * header close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Header close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Convenience near-fullscreen panel: header pinned on top, body filling and\n * scrolling on its own, optional action row pinned at the bottom. Sits\n * between `Content` (a focused card) and `FullscreenContent` (a page\n * takeover): use it for roomy working surfaces — pickers, editors, previews —\n * that still want the page peeking through an edge.\n */\nfunction InsetContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n children,\n className,\n ...props\n}: InsetContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a header X.\n const showCloseButton = actions == null && showClose;\n const hasHeader = Boolean(icon || title || description || showCloseButton);\n\n return (\n <Portal>\n <Backdrop />\n <InsetPopup className={className} {...props}>\n {hasHeader && (\n <div className=\"flex shrink-0 flex-col gap-1 px-6 pt-6\">\n {icon && <DialogHeaderIcon>{icon}</DialogHeaderIcon>}\n {(title || showCloseButton) && (\n <div className=\"relative\">\n {title ? (\n <Title className={showCloseButton ? \"pr-12\" : undefined}>\n {title}\n </Title>\n ) : (\n <div className=\"h-[1.625rem]\" aria-hidden=\"true\" />\n )}\n {showCloseButton && (\n <Close\n render={\n <CloseButton className=\"absolute top-1/2 right-0 z-10 -translate-y-1/2\" />\n }\n />\n )}\n </div>\n )}\n {description && <Description>{description}</Description>}\n </div>\n )}\n <ScrollArea.Root className=\"min-h-0 flex-1\">\n <ScrollArea.Viewport>\n <ScrollArea.Content className=\"px-6 py-5\">\n {children}\n </ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n {actions != null && (\n <div className=\"flex shrink-0 items-center justify-end gap-2 px-6 pb-5\">\n {actions}\n </div>\n )}\n </InsetPopup>\n </Portal>\n );\n}\n\n/* ========================= Dialog.FullscreenContent ======================== */\n\n/**\n * Full-viewport popup — a page-surface takeover instead of a floating card.\n * No backdrop: the popup itself is the layer. Fade only; scale is a floating-\n * card gesture and reads wrong at viewport size.\n */\nfunction FullscreenPopup({\n className,\n ...props\n}: StyledProps<typeof BaseDialog.Popup>) {\n return (\n <BaseDialog.Popup\n className={cn(\n \"bg-pho-page fixed inset-0 z-50 overflow-y-auto outline-none\",\n \"transition-opacity duration-200 ease-out\",\n \"data-[ending-style]:opacity-0 data-[ending-style]:duration-150 data-[starting-style]:opacity-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\ninterface FullscreenContentProps extends Omit<\n StyledProps<typeof BaseDialog.Popup>,\n \"title\"\n> {\n /**\n * Decorative icon above the title — same chrome as `Content`, but 48px\n * (`size-12`) for viewport-scale gates.\n */\n icon?: ReactNode;\n /** Heading of the takeover. */\n title?: ReactNode;\n /** Supporting text under the title. */\n description?: ReactNode;\n /**\n * Action row under the body. Iron rule as `Content`: when `actions` is set,\n * the corner close button is never shown — dismiss via the actions.\n */\n actions?: ReactNode;\n /**\n * Corner close control. Only applies when `actions` is absent.\n * @default true\n */\n showClose?: boolean;\n /**\n * Classes on the viewport-centering frame (the `min-h-full` flex host).\n * Use to drop the default optical `pb-20` when the stack grows (e.g. a\n * captcha) so true center stays put: `frameClassName=\"pb-6\"`.\n */\n frameClassName?: string;\n children?: ReactNode;\n}\n\n/**\n * Convenience full-screen panel: the whole viewport becomes the dialog, with\n * a centered column at the standalone-flow width (28rem — the same measure as\n * onboarding / invite cards). Column height follows its content through\n * `AnimatedHeight` (same spring as the Card shell), so step swaps — phone →\n * OTP → captcha — glide instead of jumping. Use for gates the visitor must\n * deal with before the page behind makes sense (e.g. binding a phone number);\n * prefer `Content` for everything conversational.\n */\nfunction FullscreenContent({\n icon,\n title,\n description,\n actions,\n showClose = true,\n frameClassName,\n children,\n className,\n ...props\n}: FullscreenContentProps) {\n // Iron rule: action dialogs dismiss via their actions — never a corner X.\n const showCloseButton = actions == null && showClose;\n\n return (\n <Portal>\n <FullscreenPopup className={className} {...props}>\n {showCloseButton && (\n <Close\n render={<CloseButton className=\"fixed top-4 right-4 z-10\" />}\n />\n )}\n {/* Default `pb-20` optically lifts the column above true center. */}\n <div\n className={cn(\n \"flex min-h-full items-center justify-center px-6 pt-6 pb-20\",\n frameClassName,\n )}\n >\n {/* Width stays on the outer host; AnimatedHeight measures the\n section stack and springs its own height on content changes. */}\n <div className=\"w-full max-w-md\">\n <AnimatedHeight className=\"flex flex-col gap-5\">\n {(icon || title || description) && (\n <div className=\"flex flex-col gap-1\">\n {icon && (\n <DialogHeaderIcon size=\"lg\">{icon}</DialogHeaderIcon>\n )}\n {title && <Title>{title}</Title>}\n {description && <Description>{description}</Description>}\n </div>\n )}\n {children}\n {actions != null && (\n <div className=\"flex items-center justify-end gap-2\">\n {actions}\n </div>\n )}\n </AnimatedHeight>\n </div>\n </div>\n </FullscreenPopup>\n </Portal>\n );\n}\n\n/**\n * Modal dialog built on Base UI `Dialog`. Controlled or uncontrolled via\n * `Dialog.Root` (`open` / `onOpenChange` / `defaultOpen`). `Dialog.Action`\n * adds native promise support: an async confirm keeps the dialog open and\n * undismissable until the work resolves.\n */\nexport const Dialog = {\n Root,\n Trigger,\n Portal,\n Backdrop,\n Popup,\n InsetPopup,\n FullscreenPopup,\n Title,\n Description,\n Close,\n Action,\n Content,\n InsetContent,\n FullscreenContent,\n};\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { t as L } from "./IconSearch-BKAHkLyX.js";
7
7
  import { t as $ } from "./IconX-pZ9vrtSr.js";
8
8
  import { t as w } from "./input-group-fc9_jD4d.js";
9
9
  import { t as g } from "./popover-BhBJO346.js";
10
- import { t as d } from "./command-Ck8IAgV7.js";
10
+ import { t as d } from "./command-CTYrSz9a.js";
11
11
  import { useRef as D, useState as T } from "react";
12
12
  import { jsx as a, jsxs as u } from "react/jsx-runtime";
13
13
  var E = [["path", {
@@ -256,4 +256,4 @@ export {
256
256
  O as t
257
257
  };
258
258
 
259
- //# sourceMappingURL=filter-bar-Cjjq38xo.js.map
259
+ //# sourceMappingURL=filter-bar-BsvdXwzc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar-Cjjq38xo.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs","../../src/components/filter-bar/filter-bar.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l14 0\", \"key\": \"svg-1\" }]];\nconst IconPlus = createReactComponent(\"outline\", \"plus\", \"Plus\", __iconNode);\n\nexport { __iconNode, IconPlus as default };\n//# sourceMappingURL=IconPlus.mjs.map\n","import {\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport { IconCheck, IconPlus, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { Button } from \"../button\";\nimport { Command } from \"../command\";\nimport { InputGroup } from \"../input-group\";\nimport { Popover } from \"../popover\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Filter Bar — the row that pins above a log list: a search field for an\n * id, then one chip per filter. A chip with nothing chosen reads\n * `+ Status`; with a value it reads `Status: Failed` and carries its own\n * clear. Each chip opens a small popover: a keyboard-first list of\n * options (with a search field past eight of them), or presets and a\n * from / to pair for a date range.\n *\n * Design notes:\n * - Fully controlled. The page owns `filters` and `search` and hands\n * them back changed; the bar keeps no state but which popover is open.\n * That keeps the query in one place (the URL, a store) and lets the\n * list refetch from it.\n * - Chips are real buttons (the trigger, and the clear beside it), so\n * the bar is one tab stop per control and Escape closes a popover\n * back onto its chip.\n * - No scroll container of its own: chips wrap. `sticky` pins it to the\n * top of the nearest scroll pane on the surface it sits on.\n */\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\ninterface FilterDefinitionBase {\n /** The key in `filters` this chip reads and writes. */\n key: string;\n /** The chip's word — \"Status\", \"Event type\". Sentence case. */\n label: string;\n}\n\nexport interface SelectFilterDefinition extends FilterDefinitionBase {\n type?: \"select\";\n options: readonly FilterOption[];\n /** Several values at once (`string[]`); one at a time by default. */\n multiple?: boolean;\n /**\n * A search field above the options. On by default past eight options,\n * off below; say so to override.\n */\n searchable?: boolean;\n /** The search field's placeholder. @default \"Search\" */\n searchPlaceholder?: string;\n}\n\n/** A relative preset for a date-range filter — \"Last 7 days\" is 168 hours. */\nexport interface DateRangePreset {\n label: string;\n hours: number;\n}\n\nexport interface DateRangeFilterDefinition extends FilterDefinitionBase {\n type: \"date-range\";\n /** The relative presets listed above the from / to pair. */\n presets?: readonly DateRangePreset[];\n}\n\nexport type FilterDefinition =\n SelectFilterDefinition | DateRangeFilterDefinition;\n\n/**\n * A date-range value. A preset stores an absolute ISO timestamp in `from`\n * (computed when chosen) and its label in `preset`; the from / to pair\n * stores plain `YYYY-MM-DD` dates. Either side may be open (`null`).\n */\nexport interface DateRangeValue {\n from: string | null;\n to: string | null;\n preset?: string;\n}\n\nexport type FilterValue = string | string[] | DateRangeValue;\n\n/** The page's filter state — one entry per definition key that is set. */\nexport type FilterValues = Record<string, FilterValue | undefined>;\n\n/** The relative presets a date-range chip lists when given none. */\nexport const FILTER_DATE_PRESETS: readonly DateRangePreset[] = [\n { label: \"Last hour\", hours: 1 },\n { label: \"Last 24 hours\", hours: 24 },\n { label: \"Last 7 days\", hours: 24 * 7 },\n { label: \"Last 30 days\", hours: 24 * 30 },\n];\n\n/** Past this many options a select chip shows a search field. */\nconst SEARCHABLE_PAST = 8;\n\n/** Whether a filter value counts as set — an empty string or list does not. */\nexport function isFilterSet(value: FilterValue | undefined): boolean {\n if (value == null) return false;\n if (typeof value === \"string\") return value !== \"\";\n if (Array.isArray(value)) return value.length > 0;\n return value.from != null || value.to != null;\n}\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction formatDay(value: string): string {\n // A plain date is a calendar day: format it in UTC so the day survives\n // every viewer timezone. A timestamp is a moment: format it locally.\n const dateOnly = DATE_ONLY.test(value);\n const date = new Date(dateOnly ? `${value}T00:00:00Z` : value);\n if (Number.isNaN(date.getTime())) return value;\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n ...(dateOnly ? { timeZone: \"UTC\" } : {}),\n }).format(date);\n}\n\n/** The words a set chip shows after its label. */\nexport function formatFilterValue(\n definition: FilterDefinition,\n value: FilterValue | undefined,\n): string {\n if (!isFilterSet(value) || value == null) return \"\";\n if (definition.type === \"date-range\") {\n const range = value as DateRangeValue;\n if (range.preset) return range.preset;\n if (range.from && range.to) {\n return `${formatDay(range.from)} to ${formatDay(range.to)}`;\n }\n if (range.from) return `From ${formatDay(range.from)}`;\n if (range.to) return `Until ${formatDay(range.to)}`;\n return \"\";\n }\n const labelOf = (item: string) =>\n definition.options.find((option) => option.value === item)?.label ?? item;\n if (Array.isArray(value)) return value.map(labelOf).join(\", \");\n return typeof value === \"string\" ? labelOf(value) : \"\";\n}\n\n/* --------------------------------- chips -------------------------------- */\n\nconst CHIP_TRIGGER =\n \"outline-pho-brand flex h-8 min-w-0 cursor-pointer items-center gap-1.5 rounded-full text-base transition-[color,background-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2 [&>svg]:size-4 [&>svg]:shrink-0\";\n\nfunction FilterChip({\n definition,\n value,\n onChange,\n}: {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n onChange: (next: FilterValue | undefined) => void;\n}) {\n const [open, setOpen] = useState(false);\n const focusRef = useRef<HTMLElement | null>(null);\n const set = isFilterSet(value);\n const display = formatFilterValue(definition, value);\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <span\n data-filter-chip={definition.key}\n data-set={set || undefined}\n className={cn(\n \"ring-pho-primary inline-flex max-w-full shrink-0 items-stretch rounded-full ring-1 ring-inset\",\n set ? \"bg-pho-secondary\" : \"bg-transparent\",\n )}\n >\n <Popover.Trigger\n aria-label={set ? undefined : `${definition.label} filter`}\n className={cn(\n CHIP_TRIGGER,\n \"hover:bg-pho-ghost-hover\",\n set ? \"pr-1.5 pl-3\" : \"pr-3 pl-2.5\",\n set ? \"rounded-r-none\" : \"\",\n )}\n >\n {set ? null : <IconPlus aria-hidden />}\n {set ? (\n <span className=\"flex min-w-0 items-baseline gap-1\">\n <span className=\"text-pho-description shrink-0\">\n {definition.label}:\n </span>\n <span className=\"text-pho-primary max-w-56 truncate font-medium\">\n {display}\n </span>\n </span>\n ) : (\n <span className=\"text-pho-secondary\">{definition.label}</span>\n )}\n </Popover.Trigger>\n {set ? (\n <button\n type=\"button\"\n aria-label={`Clear ${definition.label.toLowerCase()} filter`}\n onClick={() => onChange(undefined)}\n className={cn(\n CHIP_TRIGGER,\n \"text-pho-secondary hover:bg-pho-ghost-hover hover:text-pho-secondary-hover rounded-l-none pr-2.5 pl-1 [&>svg]:size-3.5\",\n )}\n >\n <IconX aria-hidden />\n </button>\n ) : null}\n </span>\n <Popover.Portal>\n <Popover.Positioner align=\"start\" sideOffset={6}>\n <Popover.Popup\n aria-label={`${definition.label} filter`}\n initialFocus={focusRef}\n className={cn(\n \"w-64 p-0\",\n definition.type === \"date-range\" && \"w-72\",\n )}\n >\n {definition.type === \"date-range\" ? (\n <DateRangePanel\n definition={definition}\n value={value as DateRangeValue | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (next?.preset) setOpen(false);\n }}\n />\n ) : (\n <OptionsPanel\n definition={definition}\n value={value as string | string[] | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (!definition.multiple) setOpen(false);\n }}\n />\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\nfunction OptionsPanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: SelectFilterDefinition;\n value: string | string[] | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: string | string[] | undefined) => void;\n}) {\n const [query, setQuery] = useState(\"\");\n const searchable =\n definition.searchable ?? definition.options.length > SEARCHABLE_PAST;\n const chosen = new Set(\n value == null ? [] : Array.isArray(value) ? value : [value],\n );\n const needle = query.trim().toLowerCase();\n const options = needle\n ? definition.options.filter(\n (option) =>\n option.label.toLowerCase().includes(needle) ||\n option.value.toLowerCase().includes(needle),\n )\n : definition.options;\n const pick = (option: FilterOption) => {\n if (definition.multiple) {\n const next = new Set(chosen);\n if (next.has(option.value)) next.delete(option.value);\n else next.add(option.value);\n // Keep the definition's order, so the chip reads the same way\n // whatever order the values were chosen in.\n const ordered = definition.options\n .map((item) => item.value)\n .filter((item) => next.has(item));\n onChange(ordered.length > 0 ? ordered : undefined);\n return;\n }\n onChange(chosen.has(option.value) ? undefined : option.value);\n };\n return (\n <Command.Root\n label={`${definition.label} options`}\n // Without a search field the list itself takes focus, so the arrow\n // keys work from the first frame.\n ref={(node: HTMLDivElement | null) => {\n if (!searchable) focusRef.current = node;\n }}\n className=\"rounded-base\"\n >\n {searchable ? (\n <Command.InputGroup>\n <IconSearch\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute left-3 size-4\"\n />\n <Command.Input\n ref={(node: HTMLInputElement | null) => {\n focusRef.current = node;\n }}\n value={query}\n onValueChange={setQuery}\n placeholder={definition.searchPlaceholder ?? \"Search\"}\n aria-label={`Search ${definition.label.toLowerCase()} options`}\n className=\"py-2 pr-3 pl-9 text-base\"\n />\n </Command.InputGroup>\n ) : null}\n <Command.List>\n <Command.Empty>Nothing matches.</Command.Empty>\n {options.map((option) => (\n <Command.Item\n key={option.value}\n value={option.value}\n title={option.label}\n aria-checked={chosen.has(option.value)}\n icon={chosen.has(option.value) ? <IconCheck aria-hidden /> : null}\n onSelect={() => pick(option)}\n />\n ))}\n </Command.List>\n </Command.Root>\n );\n}\n\nconst DATE_INPUT =\n \"bg-pho-primary ring-pho-primary text-pho-primary focus-visible:ring-pho-brand w-full min-w-0 rounded-sm px-2 py-1 text-base ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2\";\n\nfunction DateRangePanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: DateRangeFilterDefinition;\n value: DateRangeValue | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: DateRangeValue | undefined) => void;\n}) {\n const presets = definition.presets ?? FILTER_DATE_PRESETS;\n // A preset's `from` is a timestamp; the day field shows its date.\n const day = (side: string | null | undefined) =>\n side == null ? \"\" : DATE_ONLY.test(side) ? side : side.slice(0, 10);\n const setSide = (side: \"from\" | \"to\", next: string) => {\n // Editing either day leaves a preset behind: the pair is the value now,\n // and a preset's timestamp becomes the day it fell on.\n const range: DateRangeValue = {\n from: day(value?.from) || null,\n to: day(value?.to) || null,\n [side]: next || null,\n };\n onChange(range.from == null && range.to == null ? undefined : range);\n };\n return (\n <div className=\"flex flex-col\">\n <Command.Root\n label={`${definition.label} presets`}\n ref={(node: HTMLDivElement | null) => {\n focusRef.current = node;\n }}\n className=\"rounded-t-[inherit]\"\n >\n <Command.List>\n {presets.map((preset) => (\n <Command.Item\n key={preset.label}\n value={preset.label}\n title={preset.label}\n aria-checked={value?.preset === preset.label}\n icon={\n value?.preset === preset.label ? (\n <IconCheck aria-hidden />\n ) : null\n }\n onSelect={() =>\n onChange({\n from: new Date(\n Date.now() - preset.hours * 60 * 60 * 1000,\n ).toISOString(),\n to: null,\n preset: preset.label,\n })\n }\n />\n ))}\n </Command.List>\n </Command.Root>\n {/* The day fields stand outside the command list: its arrow-key\n handling would otherwise swallow the native date stepping. */}\n <div className=\"border-pho-secondary grid grid-cols-2 gap-2 border-t p-2\">\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n From\n <input\n type=\"date\"\n value={day(value?.from)}\n max={day(value?.to) || undefined}\n onChange={(event) => setSide(\"from\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n To\n <input\n type=\"date\"\n value={day(value?.to)}\n min={day(value?.from) || undefined}\n onChange={(event) => setSide(\"to\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n </div>\n </div>\n );\n}\n\n/* ---------------------------------- bar --------------------------------- */\n\nexport interface FilterBarProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** One chip per definition, in this order. */\n definitions: readonly FilterDefinition[];\n /** The values, keyed by definition key. Absent or empty means unset. */\n filters: FilterValues;\n /** The whole map, changed — set, cleared, or cleared all. */\n onFiltersChange: (next: FilterValues) => void;\n /** The search field's text. The field renders only with `onSearchChange`. */\n search?: string;\n onSearchChange?: (value: string) => void;\n /** A teaching phrase — \"Find an event by id\". @default \"Search\" */\n searchPlaceholder?: string;\n /** The field's accessible name when the placeholder is too short to be one. */\n searchLabel?: string;\n /**\n * Pin the bar to the top of the nearest scroll pane. It paints the\n * surface it sits on (`--pho-surface`) so rows scroll under it.\n */\n sticky?: boolean;\n /** Controls after the chips — a range picker, an export button. */\n children?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport function FilterBar({\n definitions,\n filters,\n onFiltersChange,\n search,\n onSearchChange,\n searchPlaceholder = \"Search\",\n searchLabel,\n sticky,\n className,\n children,\n ...props\n}: FilterBarProps) {\n const setCount = definitions.filter((definition) =>\n isFilterSet(filters[definition.key]),\n ).length;\n const change = (key: string, next: FilterValue | undefined) => {\n const rest = { ...filters };\n if (next === undefined) delete rest[key];\n else rest[key] = next;\n onFiltersChange(rest);\n };\n return (\n <div\n data-filter-bar=\"\"\n className={cn(\n \"flex min-w-0 flex-wrap items-center gap-2\",\n sticky &&\n \"sticky top-0 z-10 bg-[var(--pho-surface,var(--background-color-pho-page))] py-3\",\n className,\n )}\n {...props}\n >\n {onSearchChange != null ? (\n <InputGroup.Root size=\"sm\" className=\"w-64 max-w-full\">\n <InputGroup.Addon>\n <IconSearch />\n </InputGroup.Addon>\n <InputGroup.Input\n type=\"search\"\n value={search ?? \"\"}\n onChange={(event) => onSearchChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n onSearchChange(\"\");\n }}\n placeholder={searchPlaceholder}\n aria-label={searchLabel ?? searchPlaceholder}\n />\n </InputGroup.Root>\n ) : null}\n {definitions.map((definition) => (\n <FilterChip\n key={definition.key}\n definition={definition}\n value={filters[definition.key]}\n onChange={(next) => change(definition.key, next)}\n />\n ))}\n {setCount > 1 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n const rest = { ...filters };\n for (const definition of definitions) delete rest[definition.key];\n onFiltersChange(rest);\n }}\n >\n Clear filters\n </Button>\n ) : null}\n {children}\n </div>\n );\n}\n\nFilterBar.displayName = \"FilterBar\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"filter-bar-BsvdXwzc.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs","../../src/components/filter-bar/filter-bar.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l14 0\", \"key\": \"svg-1\" }]];\nconst IconPlus = createReactComponent(\"outline\", \"plus\", \"Plus\", __iconNode);\n\nexport { __iconNode, IconPlus as default };\n//# sourceMappingURL=IconPlus.mjs.map\n","import {\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport { IconCheck, IconPlus, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { Button } from \"../button\";\nimport { Command } from \"../command\";\nimport { InputGroup } from \"../input-group\";\nimport { Popover } from \"../popover\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Filter Bar — the row that pins above a log list: a search field for an\n * id, then one chip per filter. A chip with nothing chosen reads\n * `+ Status`; with a value it reads `Status: Failed` and carries its own\n * clear. Each chip opens a small popover: a keyboard-first list of\n * options (with a search field past eight of them), or presets and a\n * from / to pair for a date range.\n *\n * Design notes:\n * - Fully controlled. The page owns `filters` and `search` and hands\n * them back changed; the bar keeps no state but which popover is open.\n * That keeps the query in one place (the URL, a store) and lets the\n * list refetch from it.\n * - Chips are real buttons (the trigger, and the clear beside it), so\n * the bar is one tab stop per control and Escape closes a popover\n * back onto its chip.\n * - No scroll container of its own: chips wrap. `sticky` pins it to the\n * top of the nearest scroll pane on the surface it sits on.\n */\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\ninterface FilterDefinitionBase {\n /** The key in `filters` this chip reads and writes. */\n key: string;\n /** The chip's word — \"Status\", \"Event type\". Sentence case. */\n label: string;\n}\n\nexport interface SelectFilterDefinition extends FilterDefinitionBase {\n type?: \"select\";\n options: readonly FilterOption[];\n /** Several values at once (`string[]`); one at a time by default. */\n multiple?: boolean;\n /**\n * A search field above the options. On by default past eight options,\n * off below; say so to override.\n */\n searchable?: boolean;\n /** The search field's placeholder. @default \"Search\" */\n searchPlaceholder?: string;\n}\n\n/** A relative preset for a date-range filter — \"Last 7 days\" is 168 hours. */\nexport interface DateRangePreset {\n label: string;\n hours: number;\n}\n\nexport interface DateRangeFilterDefinition extends FilterDefinitionBase {\n type: \"date-range\";\n /** The relative presets listed above the from / to pair. */\n presets?: readonly DateRangePreset[];\n}\n\nexport type FilterDefinition =\n SelectFilterDefinition | DateRangeFilterDefinition;\n\n/**\n * A date-range value. A preset stores an absolute ISO timestamp in `from`\n * (computed when chosen) and its label in `preset`; the from / to pair\n * stores plain `YYYY-MM-DD` dates. Either side may be open (`null`).\n */\nexport interface DateRangeValue {\n from: string | null;\n to: string | null;\n preset?: string;\n}\n\nexport type FilterValue = string | string[] | DateRangeValue;\n\n/** The page's filter state — one entry per definition key that is set. */\nexport type FilterValues = Record<string, FilterValue | undefined>;\n\n/** The relative presets a date-range chip lists when given none. */\nexport const FILTER_DATE_PRESETS: readonly DateRangePreset[] = [\n { label: \"Last hour\", hours: 1 },\n { label: \"Last 24 hours\", hours: 24 },\n { label: \"Last 7 days\", hours: 24 * 7 },\n { label: \"Last 30 days\", hours: 24 * 30 },\n];\n\n/** Past this many options a select chip shows a search field. */\nconst SEARCHABLE_PAST = 8;\n\n/** Whether a filter value counts as set — an empty string or list does not. */\nexport function isFilterSet(value: FilterValue | undefined): boolean {\n if (value == null) return false;\n if (typeof value === \"string\") return value !== \"\";\n if (Array.isArray(value)) return value.length > 0;\n return value.from != null || value.to != null;\n}\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction formatDay(value: string): string {\n // A plain date is a calendar day: format it in UTC so the day survives\n // every viewer timezone. A timestamp is a moment: format it locally.\n const dateOnly = DATE_ONLY.test(value);\n const date = new Date(dateOnly ? `${value}T00:00:00Z` : value);\n if (Number.isNaN(date.getTime())) return value;\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n ...(dateOnly ? { timeZone: \"UTC\" } : {}),\n }).format(date);\n}\n\n/** The words a set chip shows after its label. */\nexport function formatFilterValue(\n definition: FilterDefinition,\n value: FilterValue | undefined,\n): string {\n if (!isFilterSet(value) || value == null) return \"\";\n if (definition.type === \"date-range\") {\n const range = value as DateRangeValue;\n if (range.preset) return range.preset;\n if (range.from && range.to) {\n return `${formatDay(range.from)} to ${formatDay(range.to)}`;\n }\n if (range.from) return `From ${formatDay(range.from)}`;\n if (range.to) return `Until ${formatDay(range.to)}`;\n return \"\";\n }\n const labelOf = (item: string) =>\n definition.options.find((option) => option.value === item)?.label ?? item;\n if (Array.isArray(value)) return value.map(labelOf).join(\", \");\n return typeof value === \"string\" ? labelOf(value) : \"\";\n}\n\n/* --------------------------------- chips -------------------------------- */\n\nconst CHIP_TRIGGER =\n \"outline-pho-brand flex h-8 min-w-0 cursor-pointer items-center gap-1.5 rounded-full text-base transition-[color,background-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2 [&>svg]:size-4 [&>svg]:shrink-0\";\n\nfunction FilterChip({\n definition,\n value,\n onChange,\n}: {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n onChange: (next: FilterValue | undefined) => void;\n}) {\n const [open, setOpen] = useState(false);\n const focusRef = useRef<HTMLElement | null>(null);\n const set = isFilterSet(value);\n const display = formatFilterValue(definition, value);\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <span\n data-filter-chip={definition.key}\n data-set={set || undefined}\n className={cn(\n \"ring-pho-primary inline-flex max-w-full shrink-0 items-stretch rounded-full ring-1 ring-inset\",\n set ? \"bg-pho-secondary\" : \"bg-transparent\",\n )}\n >\n <Popover.Trigger\n aria-label={set ? undefined : `${definition.label} filter`}\n className={cn(\n CHIP_TRIGGER,\n \"hover:bg-pho-ghost-hover\",\n set ? \"pr-1.5 pl-3\" : \"pr-3 pl-2.5\",\n set ? \"rounded-r-none\" : \"\",\n )}\n >\n {set ? null : <IconPlus aria-hidden />}\n {set ? (\n <span className=\"flex min-w-0 items-baseline gap-1\">\n <span className=\"text-pho-description shrink-0\">\n {definition.label}:\n </span>\n <span className=\"text-pho-primary max-w-56 truncate font-medium\">\n {display}\n </span>\n </span>\n ) : (\n <span className=\"text-pho-secondary\">{definition.label}</span>\n )}\n </Popover.Trigger>\n {set ? (\n <button\n type=\"button\"\n aria-label={`Clear ${definition.label.toLowerCase()} filter`}\n onClick={() => onChange(undefined)}\n className={cn(\n CHIP_TRIGGER,\n \"text-pho-secondary hover:bg-pho-ghost-hover hover:text-pho-secondary-hover rounded-l-none pr-2.5 pl-1 [&>svg]:size-3.5\",\n )}\n >\n <IconX aria-hidden />\n </button>\n ) : null}\n </span>\n <Popover.Portal>\n <Popover.Positioner align=\"start\" sideOffset={6}>\n <Popover.Popup\n aria-label={`${definition.label} filter`}\n initialFocus={focusRef}\n className={cn(\n \"w-64 p-0\",\n definition.type === \"date-range\" && \"w-72\",\n )}\n >\n {definition.type === \"date-range\" ? (\n <DateRangePanel\n definition={definition}\n value={value as DateRangeValue | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (next?.preset) setOpen(false);\n }}\n />\n ) : (\n <OptionsPanel\n definition={definition}\n value={value as string | string[] | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (!definition.multiple) setOpen(false);\n }}\n />\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\nfunction OptionsPanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: SelectFilterDefinition;\n value: string | string[] | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: string | string[] | undefined) => void;\n}) {\n const [query, setQuery] = useState(\"\");\n const searchable =\n definition.searchable ?? definition.options.length > SEARCHABLE_PAST;\n const chosen = new Set(\n value == null ? [] : Array.isArray(value) ? value : [value],\n );\n const needle = query.trim().toLowerCase();\n const options = needle\n ? definition.options.filter(\n (option) =>\n option.label.toLowerCase().includes(needle) ||\n option.value.toLowerCase().includes(needle),\n )\n : definition.options;\n const pick = (option: FilterOption) => {\n if (definition.multiple) {\n const next = new Set(chosen);\n if (next.has(option.value)) next.delete(option.value);\n else next.add(option.value);\n // Keep the definition's order, so the chip reads the same way\n // whatever order the values were chosen in.\n const ordered = definition.options\n .map((item) => item.value)\n .filter((item) => next.has(item));\n onChange(ordered.length > 0 ? ordered : undefined);\n return;\n }\n onChange(chosen.has(option.value) ? undefined : option.value);\n };\n return (\n <Command.Root\n label={`${definition.label} options`}\n // Without a search field the list itself takes focus, so the arrow\n // keys work from the first frame.\n ref={(node: HTMLDivElement | null) => {\n if (!searchable) focusRef.current = node;\n }}\n className=\"rounded-base\"\n >\n {searchable ? (\n <Command.InputGroup>\n <IconSearch\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute left-3 size-4\"\n />\n <Command.Input\n ref={(node: HTMLInputElement | null) => {\n focusRef.current = node;\n }}\n value={query}\n onValueChange={setQuery}\n placeholder={definition.searchPlaceholder ?? \"Search\"}\n aria-label={`Search ${definition.label.toLowerCase()} options`}\n className=\"py-2 pr-3 pl-9 text-base\"\n />\n </Command.InputGroup>\n ) : null}\n <Command.List>\n <Command.Empty>Nothing matches.</Command.Empty>\n {options.map((option) => (\n <Command.Item\n key={option.value}\n value={option.value}\n title={option.label}\n aria-checked={chosen.has(option.value)}\n icon={chosen.has(option.value) ? <IconCheck aria-hidden /> : null}\n onSelect={() => pick(option)}\n />\n ))}\n </Command.List>\n </Command.Root>\n );\n}\n\nconst DATE_INPUT =\n \"bg-pho-primary ring-pho-primary text-pho-primary focus-visible:ring-pho-brand w-full min-w-0 rounded-sm px-2 py-1 text-base ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2\";\n\nfunction DateRangePanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: DateRangeFilterDefinition;\n value: DateRangeValue | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: DateRangeValue | undefined) => void;\n}) {\n const presets = definition.presets ?? FILTER_DATE_PRESETS;\n // A preset's `from` is a timestamp; the day field shows its date.\n const day = (side: string | null | undefined) =>\n side == null ? \"\" : DATE_ONLY.test(side) ? side : side.slice(0, 10);\n const setSide = (side: \"from\" | \"to\", next: string) => {\n // Editing either day leaves a preset behind: the pair is the value now,\n // and a preset's timestamp becomes the day it fell on.\n const range: DateRangeValue = {\n from: day(value?.from) || null,\n to: day(value?.to) || null,\n [side]: next || null,\n };\n onChange(range.from == null && range.to == null ? undefined : range);\n };\n return (\n <div className=\"flex flex-col\">\n <Command.Root\n label={`${definition.label} presets`}\n ref={(node: HTMLDivElement | null) => {\n focusRef.current = node;\n }}\n className=\"rounded-t-[inherit]\"\n >\n <Command.List>\n {presets.map((preset) => (\n <Command.Item\n key={preset.label}\n value={preset.label}\n title={preset.label}\n aria-checked={value?.preset === preset.label}\n icon={\n value?.preset === preset.label ? (\n <IconCheck aria-hidden />\n ) : null\n }\n onSelect={() =>\n onChange({\n from: new Date(\n Date.now() - preset.hours * 60 * 60 * 1000,\n ).toISOString(),\n to: null,\n preset: preset.label,\n })\n }\n />\n ))}\n </Command.List>\n </Command.Root>\n {/* The day fields stand outside the command list: its arrow-key\n handling would otherwise swallow the native date stepping. */}\n <div className=\"border-pho-secondary grid grid-cols-2 gap-2 border-t p-2\">\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n From\n <input\n type=\"date\"\n value={day(value?.from)}\n max={day(value?.to) || undefined}\n onChange={(event) => setSide(\"from\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n To\n <input\n type=\"date\"\n value={day(value?.to)}\n min={day(value?.from) || undefined}\n onChange={(event) => setSide(\"to\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n </div>\n </div>\n );\n}\n\n/* ---------------------------------- bar --------------------------------- */\n\nexport interface FilterBarProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** One chip per definition, in this order. */\n definitions: readonly FilterDefinition[];\n /** The values, keyed by definition key. Absent or empty means unset. */\n filters: FilterValues;\n /** The whole map, changed — set, cleared, or cleared all. */\n onFiltersChange: (next: FilterValues) => void;\n /** The search field's text. The field renders only with `onSearchChange`. */\n search?: string;\n onSearchChange?: (value: string) => void;\n /** A teaching phrase — \"Find an event by id\". @default \"Search\" */\n searchPlaceholder?: string;\n /** The field's accessible name when the placeholder is too short to be one. */\n searchLabel?: string;\n /**\n * Pin the bar to the top of the nearest scroll pane. It paints the\n * surface it sits on (`--pho-surface`) so rows scroll under it.\n */\n sticky?: boolean;\n /** Controls after the chips — a range picker, an export button. */\n children?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport function FilterBar({\n definitions,\n filters,\n onFiltersChange,\n search,\n onSearchChange,\n searchPlaceholder = \"Search\",\n searchLabel,\n sticky,\n className,\n children,\n ...props\n}: FilterBarProps) {\n const setCount = definitions.filter((definition) =>\n isFilterSet(filters[definition.key]),\n ).length;\n const change = (key: string, next: FilterValue | undefined) => {\n const rest = { ...filters };\n if (next === undefined) delete rest[key];\n else rest[key] = next;\n onFiltersChange(rest);\n };\n return (\n <div\n data-filter-bar=\"\"\n className={cn(\n \"flex min-w-0 flex-wrap items-center gap-2\",\n sticky &&\n \"sticky top-0 z-10 bg-[var(--pho-surface,var(--background-color-pho-page))] py-3\",\n className,\n )}\n {...props}\n >\n {onSearchChange != null ? (\n <InputGroup.Root size=\"sm\" className=\"w-64 max-w-full\">\n <InputGroup.Addon>\n <IconSearch />\n </InputGroup.Addon>\n <InputGroup.Input\n type=\"search\"\n value={search ?? \"\"}\n onChange={(event) => onSearchChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n onSearchChange(\"\");\n }}\n placeholder={searchPlaceholder}\n aria-label={searchLabel ?? searchPlaceholder}\n />\n </InputGroup.Root>\n ) : null}\n {definitions.map((definition) => (\n <FilterChip\n key={definition.key}\n definition={definition}\n value={filters[definition.key]}\n onChange={(next) => change(definition.key, next)}\n />\n ))}\n {setCount > 1 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n const rest = { ...filters };\n for (const definition of definitions) delete rest[definition.key];\n onFiltersChange(rest);\n }}\n >\n Clear filters\n </Button>\n ) : null}\n {children}\n </div>\n );\n}\n\nFilterBar.displayName = \"FilterBar\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { t as s } from "./cn-ChIgwEl3.js";
3
+ import { t as n } from "./IconSearch-BKAHkLyX.js";
4
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
5
+ function u({ value: t, onChange: i, className: r, ...e }) {
6
+ return /* @__PURE__ */ o("label", {
7
+ className: s("flex min-w-40 flex-1 items-center gap-2", r),
8
+ children: [/* @__PURE__ */ a(n, {
9
+ "aria-hidden": !0,
10
+ className: "text-pho-description size-4 shrink-0"
11
+ }), /* @__PURE__ */ a("input", {
12
+ type: "search",
13
+ value: t,
14
+ onChange: (l) => i(l.target.value),
15
+ className: "text-pho-primary placeholder:text-pho-description outline-pho-brand w-full min-w-0 rounded-sm bg-transparent text-sm focus-visible:outline-2 focus-visible:outline-offset-2",
16
+ ...e,
17
+ "aria-label": e["aria-label"] ?? (e["aria-labelledby"] ? void 0 : "Search")
18
+ })]
19
+ });
20
+ }
21
+ export {
22
+ u as t
23
+ };
24
+
25
+ //# sourceMappingURL=ghost-search-BvBFa9su.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ghost-search-BvBFa9su.js","names":[],"sources":["../../src/utils/ghost-search.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport { IconSearch } from \"@tabler/icons-react\";\nimport { cn } from \"./cn\";\n\nexport interface GhostSearchProps extends Omit<\n ComponentProps<\"input\">,\n \"value\" | \"onChange\" | \"type\" | \"children\"\n> {\n value: string;\n onChange: (value: string) => void;\n}\n\n/**\n * A search box with no box: the glyph and the text on the surface's own\n * line, the way a toolbar band inside a card carries it (a `DataTable`'s\n * search, a `Trace.Waterfall`'s). Quiet ink, no ring until focus.\n */\nexport function GhostSearch({\n value,\n onChange,\n className,\n ...props\n}: GhostSearchProps) {\n return (\n <label className={cn(\"flex min-w-40 flex-1 items-center gap-2\", className)}>\n <IconSearch\n aria-hidden\n className=\"text-pho-description size-4 shrink-0\"\n />\n <input\n type=\"search\"\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"text-pho-primary placeholder:text-pho-description outline-pho-brand w-full min-w-0 rounded-sm bg-transparent text-sm focus-visible:outline-2 focus-visible:outline-offset-2\"\n {...props}\n aria-label={\n props[\"aria-label\"] ??\n (props[\"aria-labelledby\"] ? undefined : \"Search\")\n }\n />\n </label>\n );\n}\n"],"mappings":";;;;AAiBA,SAAgB,EAAY,EAC1B,OAAA,GACA,UAAA,GACA,WAAA,GACA,GAAG,EAAA,GACgB;AACnB,SACE,gBAAA,EAAC,SAAD;AAAA,IAAO,WAAW,EAAG,2CAA2C,CAAS;AAAA,IAAzE,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,MACE,eAAA;AAAA,MACA,WAAU;AAAA,IACX,CAAA,GACD,gBAAA,EAAC,SAAD;AAAA,MACE,MAAK;AAAA,MACE,OAAA;AAAA,MACP,UAAA,CAAW,MAAU,EAAS,EAAM,OAAO,KAAK;AAAA,MAChD,WAAU;AAAA,MACV,GAAI;AAAA,MACJ,cACE,EAAM,YAAA,MACL,EAAM,iBAAA,IAAqB,SAAY;AAAA,IAE3C,CAAA,CACI;AAAA;AAEX"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { i as bt, t as kt } from "./legend-C0mU7dqd.js";
3
- import { _ as Mt, a as Tt, c as wt, d as Lt, f as St, g as Ct, h as it, i as Et, l as Pt, m as Nt, n as At, o as Ft, p as It, r as zt, s as ot, t as jt, u as Dt, v as Rt } from "./use-measure-CMVgLouO.js";
3
+ import { _ as Mt, a as Tt, c as wt, d as Lt, f as St, g as Ct, h as it, i as Et, l as Pt, m as Nt, n as At, o as Ft, p as It, r as zt, s as ot, t as jt, u as Dt, v as Rt } from "./use-measure-C-i54AC6.js";
4
4
  import { useMemo as j, useState as Xt } from "react";
5
5
  import { jsx as M, jsxs as st } from "react/jsx-runtime";
6
6
  function y(t) {
@@ -450,4 +450,4 @@ export {
450
450
  Qt as t
451
451
  };
452
452
 
453
- //# sourceMappingURL=line-chart-CUR3AxrR.js.map
453
+ //# sourceMappingURL=line-chart-VuMYKzW3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"line-chart-CUR3AxrR.js","names":["constant","curveLinear","x","pointX","y","pointY","array","constant","curveLinear","pointX","pointY","array","line"],"sources":["../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/constant.js","../../../../node_modules/.pnpm/d3-path@3.1.0/node_modules/d3-path/src/path.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/path.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/array.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/linear.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/point.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/line.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/area.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/monotone.js","../../src/components/line-chart/line-chart.tsx"],"sourcesContent":["export default function(x) {\n return function constant() {\n return x;\n };\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","export var slice = Array.prototype.slice;\n\nexport default function(x) {\n return typeof x === \"object\" && \"length\" in x\n ? x // Array, TypedArray, NodeList, array-like\n : Array.from(x); // Map, Set, iterable, string, or anything else\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x, y) {\n var defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(line);\n\n x = typeof x === \"function\" ? x : (x === undefined) ? pointX : constant(x);\n y = typeof y === \"function\" ? y : (y === undefined) ? pointY : constant(y);\n\n function line(data) {\n var i,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x(d, i, data), +y(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), line) : x;\n };\n\n line.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), line) : y;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport line from \"./line.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x0, y0, y1) {\n var x1 = null,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(area);\n\n x0 = typeof x0 === \"function\" ? x0 : (x0 === undefined) ? pointX : constant(+x0);\n y0 = typeof y0 === \"function\" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);\n y1 = typeof y1 === \"function\" ? y1 : (y1 === undefined) ? pointY : constant(+y1);\n\n function area(data) {\n var i,\n j,\n k,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","import { useMemo, useState, type PointerEvent } from \"react\";\nimport { area as shapeArea, curveLinear, curveMonotoneX, line } from \"d3-shape\";\nimport { XAxis, YAxis } from \"../chart/axes\";\nimport { chartColor } from \"../chart/color\";\nimport { describeChart, numberFormatter, readValue } from \"../chart/format\";\nimport { ChartLegend } from \"../chart/legend\";\nimport {\n bucketSpan,\n bucketTimeFormatter,\n linearScale,\n nearestIndex,\n niceLinearDomain,\n thinTicks,\n timeAxisTicks,\n timeTickFormatter,\n toTime,\n} from \"../chart/scale\";\nimport { ChartShell, chartLayout } from \"../chart/shell\";\nimport { ChartTooltip } from \"../chart/tooltip\";\nimport type { ChartBaseProps, ChartDatum } from \"../chart/types\";\nimport { useMeasuredWidth } from \"../chart/use-measure\";\n\n/**\n * LineChart — series over time as lines: latency percentiles, one line\n * per destination, a min / average / max where the bounds are dashed.\n *\n * Design notes:\n * - A 2px stroke with round joins, no markers at rest. Straight segments\n * by default: a curve invents values between samples, so `curve=\n * \"monotone\"` is a choice the page makes for a smooth-by-nature\n * quantity. `area` washes the surface under a lone series at 10%.\n * - Hover snaps a crosshair to the nearest bucket and rings each series'\n * point in the surface colour, so a dot stays legible where lines\n * cross; the tooltip lists every series at that time.\n * - Gridlines, axis text, legend and the figure's spoken summary are the\n * bar chart's — one system, one reading.\n */\n\nconst LINE_WIDTH = 2;\nconst POINT_RADIUS = 4;\n\nexport interface LineChartProps<\n T extends ChartDatum,\n> extends ChartBaseProps<T> {\n /** Straight segments, or a monotone curve that never overshoots a sample. @default \"linear\" */\n curve?: \"linear\" | \"monotone\";\n /** A soft fill under the first series (a lone one, as a rule). */\n area?: boolean;\n}\n\ntype Point = [number, number | null];\n\nexport function LineChart<T extends ChartDatum>({\n data,\n series,\n label,\n description,\n height = 200,\n width: fixedWidth,\n valueFormat,\n timeFormat,\n locale,\n legend,\n baseline = \"zero\",\n curve = \"linear\",\n area = false,\n breakdownTitle,\n loading,\n empty = \"Nothing here yet.\",\n className,\n ...props\n}: LineChartProps<T>) {\n const [containerRef, width] = useMeasuredWidth<HTMLDivElement>(fixedWidth);\n const [hovered, setHovered] = useState<number | null>(null);\n\n const model = useMemo(() => {\n const colors = series.map((s, index) => chartColor(s.color, index));\n const times = data.map((d) => toTime(d.x));\n const span = bucketSpan(times);\n const axisFormat = valueFormat ?? numberFormatter(locale, true);\n const fullFormat = valueFormat ?? numberFormatter(locale);\n const headingFormat = timeFormat ?? bucketTimeFormatter(locale, span);\n const values = series.map((s) => data.map((d) => readValue(d, s.key)));\n let min = Infinity;\n let max = -Infinity;\n for (const column of values) {\n for (const value of column) {\n if (value == null) continue;\n if (value < min) min = value;\n if (value > max) max = value;\n }\n }\n if (min === Infinity) {\n min = 0;\n max = 0;\n }\n if (baseline === \"zero\") {\n min = Math.min(0, min);\n max = Math.max(0, max);\n }\n const y = niceLinearDomain(min, max);\n return {\n colors,\n times,\n values,\n axisFormat,\n fullFormat,\n headingFormat,\n y,\n yLabels: y.ticks.map(axisFormat),\n described:\n description ??\n describeChart({\n data,\n series,\n kind: \"line\",\n valueFormat: fullFormat,\n timeFormat: headingFormat,\n }),\n };\n }, [data, series, baseline, valueFormat, timeFormat, locale, description]);\n\n const layout = chartLayout(width, height, model.yLabels);\n const n = data.length;\n const t0 = model.times[0] ?? 0;\n const t1 = model.times[n - 1] ?? 0;\n const { left, right, top, bottom } = layout;\n const xScale = useMemo(\n () => linearScale(t1 > t0 ? [t0, t1] : [t0 - 1, t0 + 1], [left, right]),\n [t0, t1, left, right],\n );\n const yScale = useMemo(\n () => linearScale(model.y.domain, [bottom, top]),\n [model.y.domain, bottom, top],\n );\n const xs = useMemo(\n () => model.times.map((t) => xScale(t)),\n [model.times, xScale],\n );\n\n const paths = useMemo(() => {\n const shape = line<Point>()\n .defined((p) => p[1] != null)\n .x((p) => p[0])\n .y((p) => yScale(p[1]!))\n .curve(curve === \"monotone\" ? curveMonotoneX : curveLinear);\n const floor = Math.max(model.y.domain[0], Math.min(0, model.y.domain[1]));\n const fill = shapeArea<Point>()\n .defined((p) => p[1] != null)\n .x((p) => p[0])\n .y0(yScale(floor))\n .y1((p) => yScale(p[1]!))\n .curve(curve === \"monotone\" ? curveMonotoneX : curveLinear);\n return model.values.map((column, index) => {\n const points: Point[] = column.map((value, i) => [xs[i]!, value]);\n return {\n stroke: shape(points) ?? \"\",\n area: area && index === 0 ? (fill(points) ?? \"\") : null,\n };\n });\n }, [model.values, model.y.domain, xs, yScale, curve, area]);\n\n const xTicks = useMemo(() => {\n const innerWidth = right - left;\n if (n === 0 || innerWidth <= 0) return [];\n const format = timeTickFormatter(locale);\n const ticks = timeAxisTicks(t0, t1, innerWidth);\n return thinTicks(ticks, format, innerWidth).map((tick) => ({\n x: xScale(tick.getTime()),\n label: format(tick),\n }));\n }, [n, t0, t1, left, right, xScale, locale]);\n\n const onPointerMove = (event: PointerEvent<SVGSVGElement>) => {\n if (n === 0) return;\n const rect = event.currentTarget.getBoundingClientRect();\n const scale = rect.width > 0 ? width / rect.width : 1;\n const px = (event.clientX - rect.left) * scale;\n setHovered(nearestIndex(xs, px));\n };\n\n const hoveredDatum = hovered != null ? data[hovered] : undefined;\n const showLegend = legend ?? series.length > 1;\n\n return (\n <ChartShell\n label={label}\n description={model.described}\n height={height}\n width={width}\n containerRef={containerRef}\n loading={loading}\n empty={empty}\n showEmpty={n === 0 && !loading}\n onPlotPointerMove={onPointerMove}\n onPlotPointerLeave={() => setHovered(null)}\n className={className}\n legend={\n showLegend ? (\n <ChartLegend\n items={series.map((s, index) => ({\n label: s.label,\n color: model.colors[index]!,\n kind: \"line\",\n dashed: s.dashed,\n }))}\n />\n ) : null\n }\n tooltip={\n hovered != null && hoveredDatum != null ? (\n <ChartTooltip\n x={xs[hovered]!}\n width={width}\n top={layout.top}\n heading={model.headingFormat(new Date(hoveredDatum.x))}\n rows={series.map((s, index) => {\n const value = model.values[index]![hovered];\n return {\n label: s.label,\n value: value == null ? \"No data\" : model.fullFormat(value),\n color: model.colors[index]!,\n kind: \"line\",\n dashed: s.dashed,\n };\n })}\n breakdown={hoveredDatum.breakdown}\n breakdownTitle={breakdownTitle}\n valueFormat={model.fullFormat}\n />\n ) : null\n }\n {...props}\n >\n <YAxis\n layout={layout}\n ticks={model.y.ticks}\n labels={model.yLabels}\n scale={yScale}\n />\n <XAxis layout={layout} ticks={xTicks} />\n {hovered != null && hoveredDatum != null && (\n <line\n x1={xs[hovered]}\n x2={xs[hovered]}\n y1={layout.top}\n y2={layout.bottom}\n stroke=\"var(--color-pho-chart-crosshair)\"\n />\n )}\n <g data-lines=\"\">\n {paths.map((path, index) => (\n <g key={series[index]!.key} data-series={series[index]!.key}>\n {path.area != null && path.area !== \"\" && (\n <path\n d={path.area}\n fill={model.colors[index]}\n fillOpacity={0.1}\n />\n )}\n <path\n d={path.stroke}\n fill=\"none\"\n stroke={model.colors[index]}\n strokeWidth={LINE_WIDTH}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={series[index]!.dashed ? \"4 4\" : undefined}\n />\n </g>\n ))}\n </g>\n {hovered != null && hoveredDatum != null && (\n <g data-points=\"\">\n {model.values.map((column, index) => {\n const value = column[hovered];\n if (value == null) return null;\n return (\n <circle\n key={series[index]!.key}\n cx={xs[hovered]}\n cy={yScale(value)}\n r={POINT_RADIUS}\n fill={model.colors[index]}\n // The surface ring keeps a dot legible where lines cross.\n stroke=\"var(--pho-surface, var(--background-color-pho-primary))\"\n strokeWidth={2}\n />\n );\n })}\n </g>\n )}\n </ChartShell>\n );\n}\n\nLineChart.displayName = \"LineChart\";\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8],"mappings":"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"}
1
+ {"version":3,"file":"line-chart-VuMYKzW3.js","names":["constant","curveLinear","x","pointX","y","pointY","array","constant","curveLinear","pointX","pointY","array","line"],"sources":["../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/constant.js","../../../../node_modules/.pnpm/d3-path@3.1.0/node_modules/d3-path/src/path.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/path.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/array.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/linear.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/point.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/line.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/area.js","../../../../node_modules/.pnpm/d3-shape@3.2.0/node_modules/d3-shape/src/curve/monotone.js","../../src/components/line-chart/line-chart.tsx"],"sourcesContent":["export default function(x) {\n return function constant() {\n return x;\n };\n}\n","const pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction append(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += arguments[i] + strings[i];\n }\n}\n\nfunction appendRound(digits) {\n let d = Math.floor(digits);\n if (!(d >= 0)) throw new Error(`invalid digits: ${digits}`);\n if (d > 15) return append;\n const k = 10 ** d;\n return function(strings) {\n this._ += strings[0];\n for (let i = 1, n = strings.length; i < n; ++i) {\n this._ += Math.round(arguments[i] * k) / k + strings[i];\n }\n };\n}\n\nexport class Path {\n constructor(digits) {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n this._append = digits == null ? append : appendRound(digits);\n }\n moveTo(x, y) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}`;\n }\n closePath() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._append`Z`;\n }\n }\n lineTo(x, y) {\n this._append`L${this._x1 = +x},${this._y1 = +y}`;\n }\n quadraticCurveTo(x1, y1, x, y) {\n this._append`Q${+x1},${+y1},${this._x1 = +x},${this._y1 = +y}`;\n }\n bezierCurveTo(x1, y1, x2, y2, x, y) {\n this._append`C${+x1},${+y1},${+x2},${+y2},${this._x1 = +x},${this._y1 = +y}`;\n }\n arcTo(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._append`M${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._append`L${this._x1 = x1},${this._y1 = y1}`;\n }\n\n // Otherwise, draw an arc!\n else {\n let x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._append`L${x1 + t01 * x01},${y1 + t01 * y01}`;\n }\n\n this._append`A${r},${r},0,0,${+(y01 * x20 > x01 * y20)},${this._x1 = x1 + t21 * x21},${this._y1 = y1 + t21 * y21}`;\n }\n }\n arc(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(`negative radius: ${r}`);\n\n let dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._append`M${x0},${y0}`;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._append`L${x0},${y0}`;\n }\n\n // Is this arc empty? We’re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._append`A${r},${r},0,1,${cw},${x - dx},${y - dy}A${r},${r},0,1,${cw},${this._x1 = x0},${this._y1 = y0}`;\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._append`A${r},${r},0,${+(da >= pi)},${cw},${this._x1 = x + r * Math.cos(a1)},${this._y1 = y + r * Math.sin(a1)}`;\n }\n }\n rect(x, y, w, h) {\n this._append`M${this._x0 = this._x1 = +x},${this._y0 = this._y1 = +y}h${w = +w}v${+h}h${-w}Z`;\n }\n toString() {\n return this._;\n }\n}\n\nexport function path() {\n return new Path;\n}\n\n// Allow instanceof d3.path\npath.prototype = Path.prototype;\n\nexport function pathRound(digits = 3) {\n return new Path(+digits);\n}\n","import {Path} from \"d3-path\";\n\nexport function withPath(shape) {\n let digits = 3;\n\n shape.digits = function(_) {\n if (!arguments.length) return digits;\n if (_ == null) {\n digits = null;\n } else {\n const d = Math.floor(_);\n if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);\n digits = d;\n }\n return shape;\n };\n\n return () => new Path(digits);\n}\n","export var slice = Array.prototype.slice;\n\nexport default function(x) {\n return typeof x === \"object\" && \"length\" in x\n ? x // Array, TypedArray, NodeList, array-like\n : Array.from(x); // Map, Set, iterable, string, or anything else\n}\n","function Linear(context) {\n this._context = context;\n}\n\nLinear.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n x = +x, y = +y;\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; // falls through\n default: this._context.lineTo(x, y); break;\n }\n }\n};\n\nexport default function(context) {\n return new Linear(context);\n}\n","export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x, y) {\n var defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(line);\n\n x = typeof x === \"function\" ? x : (x === undefined) ? pointX : constant(x);\n y = typeof y === \"function\" ? y : (y === undefined) ? pointY : constant(y);\n\n function line(data) {\n var i,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer;\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) output.lineStart();\n else output.lineEnd();\n }\n if (defined0) output.point(+x(d, i, data), +y(d, i, data));\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n line.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), line) : x;\n };\n\n line.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), line) : y;\n };\n\n line.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), line) : defined;\n };\n\n line.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;\n };\n\n line.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;\n };\n\n return line;\n}\n","import array from \"./array.js\";\nimport constant from \"./constant.js\";\nimport curveLinear from \"./curve/linear.js\";\nimport line from \"./line.js\";\nimport {withPath} from \"./path.js\";\nimport {x as pointX, y as pointY} from \"./point.js\";\n\nexport default function(x0, y0, y1) {\n var x1 = null,\n defined = constant(true),\n context = null,\n curve = curveLinear,\n output = null,\n path = withPath(area);\n\n x0 = typeof x0 === \"function\" ? x0 : (x0 === undefined) ? pointX : constant(+x0);\n y0 = typeof y0 === \"function\" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);\n y1 = typeof y1 === \"function\" ? y1 : (y1 === undefined) ? pointY : constant(+y1);\n\n function area(data) {\n var i,\n j,\n k,\n n = (data = array(data)).length,\n d,\n defined0 = false,\n buffer,\n x0z = new Array(n),\n y0z = new Array(n);\n\n if (context == null) output = curve(buffer = path());\n\n for (i = 0; i <= n; ++i) {\n if (!(i < n && defined(d = data[i], i, data)) === defined0) {\n if (defined0 = !defined0) {\n j = i;\n output.areaStart();\n output.lineStart();\n } else {\n output.lineEnd();\n output.lineStart();\n for (k = i - 1; k >= j; --k) {\n output.point(x0z[k], y0z[k]);\n }\n output.lineEnd();\n output.areaEnd();\n }\n }\n if (defined0) {\n x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);\n output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);\n }\n }\n\n if (buffer) return output = null, buffer + \"\" || null;\n }\n\n function arealine() {\n return line().defined(defined).curve(curve).context(context);\n }\n\n area.x = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), x1 = null, area) : x0;\n };\n\n area.x0 = function(_) {\n return arguments.length ? (x0 = typeof _ === \"function\" ? _ : constant(+_), area) : x0;\n };\n\n area.x1 = function(_) {\n return arguments.length ? (x1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : x1;\n };\n\n area.y = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), y1 = null, area) : y0;\n };\n\n area.y0 = function(_) {\n return arguments.length ? (y0 = typeof _ === \"function\" ? _ : constant(+_), area) : y0;\n };\n\n area.y1 = function(_) {\n return arguments.length ? (y1 = _ == null ? null : typeof _ === \"function\" ? _ : constant(+_), area) : y1;\n };\n\n area.lineX0 =\n area.lineY0 = function() {\n return arealine().x(x0).y(y0);\n };\n\n area.lineY1 = function() {\n return arealine().x(x0).y(y1);\n };\n\n area.lineX1 = function() {\n return arealine().x(x1).y(y0);\n };\n\n area.defined = function(_) {\n return arguments.length ? (defined = typeof _ === \"function\" ? _ : constant(!!_), area) : defined;\n };\n\n area.curve = function(_) {\n return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;\n };\n\n area.context = function(_) {\n return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;\n };\n\n return area;\n}\n","function sign(x) {\n return x < 0 ? -1 : 1;\n}\n\n// Calculate the slopes of the tangents (Hermite-type interpolation) based on\n// the following paper: Steffen, M. 1990. A Simple Method for Monotonic\n// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.\n// NOV(II), P. 443, 1990.\nfunction slope3(that, x2, y2) {\n var h0 = that._x1 - that._x0,\n h1 = x2 - that._x1,\n s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),\n s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),\n p = (s0 * h1 + s1 * h0) / (h0 + h1);\n return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;\n}\n\n// Calculate a one-sided slope.\nfunction slope2(that, t) {\n var h = that._x1 - that._x0;\n return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;\n}\n\n// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations\n// \"you can express cubic Hermite interpolation in terms of cubic Bézier curves\n// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1\".\nfunction point(that, t0, t1) {\n var x0 = that._x0,\n y0 = that._y0,\n x1 = that._x1,\n y1 = that._y1,\n dx = (x1 - x0) / 3;\n that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);\n}\n\nfunction MonotoneX(context) {\n this._context = context;\n}\n\nMonotoneX.prototype = {\n areaStart: function() {\n this._line = 0;\n },\n areaEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._x0 = this._x1 =\n this._y0 = this._y1 =\n this._t0 = NaN;\n this._point = 0;\n },\n lineEnd: function() {\n switch (this._point) {\n case 2: this._context.lineTo(this._x1, this._y1); break;\n case 3: point(this, this._t0, slope2(this, this._t0)); break;\n }\n if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();\n this._line = 1 - this._line;\n },\n point: function(x, y) {\n var t1 = NaN;\n\n x = +x, y = +y;\n if (x === this._x1 && y === this._y1) return; // Ignore coincident points.\n switch (this._point) {\n case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;\n case 1: this._point = 2; break;\n case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;\n default: point(this, this._t0, t1 = slope3(this, x, y)); break;\n }\n\n this._x0 = this._x1, this._x1 = x;\n this._y0 = this._y1, this._y1 = y;\n this._t0 = t1;\n }\n}\n\nfunction MonotoneY(context) {\n this._context = new ReflectContext(context);\n}\n\n(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {\n MonotoneX.prototype.point.call(this, y, x);\n};\n\nfunction ReflectContext(context) {\n this._context = context;\n}\n\nReflectContext.prototype = {\n moveTo: function(x, y) { this._context.moveTo(y, x); },\n closePath: function() { this._context.closePath(); },\n lineTo: function(x, y) { this._context.lineTo(y, x); },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }\n};\n\nexport function monotoneX(context) {\n return new MonotoneX(context);\n}\n\nexport function monotoneY(context) {\n return new MonotoneY(context);\n}\n","import { useMemo, useState, type PointerEvent } from \"react\";\nimport { area as shapeArea, curveLinear, curveMonotoneX, line } from \"d3-shape\";\nimport { XAxis, YAxis } from \"../chart/axes\";\nimport { chartColor } from \"../chart/color\";\nimport { describeChart, numberFormatter, readValue } from \"../chart/format\";\nimport { ChartLegend } from \"../chart/legend\";\nimport {\n bucketSpan,\n bucketTimeFormatter,\n linearScale,\n nearestIndex,\n niceLinearDomain,\n thinTicks,\n timeAxisTicks,\n timeTickFormatter,\n toTime,\n} from \"../chart/scale\";\nimport { ChartShell, chartLayout } from \"../chart/shell\";\nimport { ChartTooltip } from \"../chart/tooltip\";\nimport type { ChartBaseProps, ChartDatum } from \"../chart/types\";\nimport { useMeasuredWidth } from \"../chart/use-measure\";\n\n/**\n * LineChart — series over time as lines: latency percentiles, one line\n * per destination, a min / average / max where the bounds are dashed.\n *\n * Design notes:\n * - A 2px stroke with round joins, no markers at rest. Straight segments\n * by default: a curve invents values between samples, so `curve=\n * \"monotone\"` is a choice the page makes for a smooth-by-nature\n * quantity. `area` washes the surface under a lone series at 10%.\n * - Hover snaps a crosshair to the nearest bucket and rings each series'\n * point in the surface colour, so a dot stays legible where lines\n * cross; the tooltip lists every series at that time.\n * - Gridlines, axis text, legend and the figure's spoken summary are the\n * bar chart's — one system, one reading.\n */\n\nconst LINE_WIDTH = 2;\nconst POINT_RADIUS = 4;\n\nexport interface LineChartProps<\n T extends ChartDatum,\n> extends ChartBaseProps<T> {\n /** Straight segments, or a monotone curve that never overshoots a sample. @default \"linear\" */\n curve?: \"linear\" | \"monotone\";\n /** A soft fill under the first series (a lone one, as a rule). */\n area?: boolean;\n}\n\ntype Point = [number, number | null];\n\nexport function LineChart<T extends ChartDatum>({\n data,\n series,\n label,\n description,\n height = 200,\n width: fixedWidth,\n valueFormat,\n timeFormat,\n locale,\n legend,\n baseline = \"zero\",\n curve = \"linear\",\n area = false,\n breakdownTitle,\n loading,\n empty = \"Nothing here yet.\",\n className,\n ...props\n}: LineChartProps<T>) {\n const [containerRef, width] = useMeasuredWidth<HTMLDivElement>(fixedWidth);\n const [hovered, setHovered] = useState<number | null>(null);\n\n const model = useMemo(() => {\n const colors = series.map((s, index) => chartColor(s.color, index));\n const times = data.map((d) => toTime(d.x));\n const span = bucketSpan(times);\n const axisFormat = valueFormat ?? numberFormatter(locale, true);\n const fullFormat = valueFormat ?? numberFormatter(locale);\n const headingFormat = timeFormat ?? bucketTimeFormatter(locale, span);\n const values = series.map((s) => data.map((d) => readValue(d, s.key)));\n let min = Infinity;\n let max = -Infinity;\n for (const column of values) {\n for (const value of column) {\n if (value == null) continue;\n if (value < min) min = value;\n if (value > max) max = value;\n }\n }\n if (min === Infinity) {\n min = 0;\n max = 0;\n }\n if (baseline === \"zero\") {\n min = Math.min(0, min);\n max = Math.max(0, max);\n }\n const y = niceLinearDomain(min, max);\n return {\n colors,\n times,\n values,\n axisFormat,\n fullFormat,\n headingFormat,\n y,\n yLabels: y.ticks.map(axisFormat),\n described:\n description ??\n describeChart({\n data,\n series,\n kind: \"line\",\n valueFormat: fullFormat,\n timeFormat: headingFormat,\n }),\n };\n }, [data, series, baseline, valueFormat, timeFormat, locale, description]);\n\n const layout = chartLayout(width, height, model.yLabels);\n const n = data.length;\n const t0 = model.times[0] ?? 0;\n const t1 = model.times[n - 1] ?? 0;\n const { left, right, top, bottom } = layout;\n const xScale = useMemo(\n () => linearScale(t1 > t0 ? [t0, t1] : [t0 - 1, t0 + 1], [left, right]),\n [t0, t1, left, right],\n );\n const yScale = useMemo(\n () => linearScale(model.y.domain, [bottom, top]),\n [model.y.domain, bottom, top],\n );\n const xs = useMemo(\n () => model.times.map((t) => xScale(t)),\n [model.times, xScale],\n );\n\n const paths = useMemo(() => {\n const shape = line<Point>()\n .defined((p) => p[1] != null)\n .x((p) => p[0])\n .y((p) => yScale(p[1]!))\n .curve(curve === \"monotone\" ? curveMonotoneX : curveLinear);\n const floor = Math.max(model.y.domain[0], Math.min(0, model.y.domain[1]));\n const fill = shapeArea<Point>()\n .defined((p) => p[1] != null)\n .x((p) => p[0])\n .y0(yScale(floor))\n .y1((p) => yScale(p[1]!))\n .curve(curve === \"monotone\" ? curveMonotoneX : curveLinear);\n return model.values.map((column, index) => {\n const points: Point[] = column.map((value, i) => [xs[i]!, value]);\n return {\n stroke: shape(points) ?? \"\",\n area: area && index === 0 ? (fill(points) ?? \"\") : null,\n };\n });\n }, [model.values, model.y.domain, xs, yScale, curve, area]);\n\n const xTicks = useMemo(() => {\n const innerWidth = right - left;\n if (n === 0 || innerWidth <= 0) return [];\n const format = timeTickFormatter(locale);\n const ticks = timeAxisTicks(t0, t1, innerWidth);\n return thinTicks(ticks, format, innerWidth).map((tick) => ({\n x: xScale(tick.getTime()),\n label: format(tick),\n }));\n }, [n, t0, t1, left, right, xScale, locale]);\n\n const onPointerMove = (event: PointerEvent<SVGSVGElement>) => {\n if (n === 0) return;\n const rect = event.currentTarget.getBoundingClientRect();\n const scale = rect.width > 0 ? width / rect.width : 1;\n const px = (event.clientX - rect.left) * scale;\n setHovered(nearestIndex(xs, px));\n };\n\n const hoveredDatum = hovered != null ? data[hovered] : undefined;\n const showLegend = legend ?? series.length > 1;\n\n return (\n <ChartShell\n label={label}\n description={model.described}\n height={height}\n width={width}\n containerRef={containerRef}\n loading={loading}\n empty={empty}\n showEmpty={n === 0 && !loading}\n onPlotPointerMove={onPointerMove}\n onPlotPointerLeave={() => setHovered(null)}\n className={className}\n legend={\n showLegend ? (\n <ChartLegend\n items={series.map((s, index) => ({\n label: s.label,\n color: model.colors[index]!,\n kind: \"line\",\n dashed: s.dashed,\n }))}\n />\n ) : null\n }\n tooltip={\n hovered != null && hoveredDatum != null ? (\n <ChartTooltip\n x={xs[hovered]!}\n width={width}\n top={layout.top}\n heading={model.headingFormat(new Date(hoveredDatum.x))}\n rows={series.map((s, index) => {\n const value = model.values[index]![hovered];\n return {\n label: s.label,\n value: value == null ? \"No data\" : model.fullFormat(value),\n color: model.colors[index]!,\n kind: \"line\",\n dashed: s.dashed,\n };\n })}\n breakdown={hoveredDatum.breakdown}\n breakdownTitle={breakdownTitle}\n valueFormat={model.fullFormat}\n />\n ) : null\n }\n {...props}\n >\n <YAxis\n layout={layout}\n ticks={model.y.ticks}\n labels={model.yLabels}\n scale={yScale}\n />\n <XAxis layout={layout} ticks={xTicks} />\n {hovered != null && hoveredDatum != null && (\n <line\n x1={xs[hovered]}\n x2={xs[hovered]}\n y1={layout.top}\n y2={layout.bottom}\n stroke=\"var(--color-pho-chart-crosshair)\"\n />\n )}\n <g data-lines=\"\">\n {paths.map((path, index) => (\n <g key={series[index]!.key} data-series={series[index]!.key}>\n {path.area != null && path.area !== \"\" && (\n <path\n d={path.area}\n fill={model.colors[index]}\n fillOpacity={0.1}\n />\n )}\n <path\n d={path.stroke}\n fill=\"none\"\n stroke={model.colors[index]}\n strokeWidth={LINE_WIDTH}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={series[index]!.dashed ? \"4 4\" : undefined}\n />\n </g>\n ))}\n </g>\n {hovered != null && hoveredDatum != null && (\n <g data-points=\"\">\n {model.values.map((column, index) => {\n const value = column[hovered];\n if (value == null) return null;\n return (\n <circle\n key={series[index]!.key}\n cx={xs[hovered]}\n cy={yScale(value)}\n r={POINT_RADIUS}\n fill={model.colors[index]}\n // The surface ring keeps a dot legible where lines cross.\n stroke=\"var(--pho-surface, var(--background-color-pho-primary))\"\n strokeWidth={2}\n />\n );\n })}\n </g>\n )}\n </ChartShell>\n );\n}\n\nLineChart.displayName = \"LineChart\";\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8],"mappings":"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"}
@@ -6,8 +6,8 @@ import { n as O } from "./spinner-BzLUo4Xk.js";
6
6
  import { a as A } from "./button-CdqS_t5a.js";
7
7
  import { i as D } from "./status-view-C8tabjDu.js";
8
8
  import { t as g } from "./skeleton-DwjSl4vC.js";
9
- import { r as E } from "./badge-DlLJPLeZ.js";
10
9
  import { t as h } from "./tooltip-BTF7GChl.js";
10
+ import { r as E } from "./badge-DlLJPLeZ.js";
11
11
  import { useEffect as T, useId as B, useRef as N } from "react";
12
12
  import { Fragment as W, jsx as t, jsxs as v } from "react/jsx-runtime";
13
13
  import { useRender as z } from "@base-ui/react/use-render";
@@ -241,4 +241,4 @@ export {
241
241
  pe as t
242
242
  };
243
243
 
244
- //# sourceMappingURL=log-list-0AXnjFrk.js.map
244
+ //# sourceMappingURL=log-list-BERiO4UJ.js.map