@tangle-network/sandbox-ui 0.50.0 → 0.51.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.
package/dist/assistant.js CHANGED
@@ -4,6 +4,10 @@ import {
4
4
  import {
5
5
  providerLabel
6
6
  } from "./chunk-7JLB7UZ3.js";
7
+ import {
8
+ ModelPicker
9
+ } from "./chunk-LQHTCM56.js";
10
+ import "./chunk-EI44GEQ5.js";
7
11
  import "./chunk-U67V476Y.js";
8
12
 
9
13
  // src/assistant/sse.ts
@@ -1532,14 +1536,14 @@ function useAssistantThreads(userId) {
1532
1536
  // src/assistant/AssistantDock.tsx
1533
1537
  import { MessageSquare } from "lucide-react";
1534
1538
  import {
1535
- useEffect as useEffect5,
1539
+ useEffect as useEffect6,
1536
1540
  useRef as useRef6
1537
1541
  } from "react";
1538
1542
 
1539
1543
  // src/assistant/AssistantPanel.tsx
1540
1544
  import { AgentTimeline, ChatInput, ThinkingIndicator } from "@tangle-network/ui/chat";
1541
1545
  import { History, MessageSquarePlus, Minus, Plus, Trash2, X } from "lucide-react";
1542
- import { useRef as useRef4, useState as useState5 } from "react";
1546
+ import { useEffect as useEffect5, useMemo, useRef as useRef4, useState as useState5 } from "react";
1543
1547
 
1544
1548
  // src/assistant/build-timeline.tsx
1545
1549
  import { jsx as jsx2 } from "react/jsx-runtime";
@@ -1910,6 +1914,23 @@ function defaultFormatMoney(usd) {
1910
1914
  currency: "USD"
1911
1915
  }).format(usd);
1912
1916
  }
