@datum-cloud/datum-ui 2.9.0 → 2.10.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.
@@ -1,9 +1,11 @@
1
1
  import { t as cn } from "../utils-Bu32wN-x.mjs";
2
+ import { t as Button } from "../button-DoMqfQLu.mjs";
2
3
  import { t as Icon } from "../icon-wrapper-DKfJlJd0.mjs";
4
+ import { t as Dialog } from "../dialog-Gu70fban.mjs";
3
5
  import { a as DropdownMenuRadioGroup, c as DropdownMenuTrigger, i as DropdownMenuLabel, o as DropdownMenuRadioItem, r as DropdownMenuContent, s as DropdownMenuSeparator, t as DropdownMenu } from "../dropdown-menu-b8zY5Cs6.mjs";
4
6
  import { t as Tooltip } from "../tooltip-DhbN1BDK.mjs";
5
7
  import { n as EASE, t as DURATION } from "../motion-DvGRWdsm.mjs";
6
- import { ArrowDown, ArrowRight, ArrowUp, Brain, Check, ChevronDown, Copy, Download, MessagesSquare, Mic, MicOff, PanelLeft, Plus, RotateCw, Square, Trash2 } from "lucide-react";
8
+ import { Archive, ArchiveRestore, ArrowDown, ArrowRight, ArrowUp, Brain, Check, ChevronDown, Copy, Download, MessagesSquare, Mic, MicOff, PanelLeft, Plus, RotateCw, Square, Trash2 } from "lucide-react";
7
9
  import { Fragment, createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
8
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
11
  import { AnimatePresence, motion } from "motion/react";
@@ -842,12 +844,32 @@ function downloadChat(chat) {
842
844
  a.click();
843
845
  URL.revokeObjectURL(url);
844
846
  }
845
- function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, header }) {
847
+ const ROW_ACTION_CLASS = "text-muted-foreground/40 shrink-0 rounded p-0.5 opacity-0 transition-colors group-hover:opacity-100";
848
+ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, onArchiveChat, onUnarchiveChat, confirmDelete = false, header }) {
849
+ const archiveEnabled = Boolean(onArchiveChat);
846
850
  const [query, setQuery] = useState("");
851
+ const [showArchived, setShowArchived] = useState(false);
852
+ const [pendingDelete, setPendingDelete] = useState(null);
853
+ const inArchivedView = archiveEnabled && showArchived;
847
854
  const filtered = useMemo(() => {
855
+ const inView = archiveEnabled ? chatList.filter((c) => Boolean(c.archived) === showArchived) : chatList;
848
856
  const q = query.trim().toLowerCase();
849
- return q ? chatList.filter((c) => c.title.toLowerCase().includes(q)) : chatList;
850
- }, [chatList, query]);
857
+ return q ? inView.filter((c) => c.title.toLowerCase().includes(q)) : inView;
858
+ }, [
859
+ archiveEnabled,
860
+ chatList,
861
+ query,
862
+ showArchived
863
+ ]);
864
+ const emptyText = inArchivedView ? query ? "No matching archived chats" : "No archived chats" : query ? "No matching chats" : "No saved chats";
865
+ const handleDelete = (e, chat) => {
866
+ if (!confirmDelete) {
867
+ onDeleteChat(e, chat.id);
868
+ return;
869
+ }
870
+ e.stopPropagation();
871
+ setPendingDelete(chat);
872
+ };
851
873
  return /* @__PURE__ */ jsxs("div", {
852
874
  className: "bg-background flex h-full w-64 shrink-0 flex-col border-r",
853
875
  children: [
@@ -855,36 +877,90 @@ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, heade
855
877
  className: "shrink-0 border-b px-3 py-2",
856
878
  children: header
857
879
  }),
858
- /* @__PURE__ */ jsx("div", {
859
- className: "flex h-12 items-center border-b px-2",
860
- children: /* @__PURE__ */ jsx("input", {
880
+ /* @__PURE__ */ jsxs("div", {
881
+ className: "flex h-12 items-center gap-1 border-b px-2",
882
+ children: [/* @__PURE__ */ jsx("input", {
861
883
  value: query,
862
884
  onChange: (e) => setQuery(e.target.value),
863
- placeholder: "Search chats…",
885
+ placeholder: inArchivedView ? "Search archived chats…" : "Search chats…",
864
886
  className: "bg-muted text-foreground placeholder:text-muted-foreground/70 focus:ring-primary/40 w-full rounded-md px-2.5 py-1.5 text-xs focus:ring-1 focus:outline-none"
865
- })
887
+ }), archiveEnabled && /* @__PURE__ */ jsx(Tooltip, {
888
+ message: showArchived ? "Show active chats" : "Show archived chats",
889
+ side: "bottom",
890
+ children: /* @__PURE__ */ jsx("button", {
891
+ type: "button",
892
+ "aria-label": "Archived",
893
+ "aria-pressed": showArchived,
894
+ onClick: () => setShowArchived((v) => !v),
895
+ className: cn("shrink-0 rounded-md p-1.5 transition-colors", showArchived ? "bg-accent text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-accent"),
896
+ children: /* @__PURE__ */ jsx(Icon, {
897
+ icon: Archive,
898
+ className: "size-3.5"
899
+ })
900
+ })
901
+ })]
866
902
  }),
867
903
  /* @__PURE__ */ jsx("div", {
868
904
  className: "flex flex-1 flex-col gap-0.5 overflow-y-auto p-2",
869
905
  children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", {
870
906
  className: "text-muted-foreground/60 px-2 py-1 text-xs",
871
- children: query ? "No matching chats" : "No saved chats"
907
+ children: emptyText
872
908
  }) : filtered.map((chat) => /* @__PURE__ */ jsxs("button", {
873
909
  type: "button",
874
910
  onClick: () => onLoadChat(chat),
875
911
  className: cn("group w-full rounded-lg px-2 py-1.5 text-left transition-colors", chat.id === currentChatId ? "bg-accent text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-accent/50"),
876
912
  children: [/* @__PURE__ */ jsxs("span", {
877
913
  className: "flex items-center gap-1",
878
- children: [/* @__PURE__ */ jsx("span", {
879
- className: "min-w-0 flex-1 truncate text-xs font-medium",
880
- children: chat.title
881
- }), /* @__PURE__ */ jsx("span", {
882
- role: "button",
883
- onClick: (e) => onDeleteChat(e, chat.id),
884
- "aria-label": "Delete chat",
885
- className: "text-muted-foreground/40 hover:text-destructive shrink-0 rounded p-0.5 opacity-0 transition-colors group-hover:opacity-100",
886
- children: /* @__PURE__ */ jsx(Trash2, { className: "size-3" })
887
- })]
914
+ children: [
915
+ /* @__PURE__ */ jsx("span", {
916
+ className: "min-w-0 flex-1 truncate text-xs font-medium",
917
+ children: chat.title
918
+ }),
919
+ archiveEnabled && !inArchivedView && /* @__PURE__ */ jsx(Tooltip, {
920
+ message: "Archive chat",
921
+ side: "top",
922
+ children: /* @__PURE__ */ jsx("span", {
923
+ role: "button",
924
+ onClick: (e) => {
925
+ e.stopPropagation();
926
+ onArchiveChat?.(e, chat.id);
927
+ },
928
+ "aria-label": "Archive chat",
929
+ className: cn(ROW_ACTION_CLASS, "hover:text-foreground"),
930
+ children: /* @__PURE__ */ jsx(Icon, {
931
+ icon: Archive,
932
+ className: "size-3"
933
+ })
934
+ })
935
+ }),
936
+ inArchivedView && onUnarchiveChat && /* @__PURE__ */ jsx(Tooltip, {
937
+ message: "Unarchive chat",
938
+ side: "top",
939
+ children: /* @__PURE__ */ jsx("span", {
940
+ role: "button",
941
+ onClick: (e) => {
942
+ e.stopPropagation();
943
+ onUnarchiveChat(e, chat.id);
944
+ },
945
+ "aria-label": "Unarchive chat",
946
+ className: cn(ROW_ACTION_CLASS, "hover:text-foreground"),
947
+ children: /* @__PURE__ */ jsx(Icon, {
948
+ icon: ArchiveRestore,
949
+ className: "size-3"
950
+ })
951
+ })
952
+ }),
953
+ /* @__PURE__ */ jsx("span", {
954
+ role: "button",
955
+ onClick: (e) => handleDelete(e, chat),
956
+ "aria-label": "Delete chat",
957
+ className: cn(ROW_ACTION_CLASS, "hover:text-destructive"),
958
+ children: /* @__PURE__ */ jsx(Icon, {
959
+ icon: Trash2,
960
+ className: "size-3"
961
+ })
962
+ })
963
+ ]
888
964
  }), /* @__PURE__ */ jsxs("span", {
889
965
  className: "flex items-center gap-1",
890
966
  children: [/* @__PURE__ */ jsx("span", {
@@ -900,8 +976,11 @@ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, heade
900
976
  downloadChat(chat);
901
977
  },
902
978
  "aria-label": "Download chat as Markdown",
903
- className: "text-muted-foreground/40 hover:text-foreground shrink-0 rounded p-0.5 opacity-0 transition-colors group-hover:opacity-100",
904
- children: /* @__PURE__ */ jsx(Download, { className: "size-3" })
979
+ className: cn(ROW_ACTION_CLASS, "hover:text-foreground"),
980
+ children: /* @__PURE__ */ jsx(Icon, {
981
+ icon: Download,
982
+ className: "size-3"
983
+ })
905
984
  })
906
985
  })]
907
986
  })]
@@ -910,13 +989,40 @@ function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, heade
910
989
  /* @__PURE__ */ jsx("p", {
911
990
  className: "text-muted-foreground mt-auto shrink-0 border-t px-3 py-2 text-[10px]",
912
991
  children: "Chats are saved to your browser's local storage."
992
+ }),
993
+ confirmDelete && /* @__PURE__ */ jsx(Dialog, {
994
+ open: pendingDelete !== null,
995
+ onOpenChange: (open) => !open && setPendingDelete(null),
996
+ children: /* @__PURE__ */ jsxs(Dialog.Content, {
997
+ className: "sm:max-w-md",
998
+ children: [/* @__PURE__ */ jsx(Dialog.Header, {
999
+ title: "Delete chat?",
1000
+ description: pendingDelete ? `"${pendingDelete.title}" will be permanently deleted. This can't be undone.` : void 0
1001
+ }), /* @__PURE__ */ jsxs(Dialog.Footer, {
1002
+ className: "border-t-0",
1003
+ children: [/* @__PURE__ */ jsx(Button, {
1004
+ type: "tertiary",
1005
+ theme: "outline",
1006
+ onClick: () => setPendingDelete(null),
1007
+ children: "Cancel"
1008
+ }), /* @__PURE__ */ jsx(Button, {
1009
+ type: "danger",
1010
+ theme: "solid",
1011
+ onClick: (e) => {
1012
+ if (pendingDelete) onDeleteChat(e, pendingDelete.id);
1013
+ setPendingDelete(null);
1014
+ },
1015
+ children: "Delete"
1016
+ })]
1017
+ })]
1018
+ })
913
1019
  })
914
1020
  ]
915
1021
  });