1917
+ function toPickerModels(models, selected) {
1918
+ const mapped = models.models.map((m) => ({
1919
+ id: m.slug,
1920
+ name: m.label,
1921
+ ...m.contextTokens != null ? { context_length: m.contextTokens } : {}
1922
+ }));
1923
+ for (const slug of [models.default, selected]) {
1924
+ if (slug && !mapped.some((m) => m.id === slug)) {
1925
+ mapped.push({ id: slug, name: slug });
1926
+ }
1927
+ }
1928
+ return mapped;
1929
+ }
1930
+ function nextModelSelection(id, defaultSlug) {
1931
+ if (defaultSlug != null && id === defaultSlug) return null;
1932
+ return id || null;
1933
+ }
1913
1934
  function AssistantPanel({
1914
1935
  chat,
1915
1936
  userId,
@@ -1924,9 +1945,41 @@ function AssistantPanel({
1924
1945
  const threads = useAssistantThreads(userId);
1925
1946
  const font = useFontScale();
1926
1947
  const [historyOpen, setHistoryOpen] = useState5(false);
1948
+ const historyRef = useRef4(null);
1949
+ const historyButtonRef = useRef4(null);
1950
+ const pickerModels = useMemo(
1951
+ () => toPickerModels(models, chat.selectedModel),
1952
+ [models, chat.selectedModel]
1953
+ );
1954
+ const pickerValue = chat.selectedModel ?? models.default ?? "";
1927
1955
  const { state } = chat;
1928
1956
  const chatRef = useRef4(chat);
1929
1957
  chatRef.current = chat;
1958
+ useEffect5(() => {
1959
+ if (!historyOpen) return;
1960
+ const onPointerDown = (e) => {
1961
+ const target = e.target;
1962
+ if (historyRef.current?.contains(target)) return;
1963
+ if (historyButtonRef.current?.contains(target)) return;
1964
+ setHistoryOpen(false);
1965
+ };
1966
+ const onKeyDownCapture = (e) => {
1967
+ if (e.key !== "Escape") return;
1968
+ if (!historyRef.current?.contains(e.target)) return;
1969
+ e.stopImmediatePropagation();
1970
+ setHistoryOpen(false);
1971
+ historyButtonRef.current?.focus();
1972
+ };
1973
+ document.addEventListener("pointerdown", onPointerDown);
1974
+ document.addEventListener("keydown", onKeyDownCapture, true);
1975
+ return () => {
1976
+ document.removeEventListener("pointerdown", onPointerDown);
1977
+ document.removeEventListener("keydown", onKeyDownCapture, true);
1978
+ };
1979
+ }, [historyOpen]);
1980
+ useEffect5(() => {
1981
+ if (historyOpen) historyRef.current?.focus();
1982
+ }, [historyOpen]);
1930
1983
  const effectiveBalance = state.usage?.balanceUsd ?? balanceUsd;
1931
1984
  const errorView = state.error ? presentError(state.error.code, state.error.message) : null;
1932
1985
  const low = isLowBalance(effectiveBalance) && !errorView;
@@ -1965,140 +2018,161 @@ function AssistantPanel({
1965
2018
  chatRef.current.reset();
1966
2019
  }
1967
2020
  };
1968
- return /* @__PURE__ */ jsxs2("div", { className: "flex h-full flex-col bg-background", children: [
1969
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 border-border border-b px-4 py-3", children: [
1970
- /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-col", children: [
1971
- /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-2", children: [
1972
- /* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground text-sm", children: "Assistant" }),
1973
- /* @__PURE__ */ jsx4(
2021
+ return /* @__PURE__ */ jsxs2("div", { className: "relative flex h-full flex-col bg-background", children: [
2022
+ /* @__PURE__ */ jsxs2("div", { className: "relative z-10 border-border border-b", children: [
2023
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 px-4 pt-3 pb-1.5", children: [
2024
+ /* @__PURE__ */ jsxs2("div", { className: "flex min-w-0 flex-col", children: [
2025
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-baseline gap-2", children: [
2026
+ /* @__PURE__ */ jsx4("span", { className: "font-medium text-foreground text-sm", children: "Assistant" }),
2027
+ /* @__PURE__ */ jsx4(
2028
+ "span",
2029
+ {
2030
+ "aria-label": "Your credit balance",
2031
+ className: "text-muted-foreground text-xs",
2032
+ children: formatMoney(effectiveBalance)
2033
+ }
2034
+ )
2035
+ ] }),
2036
+ conversationTitle && /* @__PURE__ */ jsx4(
1974
2037
  "span",
1975
2038
  {
1976
- "aria-label": "Your credit balance",
1977
- className: "text-muted-foreground text-xs",
1978
- children: formatMoney(effectiveBalance)
2039
+ className: "truncate text-muted-foreground text-xs",
2040
+ title: conversationTitle,
2041
+ children: conversationTitle
1979
2042
  }
1980
2043
  )
1981
2044
  ] }),
1982
- conversationTitle && /* @__PURE__ */ jsx4(
1983
- "span",
1984
- {
1985
- className: "truncate text-muted-foreground text-xs",
1986
- title: conversationTitle,
1987
- children: conversationTitle
1988
- }
1989
- )
1990
- ] }),
1991
- /* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-1", children: [
1992
- /* @__PURE__ */ jsxs2("div", { className: "flex items-center", role: "group", "aria-label": "Text size", children: [
2045
+ /* @__PURE__ */ jsxs2("div", { className: "flex shrink-0 items-center gap-0.5", children: [
1993
2046
  /* @__PURE__ */ jsx4(
1994
2047
  "button",
1995
2048
  {
2049
+ ref: historyButtonRef,
1996
2050
  type: "button",
1997
- onClick: font.decrease,
1998
- disabled: !font.canDecrease,
1999
- "aria-label": "Decrease text size",
2000
- className: "rounded p-1 text-muted-foreground hover:text-foreground disabled:opacity-40",
2001
- children: /* @__PURE__ */ jsx4(Minus, { className: "h-4 w-4" })
2051
+ onClick: openHistory,
2052
+ "aria-label": "Chat history",
2053
+ "aria-pressed": historyOpen,
2054
+ className: `rounded-md p-1.5 transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring ${historyOpen ? "bg-muted text-foreground" : "text-muted-foreground"}`,
2055
+ children: /* @__PURE__ */ jsx4(History, { className: "h-4 w-4" })
2002
2056
  }
2003
2057
  ),
2004
2058
  /* @__PURE__ */ jsx4(
2005
2059
  "button",
2006
2060
  {
2007
2061
  type: "button",
2008
- onClick: font.increase,
2009
- disabled: !font.canIncrease,
2010
- "aria-label": "Increase text size",
2011
- className: "rounded p-1 text-muted-foreground hover:text-foreground disabled:opacity-40",
2012
- children: /* @__PURE__ */ jsx4(Plus, { className: "h-4 w-4" })
2062
+ onClick: chat.reset,
2063
+ "aria-label": "New chat",
2064
+ title: "New chat",
2065
+ className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2066
+ children: /* @__PURE__ */ jsx4(MessageSquarePlus, { className: "h-4 w-4" })
2067
+ }
2068
+ ),
2069
+ /* @__PURE__ */ jsx4(
2070
+ "button",
2071
+ {
2072
+ type: "button",
2073
+ onClick: onClose,
2074
+ "aria-label": "Close assistant",
2075
+ className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
2076
+ children: /* @__PURE__ */ jsx4(X, { className: "h-4 w-4" })
2013
2077
  }
2014
2078
  )
2015
- ] }),
2016
- /* @__PURE__ */ jsx4(
2017
- "button",
2018
- {
2019
- type: "button",
2020
- onClick: openHistory,
2021
- "aria-label": "Chat history",
2022
- "aria-pressed": historyOpen,
2023
- className: "rounded p-1 text-muted-foreground hover:text-foreground",
2024
- children: /* @__PURE__ */ jsx4(History, { className: "h-4 w-4" })
2025
- }
2026
- ),
2027
- /* @__PURE__ */ jsx4(
2028
- "button",
2079
+ ] })
2080
+ ] }),
2081
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 px-3 pb-2", children: [
2082
+ pickerModels.length > 0 ? /* @__PURE__ */ jsx4(
2083
+ ModelPicker,
2029
2084
  {
2030
- type: "button",
2031
- onClick: chat.reset,
2032
- "aria-label": "New chat",
2033
- title: "New chat",
2034
- className: "rounded p-1 text-muted-foreground hover:text-foreground",
2035
- children: /* @__PURE__ */ jsx4(MessageSquarePlus, { className: "h-4 w-4" })
2085
+ variant: "pill",
2086
+ label: "Model",
2087
+ value: pickerValue,
2088
+ onChange: (id) => chat.setModel(nextModelSelection(id, models.default)),
2089
+ models: pickerModels
2036
2090
  }
2037
- ),
2038
- /* @__PURE__ */ jsx4(
2039
- "button",
2091
+ ) : /* @__PURE__ */ jsx4("span", { className: "px-1 text-muted-foreground text-xs", children: "Default model" }),
2092
+ /* @__PURE__ */ jsxs2(
2093
+ "div",
2040
2094
  {
2041
- type: "button",
2042
- onClick: onClose,
2043
- "aria-label": "Close assistant",
2044
- className: "rounded p-1 text-muted-foreground hover:text-foreground",
2045
- children: /* @__PURE__ */ jsx4(X, { className: "h-4 w-4" })
2095
+ className: "flex items-center overflow-hidden rounded-md border border-border",
2096
+ role: "group",
2097
+ "aria-label": "Text size",
2098
+ children: [
2099
+ /* @__PURE__ */ jsx4(
2100
+ "button",
2101
+ {
2102
+ type: "button",
2103
+ onClick: font.decrease,
2104
+ disabled: !font.canDecrease,
2105
+ "aria-label": "Decrease text size",
2106
+ className: "px-1.5 py-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:hover:bg-transparent",
2107
+ children: /* @__PURE__ */ jsx4(Minus, { className: "h-3.5 w-3.5" })
2108
+ }
2109
+ ),
2110
+ /* @__PURE__ */ jsx4(
2111
+ "button",
2112
+ {
2113
+ type: "button",
2114
+ onClick: font.increase,
2115
+ disabled: !font.canIncrease,
2116
+ "aria-label": "Increase text size",
2117
+ className: "border-border border-l px-1.5 py-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:hover:bg-transparent",
2118
+ children: /* @__PURE__ */ jsx4(Plus, { className: "h-3.5 w-3.5" })
2119
+ }
2120
+ )
2121
+ ]
2046
2122
  }
2047
2123
  )
2048
- ] })
2049
- ] }),
2050
- models.models.length > 0 && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 border-border border-b px-4 py-2", children: [
2051
- /* @__PURE__ */ jsx4(
2052
- "label",
2053
- {
2054
- htmlFor: "assistant-model",
2055
- className: "text-muted-foreground text-xs",
2056
- children: "Model"
2057
- }
2058
- ),
2059
- /* @__PURE__ */ jsxs2(
2060
- "select",
2124
+ ] }),
2125
+ historyOpen && /* @__PURE__ */ jsxs2(
2126
+ "div",
2061
2127
  {
2062
- id: "assistant-model",
2063
- value: chat.selectedModel ?? "",
2064
- onChange: (e) => chat.setModel(e.target.value || null),
2065
- className: "rounded border border-border bg-card px-2 py-1 text-foreground text-xs",
2128
+ ref: historyRef,
2129
+ role: "dialog",
2130
+ "aria-label": "Recent conversations",
2131
+ tabIndex: -1,
2132
+ className: "absolute inset-x-2 top-full z-30 mt-1 overflow-hidden rounded-lg border border-border bg-surface-container-highest shadow-xl ring-1 ring-black/5 focus:outline-none",
2066
2133
  children: [
2067
- /* @__PURE__ */ jsx4("option", { value: "", children: models.default ?? "Default" }),
2068
- models.models.map((m) => /* @__PURE__ */ jsx4("option", { value: m.slug, children: m.label }, m.slug))
2134
+ /* @__PURE__ */ jsx4("div", { className: "border-border border-b bg-surface-container-high px-3 py-2 font-medium text-[11px] text-muted-foreground uppercase tracking-wide", children: "Recent conversations" }),
2135
+ /* @__PURE__ */ jsx4("div", { className: "max-h-[min(18rem,50vh)] overflow-y-auto", children: threads.threads.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "px-3 py-3 text-muted-foreground text-xs", children: threads.loaded ? "No past conversations." : "Loading\u2026" }) : /* @__PURE__ */ jsx4("ul", { className: "py-1", children: threads.threads.map((t) => {
2136
+ const busyActive = state.threadId === t.id && state.status !== "idle";
2137
+ const active = state.threadId === t.id;
2138
+ return /* @__PURE__ */ jsxs2(
2139
+ "li",
2140
+ {
2141
+ className: `group flex items-center transition-colors hover:bg-muted/60 ${active ? "bg-primary/10" : ""}`,
2142
+ children: [
2143
+ /* @__PURE__ */ jsx4(
2144
+ "button",
2145
+ {
2146
+ type: "button",
2147
+ onClick: () => {
2148
+ chat.switchThread(t.id);
2149
+ setHistoryOpen(false);
2150
+ },
2151
+ className: `min-w-0 flex-1 truncate px-3 py-2 text-left text-xs ${active ? "font-medium text-foreground" : "text-foreground"}`,
2152
+ children: t.title ?? "Untitled conversation"
2153
+ }
2154
+ ),
2155
+ threads.canRemove && /* @__PURE__ */ jsx4(
2156
+ "button",
2157
+ {
2158
+ type: "button",
2159
+ onClick: () => void deleteThread(t.id),
2160
+ disabled: busyActive,
2161
+ "aria-label": "Delete conversation",
2162
+ title: busyActive ? "Can't delete while this conversation is active" : "Delete conversation",
2163
+ className: "shrink-0 p-2 text-muted-foreground opacity-0 transition hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 disabled:cursor-not-allowed disabled:opacity-30",
2164
+ children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3.5 w-3.5" })
2165
+ }
2166
+ )
2167
+ ]
2168
+ },
2169
+ t.id
2170
+ );
2171
+ }) }) })
2069
2172
  ]
2070
2173
  }
2071
2174
  )
2072
2175
  ] }),
2073
- historyOpen && /* @__PURE__ */ jsx4("div", { className: "max-h-48 overflow-y-auto border-border border-b", children: threads.threads.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "px-4 py-3 text-muted-foreground text-xs", children: threads.loaded ? "No past conversations." : "Loading\u2026" }) : /* @__PURE__ */ jsx4("ul", { children: threads.threads.map((t) => {
2074
- const busyActive = state.threadId === t.id && state.status !== "idle";
2075
- return /* @__PURE__ */ jsxs2("li", { className: "group flex items-center hover:bg-muted/50", children: [
2076
- /* @__PURE__ */ jsx4(
2077
- "button",
2078
- {
2079
- type: "button",
2080
- onClick: () => {
2081
- chat.switchThread(t.id);
2082
- setHistoryOpen(false);
2083
- },
2084
- className: "min-w-0 flex-1 truncate px-4 py-2 text-left text-foreground text-xs",
2085
- children: t.title ?? "Untitled conversation"
2086
- }
2087
- ),
2088
- threads.canRemove && /* @__PURE__ */ jsx4(
2089
- "button",
2090
- {
2091
- type: "button",
2092
- onClick: () => void deleteThread(t.id),
2093
- disabled: busyActive,
2094
- "aria-label": "Delete conversation",
2095
- title: busyActive ? "Can't delete while this conversation is active" : "Delete conversation",
2096
- className: "shrink-0 p-2 text-muted-foreground opacity-0 transition hover:text-destructive focus-visible:opacity-100 group-hover:opacity-100 disabled:cursor-not-allowed disabled:opacity-30",
2097
- children: /* @__PURE__ */ jsx4(Trash2, { className: "h-3.5 w-3.5" })
2098
- }
2099
- )
2100
- ] }, t.id);
2101
- }) }) }),
2102
2176
  /* @__PURE__ */ jsx4(
2103
2177
  "div",
2104
2178
  {
@@ -2106,7 +2180,7 @@ function AssistantPanel({
2106
2180
  "aria-label": "Conversation",
2107
2181
  "aria-live": "polite",
2108
2182
  className: "min-h-0 flex-1 overflow-y-auto px-2 py-3",
2109
- style: { fontSize: `${font.scale}rem` },
2183
+ style: { zoom: font.scale },
2110
2184
  children: renderTranscript ? renderTranscript({
2111
2185
  messages: state.messages,
2112
2186
  reasoning: state.reasoning,
@@ -2192,7 +2266,7 @@ import {
2192
2266
  createContext as createContext2,
2193
2267
  useCallback as useCallback4,
2194
2268
  useContext as useContext2,
2195
- useMemo,
2269
+ useMemo as useMemo2,
2196
2270
  useState as useState6
2197
2271
  } from "react";
2198
2272
  import { jsx as jsx5 } from "react/jsx-runtime";
@@ -2208,7 +2282,7 @@ function AssistantLauncherProvider({
2208
2282
  }, []);
2209
2283
  const closeAssistant = useCallback4(() => setOpen(false), []);
2210
2284
  const clearSeed = useCallback4(() => setSeed(null), []);
2211
- const value = useMemo(
2285
+ const value = useMemo2(
2212
2286
  () => ({ open, seed, openAssistant, closeAssistant, clearSeed }),
2213
2287
  [open, seed, openAssistant, closeAssistant, clearSeed]
2214
2288
  );
@@ -2327,7 +2401,7 @@ function AssistantDock({
2327
2401
  const dialogRef = useRef6(null);
2328
2402
  const returnFocusRef = useRef6(null);
2329
2403
  const wasOpenRef = useRef6(false);
2330
- useEffect5(() => {
2404
+ useEffect6(() => {
2331
2405
  if (!open) return;
2332
2406
  const onKeyDown = (e) => {
2333
2407
  if (e.key === "Escape") closeAssistant();
@@ -2335,7 +2409,7 @@ function AssistantDock({
2335
2409
  document.addEventListener("keydown", onKeyDown);
2336
2410
  return () => document.removeEventListener("keydown", onKeyDown);
2337
2411
  }, [open, closeAssistant]);
2338
- useEffect5(() => {
2412
+ useEffect6(() => {
2339
2413
  if (open) {
2340
2414
  if (!wasOpenRef.current && !returnFocusRef.current) {
2341
2415
  returnFocusRef.current = document.activeElement;
package/dist/globals.css CHANGED
@@ -317,6 +317,9 @@
317
317
  .inset-x-0 {
318
318
  inset-inline: calc(var(--spacing) * 0);
319
319
  }
320
+ .inset-x-2 {
321
+ inset-inline: calc(var(--spacing) * 2);
322
+ }
320
323
  .inset-y-0 {
321
324
  inset-block: calc(var(--spacing) * 0);
322
325
  }
@@ -759,6 +762,9 @@
759
762
  .h-\[640px\] {
760
763
  height: 640px;
761
764
  }
765
+ .h-\[720px\] {
766
+ height: 720px;
767
+ }
762
768
  .h-\[var\(--avatar-size\)\] {
763
769
  height: var(--avatar-size);
764
770
  }
@@ -822,6 +828,9 @@
822
828
  .max-h-\[440px\] {
823
829
  max-height: 440px;
824
830
  }
831
+ .max-h-\[min\(18rem\,50vh\)\] {
832
+ max-height: min(18rem, 50vh);
833
+ }
825
834
  .min-h-0 {
826
835
  min-height: calc(var(--spacing) * 0);
827
836
  }
@@ -1032,6 +1041,9 @@
1032
1041
  .w-\[420px\] {
1033
1042
  width: 420px;
1034
1043
  }
1044
+ .w-\[460px\] {
1045
+ width: 460px;
1046
+ }
1035
1047
  .w-\[480px\] {
1036
1048
  width: 480px;
1037
1049
  }
@@ -3458,6 +3470,12 @@
3458
3470
  .ring-\[var\(--md3-outline-variant\)\] {
3459
3471
  --tw-ring-color: var(--md3-outline-variant);
3460
3472
  }
3473
+ .ring-black\/5 {
3474
+ --tw-ring-color: color-mix(in srgb, #000 5%, transparent);
3475
+ @supports (color: color-mix(in lab, red, red)) {
3476
+ --tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent);
3477
+ }
3478
+ }
3461
3479
  .ring-border {
3462
3480
  --tw-ring-color: var(--color-border);
3463
3481
  }
@@ -4206,6 +4224,16 @@
4206
4224
  }
4207
4225
  }
4208
4226
  }
4227
+ .hover\:bg-muted\/60 {
4228
+ &:hover {
4229
+ @media (hover: hover) {
4230
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4231
+ @supports (color: color-mix(in lab, red, red)) {
4232
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4233
+ }
4234
+ }
4235
+ }
4236
+ }
4209
4237
  .hover\:bg-muted\/80 {
4210
4238
  &:hover {
4211
4239
  @media (hover: hover) {
@@ -4773,6 +4801,15 @@
4773
4801
  opacity: 60%;
4774
4802
  }
4775
4803
  }
4804
+ .disabled\:hover\:bg-transparent {
4805
+ &:disabled {
4806
+ &:hover {
4807
+ @media (hover: hover) {
4808
+ background-color: transparent;
4809
+ }
4810
+ }
4811
+ }
4812
+ }
4776
4813
  .data-\[disabled\]\:pointer-events-none {
4777
4814
  &[data-disabled] {
4778
4815
  pointer-events: none;
package/dist/styles.css CHANGED
@@ -317,6 +317,9 @@
317
317
  .inset-x-0 {
318
318
  inset-inline: calc(var(--spacing) * 0);
319
319
  }
320
+ .inset-x-2 {
321
+ inset-inline: calc(var(--spacing) * 2);
322
+ }
320
323
  .inset-y-0 {
321
324
  inset-block: calc(var(--spacing) * 0);
322
325
  }
@@ -759,6 +762,9 @@
759
762
  .h-\[640px\] {
760
763
  height: 640px;
761
764
  }
765
+ .h-\[720px\] {
766
+ height: 720px;
767
+ }
762
768
  .h-\[var\(--avatar-size\)\] {
763
769
  height: var(--avatar-size);
764
770
  }
@@ -822,6 +828,9 @@
822
828
  .max-h-\[440px\] {
823
829
  max-height: 440px;
824
830
  }
831
+ .max-h-\[min\(18rem\,50vh\)\] {
832
+ max-height: min(18rem, 50vh);
833
+ }
825
834
  .min-h-0 {
826
835
  min-height: calc(var(--spacing) * 0);
827
836
  }
@@ -1032,6 +1041,9 @@
1032
1041
  .w-\[420px\] {
1033
1042
  width: 420px;
1034
1043
  }
1044
+ .w-\[460px\] {
1045
+ width: 460px;
1046
+ }
1035
1047
  .w-\[480px\] {
1036
1048
  width: 480px;
1037
1049
  }
@@ -3458,6 +3470,12 @@
3458
3470
  .ring-\[var\(--md3-outline-variant\)\] {
3459
3471
  --tw-ring-color: var(--md3-outline-variant);
3460
3472
  }
3473
+ .ring-black\/5 {
3474
+ --tw-ring-color: color-mix(in srgb, #000 5%, transparent);
3475
+ @supports (color: color-mix(in lab, red, red)) {
3476
+ --tw-ring-color: color-mix(in oklab, var(--color-black) 5%, transparent);
3477
+ }
3478
+ }
3461
3479
  .ring-border {
3462
3480
  --tw-ring-color: var(--color-border);
3463
3481
  }
@@ -4206,6 +4224,16 @@
4206
4224
  }
4207
4225
  }
4208
4226
  }
4227
+ .hover\:bg-muted\/60 {
4228
+ &:hover {
4229
+ @media (hover: hover) {
4230
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4231
+ @supports (color: color-mix(in lab, red, red)) {
4232
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4233
+ }
4234
+ }
4235
+ }
4236
+ }
4209
4237
  .hover\:bg-muted\/80 {
4210
4238
  &:hover {
4211
4239
  @media (hover: hover) {
@@ -4773,6 +4801,15 @@
4773
4801
  opacity: 60%;
4774
4802
  }
4775
4803
  }
4804
+ .disabled\:hover\:bg-transparent {
4805
+ &:disabled {
4806
+ &:hover {
4807
+ @media (hover: hover) {
4808
+ background-color: transparent;
4809
+ }
4810
+ }
4811
+ }
4812
+ }
4776
4813
  .data-\[disabled\]\:pointer-events-none {
4777
4814
  &[data-disabled] {
4778
4815
  pointer-events: none;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",