916
1022
  }
917
1023
  //#endregion
918
1024
  //#region src/components/features/assistant/components/assistant-workspace.tsx
919
- function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory }) {
1025
+ function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onArchiveChat, onUnarchiveChat, confirmDelete, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory }) {
920
1026
  const hasMessages = messages.length > 0;
921
1027
  const promptCard = /* @__PURE__ */ jsx(PromptCard, {
922
1028
  editor,
@@ -961,7 +1067,10 @@ function AssistantWorkspace({ config, userName, title, messages, status, error,
961
1067
  currentChatId,
962
1068
  header: sidebarHeader,
963
1069
  onLoadChat,
964
- onDeleteChat
1070
+ onDeleteChat,
1071
+ onArchiveChat,
1072
+ onUnarchiveChat,
1073
+ confirmDelete
965
1074
  })
966
1075
  })
967
1076
  }),
@@ -1,2 +1,2 @@
1
- import { a as CardField, c as CardFooter, d as CardTitle, i as CardContent, l as CardHeader, n as Card, o as CardFieldLabel, r as CardAction, s as CardFieldValue, t as CardSaveBar, u as CardDescription } from "../card-save-bar-Dub71HRf.mjs";
1
+ import { a as CardField, c as CardFooter, d as CardTitle, i as CardContent, l as CardHeader, n as Card, o as CardFieldLabel, r as CardAction, s as CardFieldValue, t as CardSaveBar, u as CardDescription } from "../card-save-bar-BZzNnKYj.mjs";
2
2
  export { Card, CardAction, CardContent, CardDescription, CardField, CardFieldLabel, CardFieldValue, CardFooter, CardHeader, CardSaveBar, CardTitle };
@@ -35,7 +35,9 @@ function CardDescription({ className, ...props }) {
35
35
  * --card-py vertical inset used by header/footer/content in sectioned cards
36
36
  *
37
37
  * Both are equal for a given `size` (1rem for `sm`, 1.5rem for `md`), so the
38
- * card frame is uniform; `CardHeader size` only nudges the header's own inset.
38
+ * card frame is uniform. `CardHeader size` is a separate density scale
39
+ * (`sm` | `md` | `lg`) for title/description gap and sectioned min-height —
40
+ * it does not change `--card-px` / `--card-py`.
39
41
  *
40
42
  * Consumers building their own rows inside a flush `CardContent` can use
41
43
  * `px-(--card-px)` to line up with the card chrome regardless of `size`.
@@ -90,10 +92,10 @@ function Card({ className, size, sectioned, ...props }) {
90
92
  const cardHeaderVariants = cva("@container/card-header group/card-header border-card-border grid auto-rows-min grid-rows-[auto_auto] content-center items-center px-(--card-px) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:items-start", {
91
93
  variants: {
92
94
  /**
93
- * Header density. Controls the gap between title and description and,
94
- * in sectioned cards, the header's minimum height (`lg` also grows the
95
- * vertical inset). Stacked cards take their vertical spacing from the
96
- * root.
95
+ * Header density (not the card's inset `size`). Controls the gap
96
+ * between title and description and, in sectioned cards, the header's
97
+ * minimum height (`lg` also grows the vertical inset). Stacked cards
98
+ * take their vertical spacing from the root.
97
99
  */
98
100
  size: {
99
101
  sm: "has-data-[slot=card-description]:gap-1 group-data-[layout=sectioned]/card:min-h-12 group-data-[layout=sectioned]/card:py-(--card-py)",
@@ -133,19 +135,20 @@ function CardAction({ className, ...props }) {
133
135
  ...props
134
136
  });
135
137
  }
138
+ /**
139
+ * Shared by CardContent and CardFooter.
140
+ * - `default`: inset to match the card chrome.
141
+ * - `x-none`: no horizontal inset — rows, tables, and dividers run to the
142
+ * card edge while the header stays inset.
143
+ * - `none`: no inset at all.
144
+ */
145
+ const cardPadding = {
146
+ "default": "px-(--card-px) group-data-[layout=sectioned]/card:py-(--card-py)",
147
+ "x-none": "px-0 group-data-[layout=sectioned]/card:py-(--card-py)",
148
+ "none": "p-0"
149
+ };
136
150
  const cardContentVariants = cva("", {
137
- variants: {
138
- /**
139
- * - `default`: inset to match the card chrome.
140
- * - `x-none`: no horizontal inset — rows, tables, and dividers run to
141
- * the card edge while the header stays inset.
142
- * - `none`: no inset at all.
143
- */
144
- padding: {
145
- "default": "px-(--card-px) group-data-[layout=sectioned]/card:py-(--card-py)",
146
- "x-none": "px-0 group-data-[layout=sectioned]/card:py-(--card-py)",
147
- "none": "p-0"
148
- } },
151
+ variants: { padding: cardPadding },
149
152
  defaultVariants: { padding: "default" }
150
153
  });
151
154
  function CardContent({ className, padding, ...props }) {
@@ -157,11 +160,7 @@ function CardContent({ className, padding, ...props }) {
157
160
  }
158
161
  const cardFooterVariants = cva("border-card-border", {
159
162
  variants: {
160
- padding: {
161
- "default": "px-(--card-px) group-data-[layout=sectioned]/card:py-(--card-py)",
162
- "x-none": "px-0 group-data-[layout=sectioned]/card:py-(--card-py)",
163
- "none": "p-0"
164
- },
163
+ padding: cardPadding,
165
164
  /** Draw a divider above the footer. Pairs with `sectioned` cards. */
166
165
  bordered: {
167
166
  true: "border-t",
@@ -236,11 +235,12 @@ function CardSaveBar({ changeCount, errorCount = 0, saving = false, onCancel, on
236
235
  return /* @__PURE__ */ jsxs(CardFooter, {
237
236
  bordered: true,
238
237
  "data-slot": "card-save-bar",
239
- role: "status",
240
- "aria-live": "polite",
241
238
  className: cn("flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", className),
242
239
  ...props,
243
240
  children: [/* @__PURE__ */ jsxs("p", {
241
+ role: "status",
242
+ "aria-live": "polite",
243
+ "aria-atomic": "true",
244
244
  className: "text-muted-foreground flex min-w-0 flex-wrap items-center gap-x-1.5 gap-y-0.5 text-sm",
245
245
  children: [/* @__PURE__ */ jsx("span", {
246
246
  className: "text-foreground font-medium",
@@ -16,7 +16,9 @@ import * as React from 'react';
16
16
  * --card-py vertical inset used by header/footer/content in sectioned cards
17
17
  *
18
18
  * Both are equal for a given `size` (1rem for `sm`, 1.5rem for `md`), so the
19
- * card frame is uniform; `CardHeader size` only nudges the header's own inset.
19
+ * card frame is uniform. `CardHeader size` is a separate density scale
20
+ * (`sm` | `md` | `lg`) for title/description gap and sectioned min-height —
21
+ * it does not change `--card-px` / `--card-py`.
20
22
  *
21
23
  * Consumers building their own rows inside a flush `CardContent` can use
22
24
  * `px-(--card-px)` to line up with the card chrome regardless of `size`.
@@ -1,2 +1 @@
1
1
  export { SettingsNav, SettingsNavItem, type SettingsNavItemProps, SettingsNavLabel } from './settings-nav';
2
- export { settingsNavItemVariants } from './settings-nav-variants';
@@ -1,6 +1,5 @@
1
1
  import type { VariantProps } from 'class-variance-authority';
2
2
  import * as React from 'react';
3
- import { settingsNavItemVariants } from './settings-nav-variants';
4
3
  /**
5
4
  * Compact inset settings navigation for configuration pages.
6
5
  *
@@ -9,6 +8,9 @@ import { settingsNavItemVariants } from './settings-nav-variants';
9
8
  * eyebrow, icon items with an active fill, optional error dots, Soon badges,
10
9
  * and a danger item for destructive sections.
11
10
  */
11
+ declare const settingsNavItemVariants: (props?: ({
12
+ variant?: "default" | "danger" | null | undefined;
13
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
14
  declare function SettingsNav({ className, ...props }: React.ComponentProps<'nav'>): React.JSX.Element;
13
15
  declare function SettingsNavLabel({ className, ...props }: React.ComponentProps<'div'>): React.JSX.Element;
14
16
  export interface SettingsNavItemProps extends React.AnchorHTMLAttributes<HTMLAnchorElement>, VariantProps<typeof settingsNavItemVariants> {
@@ -38,6 +38,16 @@ export interface AssistantWorkspaceProps {
38
38
  onNewChat: () => void;
39
39
  onLoadChat: (chat: ChatSummary) => void;
40
40
  onDeleteChat: (e: ReactMouseEvent, chatId: string) => void;
41
+ /**
42
+ * Opt-in archive support. When provided, `chatList` may mix archived and
43
+ * active chats; the history panel lists active chats by default and adds an
44
+ * "Archived" view toggle plus per-row archive actions.
45
+ */
46
+ onArchiveChat?: (e: ReactMouseEvent, chatId: string) => void;
47
+ /** Restores an archived chat from the history panel's archived view. */
48
+ onUnarchiveChat?: (e: ReactMouseEvent, chatId: string) => void;
49
+ /** Confirm (deletion can't be undone) before calling `onDeleteChat`. */
50
+ confirmDelete?: boolean;
41
51
  onSuggestion: (text: string) => void;
42
52
  modelId: string;
43
53
  effortId: EffortId;
@@ -50,4 +60,4 @@ export interface AssistantWorkspaceProps {
50
60
  historyOpen: boolean;
51
61
  onToggleHistory: () => void;
52
62
  }
53
- export declare function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory, }: AssistantWorkspaceProps): import("react").JSX.Element;
63
+ export declare function AssistantWorkspace({ config, userName, title, messages, status, error, isReady, chatList, currentChatId, sidebarHeader, editor, htmlByUserMsgIndex, bottomRef, containerRef, userScrolledUpRef, onSend, onStop, onRetry, onNewChat, onLoadChat, onDeleteChat, onArchiveChat, onUnarchiveChat, confirmDelete, onSuggestion, modelId, effortId, onModelChange, onEffortChange, micSupported, micListening, micFrequencyData, onMicToggle, historyOpen, onToggleHistory, }: AssistantWorkspaceProps): import("react").JSX.Element;
@@ -1,10 +1,24 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { ChatSummary } from '../../types';
3
- interface HistoryPanelProps {
3
+ export interface HistoryPanelProps {
4
4
  chatList: ChatSummary[];
5
5
  currentChatId: string;
6
6
  onLoadChat: (chat: ChatSummary) => void;
7
7
  onDeleteChat: (e: React.MouseEvent, chatId: string) => void;
8
+ /**
9
+ * Opt-in archive support. When provided, `chatList` may mix archived and
10
+ * active chats: the panel lists active chats by default, adds an "Archived"
11
+ * view toggle next to the search input, and gives active rows an archive
12
+ * action. When omitted, the `archived` flag is ignored and no archive UI renders.
13
+ */
14
+ onArchiveChat?: (e: React.MouseEvent, chatId: string) => void;
15
+ /** Restores an archived chat. Rendered on rows in the archived view. */
16
+ onUnarchiveChat?: (e: React.MouseEvent, chatId: string) => void;
17
+ /**
18
+ * Ask for confirmation (deletion can't be undone) before calling
19
+ * `onDeleteChat`. Defaults to false, which deletes immediately.
20
+ */
21
+ confirmDelete?: boolean;
8
22
  /**
9
23
  * Optional host-supplied block pinned above the search input, naming the scope
10
24
  * the listed chats belong to — cloud-portal shows the current project. Hosts
@@ -12,5 +26,4 @@ interface HistoryPanelProps {
12
26
  */
13
27
  header?: ReactNode;
14
28
  }
15
- export declare function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, header, }: HistoryPanelProps): import("react").JSX.Element;
16
- export {};
29
+ export declare function HistoryPanel({ chatList, currentChatId, onLoadChat, onDeleteChat, onArchiveChat, onUnarchiveChat, confirmDelete, header, }: HistoryPanelProps): import("react").JSX.Element;
@@ -63,4 +63,9 @@ export interface ChatSummary {
63
63
  title: string;
64
64
  updatedAt: number;
65
65
  messages: UIMessage[];
66
+ /**
67
+ * Archived (hidden but restorable). Only honoured when the host passes
68
+ * `onArchiveChat`; otherwise every chat is listed regardless of this flag.
69
+ */
70
+ archived?: boolean;
66
71
  }
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import { t as Separator } from "./separator-vbPD_WFQ.mjs";
10
10
  import { i as buttonGroupVariants, n as ButtonGroupSeparator, r as ButtonGroupText, t as ButtonGroup } from "./button-group-DFrTH4L8.mjs";
11
11
  import { t as Icon } from "./icon-wrapper-DKfJlJd0.mjs";
12
12
  import { Calendar, CalendarDayButton } from "./calendar/index.mjs";
13
- import { a as CardField, c as CardFooter, d as CardTitle, i as CardContent, l as CardHeader, n as Card, o as CardFieldLabel, r as CardAction, s as CardFieldValue, t as CardSaveBar, u as CardDescription } from "./card-save-bar-Dub71HRf.mjs";
13
+ import { a as CardField, c as CardFooter, d as CardTitle, i as CardContent, l as CardHeader, n as Card, o as CardFieldLabel, r as CardAction, s as CardFieldValue, t as CardSaveBar, u as CardDescription } from "./card-save-bar-BZzNnKYj.mjs";
14
14
  import { a as ChartTooltip, i as ChartStyle, n as ChartLegend, o as ChartTooltipContent, r as ChartLegendContent, t as ChartContainer } from "./chart-EgzTS28l.mjs";
15
15
  import { t as Checkbox } from "./checkbox-C6P12fio.mjs";
16
16
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./collapsible/index.mjs";
@@ -33,7 +33,7 @@ import { t as useBreakpoint } from "./use-breakpoint-CwiUJSmk.mjs";
33
33
  import { t as ResponsiveDropdown } from "./responsive-dropdown-C_KKgLbH.mjs";
34
34
  import { t as ResponsivePopover } from "./responsive-popover-8VcjBM2d.mjs";
35
35
  import { a as SelectLabel, c as SelectSeparator, i as SelectItem, l as SelectTrigger, n as SelectContent, o as SelectScrollDownButton, r as SelectGroup, s as SelectScrollUpButton, t as Select, u as SelectValue } from "./select-D4pk9e2d.mjs";
36
- import { i as settingsNavItemVariants, n as SettingsNavItem, r as SettingsNavLabel, t as SettingsNav } from "./settings-nav-BCL1lMTM.mjs";
36
+ import { n as SettingsNavItem, r as SettingsNavLabel, t as SettingsNav } from "./settings-nav-C_AF6gld.mjs";
37
37
  import { C as SidebarProvider, S as SidebarGroupLabel, _ as SidebarMenuSubButton, a as SidebarInput, b as SidebarGroupAction, c as SidebarSeparator, d as SidebarMenuAction, f as SidebarMenuBadge, g as SidebarMenuSub, h as SidebarMenuSkeleton, i as SidebarHeader, l as SidebarTrigger, m as SidebarMenuItem, n as SidebarContent, o as SidebarInset, p as SidebarMenuButton, r as SidebarFooter, s as SidebarRail, t as Sidebar, u as SidebarMenu, v as SidebarMenuSubItem, w as useSidebar, x as SidebarGroupContent, y as SidebarGroup } from "./sidebar-BeWEEu7P.mjs";
38
38
  import { t as Tooltip } from "./tooltip-DhbN1BDK.mjs";
39
39
  import { Skeleton } from "./skeleton/index.mjs";
@@ -85,4 +85,4 @@ import { _ as RedisTaskStorage, a as TaskPanelItem, b as createProjectMetadata,
85
85
  import { _ as getShortTimezoneDisplay, a as TimeRangePicker, b as utcToLocalInputString, c as getPresetByKey, d as TimezoneSelector, f as QuickRangesPanel, g as getDefaultTimezoneOptions, h as formatUtcForDisplay, i as formatTimeRangeDisplay, l as getPresetByShortcut, m as createTimezoneOption, n as formatDateForInput, o as DEFAULT_PRESETS, p as CustomRangePanel, r as formatSingleTimeDisplay, s as getDefaultPreset, t as toApiTimeRange, u as getPresetRange, v as localInputStringToUtc, x as zonedDateToUtcString, y as utcStringToZonedDate } from "./to-api-format-W3qJE68W.mjs";
86
86
  import { t as useDebounce } from "./hooks-CwZ6hyI1.mjs";
87
87
  import { n as toUTCTimestampStartOfDay, t as toUTCTimestampEndOfDay } from "./utils-CA4QEIJ8.mjs";
88
- export { CustomRangePanel as AbsoluteRangePanel, CustomRangePanel, ActionRow, Alert, AlertDescription, AlertTitle, AppNavigation, Autocomplete, Autosearch, Avatar, AvatarFallback, AvatarImage, AvatarStack, Badge, Blockquote, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDatePicker, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardField, CardFieldLabel, CardFieldValue, CardFooter, CardHeader, CardSaveBar, CardTitle, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, ClientOnly, CloseIcon, Code, CodeEditor, CodeEditorTabs, Col, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_DATE_FORMAT, DEFAULT_DEBOUNCE_MS, DEFAULT_LOADING_ROWS, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES, DEFAULT_PRESETS, DEFAULT_SEARCH_DEBOUNCE_MS, DURATION, DataTable, DataTableColumnHeader, DataTableRowActions, DateTime, DateTimePicker, Dialog, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Dropzone, DropzoneContent, DropzoneEmptyState, EASE, EmptyContent, FileInputButton, Form, FormAdapterProvider, FormAutocomplete, FormAutosearch, FormButton, FormCheckbox, FormCombobox, FormCopyBox, FormCustom, FormDatePicker, FormDateTimePicker, FormDescription, FormDialog, FormError, FormField, FormFieldArray, FormInput, FormRadioGroup, FormRadioItem, FormRoot, FormSelect, FormSelectItem, FormSubmit, FormSwitch, FormTextarea, FormTimePicker, FormTransfer, FormWhen, GRID_BREAKPOINTS, GRID_COLUMNS, GRID_PREFIX, GroupedTable, HoverCard, HoverCardContent, HoverCardTrigger, Icon, InSheetContext, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputNumber, InputWithAddons, Label, Link, LinkButton, List, ListItem, LoaderOverlay, LocalTaskStorage, Logo, LogoFlat, LogoIcon, LogoStacked, LogoText, Map, MapCircle, MapCircleMarker, MapControlContainer, MapDrawCircle, MapDrawControl, MapDrawDelete, MapDrawEdit, MapDrawMarker, MapDrawPolygon, MapDrawPolyline, MapDrawRectangle, MapDrawUndo, MapFeatureGroup, MapFullscreenControl, MapLayerGroup, MapLayers, MapLayersControl, MapLocateControl, MapMarker, MapMarkerClusterGroup, MapPolygon, MapPolyline, MapPopup, MapRectangle, MapSearchControl, MapTileLayer, MapTooltip, MapZoomControl, MobileSheet, MoreActions, MultiSelect, NavMenu, NavMenuItem, PageTitle, Paragraph, PlaceAutocomplete, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, QuickRangesPanel, RESPONSIVE_ARRAY, RESPONSIVE_MAP, RadioGroup, RadioGroupItem, RedisTaskStorage, ResponsiveDropdown, ResponsivePopover, ResponsiveSheetTrigger, RichTextContent, RichTextEditor, Row, RowContext, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SettingsNav, SettingsNavItem, SettingsNavLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Spinner, SpinnerIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsLinkTrigger, TabsList, TabsTrigger, TagsInput, TaskPanel, TaskPanelActions, TaskPanelCounter, TaskPanelHeader, TaskPanelItem, TaskQueue, TaskQueueDropdown, TaskQueueProvider, TaskQueueTrigger, TaskSummaryDialog, Text, Textarea, ThemeProvider, ThemeScript, TimePicker, TimeRangePicker, TimezoneSelector, Title, Toaster, Tooltip, Transfer, VisuallyHidden, avatarStackVariants, badgeVariants, buttonGroupVariants, buttonVariants, cn, configureProgress, createCodeEditorSchema, createDataTableStore, createOrgMetadata, createProjectMetadata, createSelectionColumn, createTimezoneOption, createUserMetadata, dataTableFeatures, defaultAutosearchValue, defineStepper, detectStorage, findItemByHref, formatAbsoluteDate, formatCombinedDate, formatDateForInput, formatJson, formatRelativeDate, formatSingleTimeDisplay, formatTimeRangeDisplay, formatTimezoneDate, formatTimezoneLabel, formatUTCDate, formatUtcForDisplay, formatYaml, getBrowserTimezone, getContextLabel, getDefaultPreset, getDefaultTimezoneOptions, getGutter, getPresetByKey, getPresetByShortcut, getPresetRange, getResponsiveValue, getShortTimezoneDisplay, getTimestamp, getTimezoneAbbreviation, getTimezoneOffset, hasActiveDescendant, isNavItemActive, isValidJson, isValidYaml, jsonSchema, jsonToYaml, localInputStringToUtc, logoStyles, matchesCurrentScope, normalizePath, paragraphVariants, parseDate, registerMediaQuery, resolvePath, rowMatchesSearch, settingsNavItemVariants, startProgress, stopProgress, textVariants, titleVariants, toApiTimeRange, toUTCTimestampEndOfDay, toUTCTimestampStartOfDay, toast, useAdapter, useBreakpoint, useControllableState, useCopyToClipboard, useCurrentScope, useDataTableFilters, useDataTableInlineContents, useDataTableLoading, useDataTablePagination, useDataTableRows, useDataTableSearch, useDataTableSelection, useDataTableSorting, useDebounce, useDebouncedSearchInput, useField, useFieldContext, useFormContext, useFormState, useInSheet, useLeaflet, useNuqsAdapter, useRichTextEditor, useSidebar, useTaskQueue, useTasksWithLabels, useTheme, useToast, useWatch, useWatchAll, utcStringToZonedDate, utcToLocalInputString, yamlSchema, yamlToJson, zonedDateToUtcString };
88
+ export { CustomRangePanel as AbsoluteRangePanel, CustomRangePanel, ActionRow, Alert, AlertDescription, AlertTitle, AppNavigation, Autocomplete, Autosearch, Avatar, AvatarFallback, AvatarImage, AvatarStack, Badge, Blockquote, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDatePicker, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardField, CardFieldLabel, CardFieldValue, CardFooter, CardHeader, CardSaveBar, CardTitle, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, ClientOnly, CloseIcon, Code, CodeEditor, CodeEditorTabs, Col, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_DATE_FORMAT, DEFAULT_DEBOUNCE_MS, DEFAULT_LOADING_ROWS, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZES, DEFAULT_PRESETS, DEFAULT_SEARCH_DEBOUNCE_MS, DURATION, DataTable, DataTableColumnHeader, DataTableRowActions, DateTime, DateTimePicker, Dialog, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Dropzone, DropzoneContent, DropzoneEmptyState, EASE, EmptyContent, FileInputButton, Form, FormAdapterProvider, FormAutocomplete, FormAutosearch, FormButton, FormCheckbox, FormCombobox, FormCopyBox, FormCustom, FormDatePicker, FormDateTimePicker, FormDescription, FormDialog, FormError, FormField, FormFieldArray, FormInput, FormRadioGroup, FormRadioItem, FormRoot, FormSelect, FormSelectItem, FormSubmit, FormSwitch, FormTextarea, FormTimePicker, FormTransfer, FormWhen, GRID_BREAKPOINTS, GRID_COLUMNS, GRID_PREFIX, GroupedTable, HoverCard, HoverCardContent, HoverCardTrigger, Icon, InSheetContext, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputNumber, InputWithAddons, Label, Link, LinkButton, List, ListItem, LoaderOverlay, LocalTaskStorage, Logo, LogoFlat, LogoIcon, LogoStacked, LogoText, Map, MapCircle, MapCircleMarker, MapControlContainer, MapDrawCircle, MapDrawControl, MapDrawDelete, MapDrawEdit, MapDrawMarker, MapDrawPolygon, MapDrawPolyline, MapDrawRectangle, MapDrawUndo, MapFeatureGroup, MapFullscreenControl, MapLayerGroup, MapLayers, MapLayersControl, MapLocateControl, MapMarker, MapMarkerClusterGroup, MapPolygon, MapPolyline, MapPopup, MapRectangle, MapSearchControl, MapTileLayer, MapTooltip, MapZoomControl, MobileSheet, MoreActions, MultiSelect, NavMenu, NavMenuItem, PageTitle, Paragraph, PlaceAutocomplete, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, QuickRangesPanel, RESPONSIVE_ARRAY, RESPONSIVE_MAP, RadioGroup, RadioGroupItem, RedisTaskStorage, ResponsiveDropdown, ResponsivePopover, ResponsiveSheetTrigger, RichTextContent, RichTextEditor, Row, RowContext, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SettingsNav, SettingsNavItem, SettingsNavLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Spinner, SpinnerIcon, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsLinkTrigger, TabsList, TabsTrigger, TagsInput, TaskPanel, TaskPanelActions, TaskPanelCounter, TaskPanelHeader, TaskPanelItem, TaskQueue, TaskQueueDropdown, TaskQueueProvider, TaskQueueTrigger, TaskSummaryDialog, Text, Textarea, ThemeProvider, ThemeScript, TimePicker, TimeRangePicker, TimezoneSelector, Title, Toaster, Tooltip, Transfer, VisuallyHidden, avatarStackVariants, badgeVariants, buttonGroupVariants, buttonVariants, cn, configureProgress, createCodeEditorSchema, createDataTableStore, createOrgMetadata, createProjectMetadata, createSelectionColumn, createTimezoneOption, createUserMetadata, dataTableFeatures, defaultAutosearchValue, defineStepper, detectStorage, findItemByHref, formatAbsoluteDate, formatCombinedDate, formatDateForInput, formatJson, formatRelativeDate, formatSingleTimeDisplay, formatTimeRangeDisplay, formatTimezoneDate, formatTimezoneLabel, formatUTCDate, formatUtcForDisplay, formatYaml, getBrowserTimezone, getContextLabel, getDefaultPreset, getDefaultTimezoneOptions, getGutter, getPresetByKey, getPresetByShortcut, getPresetRange, getResponsiveValue, getShortTimezoneDisplay, getTimestamp, getTimezoneAbbreviation, getTimezoneOffset, hasActiveDescendant, isNavItemActive, isValidJson, isValidYaml, jsonSchema, jsonToYaml, localInputStringToUtc, logoStyles, matchesCurrentScope, normalizePath, paragraphVariants, parseDate, registerMediaQuery, resolvePath, rowMatchesSearch, startProgress, stopProgress, textVariants, titleVariants, toApiTimeRange, toUTCTimestampEndOfDay, toUTCTimestampStartOfDay, toast, useAdapter, useBreakpoint, useControllableState, useCopyToClipboard, useCurrentScope, useDataTableFilters, useDataTableInlineContents, useDataTableLoading, useDataTablePagination, useDataTableRows, useDataTableSearch, useDataTableSelection, useDataTableSorting, useDebounce, useDebouncedSearchInput, useField, useFieldContext, useFormContext, useFormState, useInSheet, useLeaflet, useNuqsAdapter, useRichTextEditor, useSidebar, useTaskQueue, useTasksWithLabels, useTheme, useToast, useWatch, useWatchAll, utcStringToZonedDate, utcToLocalInputString, yamlSchema, yamlToJson, zonedDateToUtcString };
@@ -1,2 +1,2 @@
1
- import { i as settingsNavItemVariants, n as SettingsNavItem, r as SettingsNavLabel, t as SettingsNav } from "../settings-nav-BCL1lMTM.mjs";
2
- export { SettingsNav, SettingsNavItem, SettingsNavLabel, settingsNavItemVariants };
1
+ import { n as SettingsNavItem, r as SettingsNavLabel, t as SettingsNav } from "../settings-nav-C_AF6gld.mjs";
2
+ export { SettingsNav, SettingsNavItem, SettingsNavLabel };
@@ -1,17 +1,8 @@
1
1
  import { t as cn } from "./utils-Bu32wN-x.mjs";
2
2
  import { cva } from "class-variance-authority";
3
- import "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Slot } from "@radix-ui/react-slot";
6
- //#region src/components/base/settings-nav/settings-nav-variants.ts
7
- const settingsNavItemVariants = cva("group/settings-nav-item relative flex w-full items-center gap-2.5 rounded-md px-2.5 py-1.5 text-sm font-normal transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50", {
8
- variants: { variant: {
9
- default: "text-foreground hover:bg-primary/5 hover:text-primary data-[active=true]:bg-primary/10 data-[active=true]:text-primary",
10
- danger: "text-destructive hover:bg-destructive/10 data-[active=true]:bg-destructive/10 data-[active=true]:text-destructive"
11
- } },
12
- defaultVariants: { variant: "default" }
13
- });
14
- //#endregion
15
6
  //#region src/components/base/settings-nav/settings-nav.tsx
16
7
  /**
17
8
  * Compact inset settings navigation for configuration pages.
@@ -21,6 +12,13 @@ const settingsNavItemVariants = cva("group/settings-nav-item relative flex w-ful
21
12
  * eyebrow, icon items with an active fill, optional error dots, Soon badges,
22
13
  * and a danger item for destructive sections.
23
14
  */
15
+ const settingsNavItemVariants = cva("group/settings-nav-item relative flex w-full items-center gap-2.5 rounded-md px-2.5 py-1.5 text-xs font-normal transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring aria-disabled:pointer-events-none aria-disabled:opacity-50", {
16
+ variants: { variant: {
17
+ default: "text-foreground hover:bg-primary/5 hover:text-primary data-[active=true]:bg-primary/10 data-[active=true]:text-primary",
18
+ danger: "text-destructive hover:bg-destructive/10 data-[active=true]:bg-destructive/10 data-[active=true]:text-destructive"
19
+ } },
20
+ defaultVariants: { variant: "default" }
21
+ });
24
22
  function SettingsNav({ className, ...props }) {
25
23
  return /* @__PURE__ */ jsx("nav", {
26
24
  "data-slot": "settings-nav",
@@ -37,7 +35,6 @@ function SettingsNavLabel({ className, ...props }) {
37
35
  });
38
36
  }
39
37
  function SettingsNavItem({ className, variant, asChild = false, icon, active = false, indicator = false, badge, disabled = false, children, href, onClick, ...props }) {
40
- const Comp = asChild ? Slot : "a";
41
38
  const handleClick = (event) => {
42
39
  if (disabled) {
43
40
  event.preventDefault();
@@ -45,40 +42,53 @@ function SettingsNavItem({ className, variant, asChild = false, icon, active = f
45
42
  }
46
43
  onClick?.(event);
47
44
  };
48
- return /* @__PURE__ */ jsxs(Comp, {
45
+ const label = asChild && React.isValidElement(children) ? children.props.children : children;
46
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
47
+ icon ? /* @__PURE__ */ jsx("span", {
48
+ "data-slot": "settings-nav-item-icon",
49
+ className: "flex size-4 shrink-0 items-center justify-center text-muted-foreground transition-colors group-hover/settings-nav-item:text-primary group-data-[active=true]/settings-nav-item:text-primary group-data-[variant=danger]/settings-nav-item:!text-destructive [&_svg]:size-4",
50
+ "aria-hidden": "true",
51
+ children: icon
52
+ }) : null,
53
+ /* @__PURE__ */ jsx("span", {
54
+ className: "min-w-0 flex-1 truncate text-left",
55
+ children: label
56
+ }),
57
+ indicator ? /* @__PURE__ */ jsx("span", {
58
+ "data-slot": "settings-nav-item-indicator",
59
+ className: "bg-destructive size-1.5 shrink-0 rounded-full",
60
+ "aria-label": "Needs attention"
61
+ }) : null,
62
+ badge != null ? /* @__PURE__ */ jsx("span", {
63
+ "data-slot": "settings-nav-item-badge",
64
+ className: "bg-muted text-muted-foreground rounded-md px-1.5 py-0.5 text-[10px] font-semibold tracking-wide uppercase",
65
+ children: badge
66
+ }) : null
67
+ ] });
68
+ const itemClassName = cn(settingsNavItemVariants({ variant }), className);
69
+ const itemProps = {
49
70
  "data-slot": "settings-nav-item",
50
71
  "data-active": active || void 0,
51
72
  "data-variant": variant ?? "default",
52
73
  "aria-current": active ? "page" : void 0,
53
74
  "aria-disabled": disabled || void 0,
54
- tabIndex: disabled ? -1 : void 0,
75
+ "tabIndex": disabled ? -1 : void 0,
76
+ "onClick": handleClick,
77
+ "className": itemClassName,
78
+ ...props
79
+ };
80
+ if (asChild && React.isValidElement(children)) {
81
+ const slotted = React.cloneElement(children, void 0, content);
82
+ return /* @__PURE__ */ jsx(Slot, {
83
+ ...itemProps,
84
+ children: slotted
85
+ });
86
+ }
87
+ return /* @__PURE__ */ jsx("a", {
55
88
  href: disabled ? void 0 : href,
56
- onClick: handleClick,
57
- className: cn(settingsNavItemVariants({ variant }), className),
58
- ...props,
59
- children: [
60
- icon ? /* @__PURE__ */ jsx("span", {
61
- "data-slot": "settings-nav-item-icon",
62
- className: cn("flex size-4 shrink-0 items-center justify-center [&_svg]:size-4", variant === "danger" ? "text-destructive" : "text-muted-foreground transition-colors group-hover/settings-nav-item:text-primary group-data-[active=true]/settings-nav-item:text-primary"),
63
- "aria-hidden": "true",
64
- children: icon
65
- }) : null,
66
- /* @__PURE__ */ jsx("span", {
67
- className: "min-w-0 flex-1 truncate text-left",
68
- children
69
- }),
70
- indicator ? /* @__PURE__ */ jsx("span", {
71
- "data-slot": "settings-nav-item-indicator",
72
- className: "bg-destructive size-1.5 shrink-0 rounded-full",
73
- "aria-label": "Needs attention"
74
- }) : null,
75
- badge != null ? /* @__PURE__ */ jsx("span", {
76
- "data-slot": "settings-nav-item-badge",
77
- className: "bg-muted text-muted-foreground rounded-md px-1.5 py-0.5 text-[10px] font-semibold tracking-wide uppercase",
78
- children: badge
79
- }) : null
80
- ]
89
+ ...itemProps,
90
+ children: content
81
91
  });
82
92
  }
83
93
  //#endregion
84
- export { settingsNavItemVariants as i, SettingsNavItem as n, SettingsNavLabel as r, SettingsNav as t };
94
+ export { SettingsNavItem as n, SettingsNavLabel as r, SettingsNav as t };
@@ -15,9 +15,9 @@ function Tabs({ className, value: valueProp, defaultValue, onValueChange, ...pro
15
15
  const value = valueProp ?? uncontrolled;
16
16
  const indicatorId = React.useId();
17
17
  const handleValueChange = React.useCallback((next) => {
18
- setUncontrolled(next);
18
+ if (valueProp === void 0) setUncontrolled(next);
19
19
  onValueChange?.(next);
20
- }, [onValueChange]);
20
+ }, [onValueChange, valueProp]);
21
21
  const ctx = React.useMemo(() => ({
22
22
  value,
23
23
  indicatorId
@@ -65,6 +65,7 @@ function TabsTrigger({ className, value, children, asChild, ...props }) {
65
65
  "aria-hidden": true,
66
66
  "data-slot": "tabs-indicator",
67
67
  layoutId: `tabs-indicator-${indicatorId}`,
68
+ "data-layout-id": `tabs-indicator-${indicatorId}`,
68
69
  className: "bg-primary absolute inset-x-0 bottom-0 h-0.5",
69
70
  transition: {
70
71
  type: "spring",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datum-cloud/datum-ui",
3
3
  "type": "module",
4
- "version": "2.9.0",
4
+ "version": "2.10.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "url": "https://github.com/datum-cloud/datum-ui"
@@ -1,3 +0,0 @@
1
- export declare const settingsNavItemVariants: (props?: ({
2
- variant?: "default" | "danger" | null | undefined;
3
- } & import("class-variance-authority/types").ClassProp) | undefined) => string;