@upstash/react-redis-browser 0.2.7 → 0.2.9

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/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/databrowser/index.tsx
2
- import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef6 } from "react";
2
+ import { useEffect as useEffect14, useMemo as useMemo9, useRef as useRef7 } from "react";
3
3
 
4
4
  // src/dark-mode-context.tsx
5
5
  import { createContext, useContext } from "react";
@@ -260,7 +260,7 @@ var DatabrowserProvider = ({
260
260
  removeItem: () => {
261
261
  }
262
262
  },
263
- version: 2,
263
+ version: 3,
264
264
  // @ts-expect-error Reset the store for < v1
265
265
  migrate: (originalState, version) => {
266
266
  const state = originalState;
@@ -273,6 +273,21 @@ var DatabrowserProvider = ({
273
273
  tabs: state.tabs.map(([id, data]) => [id, { ...data, id }])
274
274
  };
275
275
  }
276
+ if (version === 2) {
277
+ return {
278
+ ...state,
279
+ tabs: state.tabs.map(([id, data]) => {
280
+ const oldData = data;
281
+ return [
282
+ id,
283
+ {
284
+ ...data,
285
+ selectedKeys: oldData.selectedKey ? [oldData.selectedKey] : []
286
+ }
287
+ ];
288
+ })
289
+ };
290
+ }
276
291
  return state;
277
292
  }
278
293
  })
@@ -302,7 +317,7 @@ var storeCreator = (set, get) => ({
302
317
  const id = crypto.randomUUID();
303
318
  const newTabData = {
304
319
  id,
305
- selectedKey: void 0,
320
+ selectedKeys: [],
306
321
  search: { key: "", type: void 0 },
307
322
  pinned: false
308
323
  };
@@ -395,16 +410,19 @@ var storeCreator = (set, get) => ({
395
410
  selectTab: (id) => {
396
411
  set({ selectedTab: id });
397
412
  },
398
- getSelectedKey: (tabId) => {
399
- return get().tabs.find(([id]) => id === tabId)?.[1]?.selectedKey;
413
+ getSelectedKeys: (tabId) => {
414
+ return get().tabs.find(([id]) => id === tabId)?.[1]?.selectedKeys ?? [];
400
415
  },
401
416
  setSelectedKey: (tabId, key) => {
417
+ get().setSelectedKeys(tabId, key ? [key] : []);
418
+ },
419
+ setSelectedKeys: (tabId, keys) => {
402
420
  set((old) => {
403
421
  const tabIndex = old.tabs.findIndex(([id]) => id === tabId);
404
422
  if (tabIndex === -1) return old;
405
423
  const newTabs = [...old.tabs];
406
424
  const [, tabData] = newTabs[tabIndex];
407
- newTabs[tabIndex] = [tabId, { ...tabData, selectedKey: key, selectedListItem: void 0 }];
425
+ newTabs[tabIndex] = [tabId, { ...tabData, selectedKeys: keys, selectedListItem: void 0 }];
408
426
  return { ...old, tabs: newTabs };
409
427
  });
410
428
  },
@@ -485,6 +503,7 @@ var useTab = () => {
485
503
  selectedTab,
486
504
  tabs,
487
505
  setSelectedKey,
506
+ setSelectedKeys,
488
507
  setSelectedListItem,
489
508
  setSearch,
490
509
  setSearchKey,
@@ -497,11 +516,14 @@ var useTab = () => {
497
516
  return useMemo3(
498
517
  () => ({
499
518
  active: selectedTab === tabId,
500
- selectedKey: tabData.selectedKey,
519
+ selectedKey: tabData.selectedKeys[0],
520
+ // Backwards compatibility - first selected key
521
+ selectedKeys: tabData.selectedKeys,
501
522
  selectedListItem: tabData.selectedListItem,
502
523
  search: tabData.search,
503
524
  pinned: tabData.pinned,
504
525
  setSelectedKey: (key) => setSelectedKey(tabId, key),
526
+ setSelectedKeys: (keys) => setSelectedKeys(tabId, keys),
505
527
  setSelectedListItem: (item) => setSelectedListItem(tabId, item),
506
528
  setSearch: (search) => setSearch(tabId, search),
507
529
  setSearchKey: (key) => setSearchKey(tabId, key),
@@ -3836,8 +3858,8 @@ var HeaderTTLBadge = ({ dataKey }) => {
3836
3858
  }
3837
3859
  );
3838
3860
  };
3839
- var Badge = ({ children, label }) => /* @__PURE__ */ jsxs3("div", { className: "flex h-6 items-center gap-0.5 rounded-md bg-white px-2 text-xs text-zinc-700", children: [
3840
- /* @__PURE__ */ jsx11("span", { className: "text-zinc-500", children: label }),
3861
+ var Badge = ({ children, label }) => /* @__PURE__ */ jsxs3("div", { className: "flex h-6 items-center gap-0.5 rounded-md bg-white px-2 text-xs text-zinc-700 dark:bg-zinc-200", children: [
3862
+ /* @__PURE__ */ jsx11("span", { className: "text-zinc-500 dark:text-zinc-600", children: label }),
3841
3863
  /* @__PURE__ */ jsx11("span", { className: "font-medium", children })
3842
3864
  ] });
3843
3865
 
@@ -4441,16 +4463,20 @@ function DeleteAlertDialog({
4441
4463
  onDeleteConfirm,
4442
4464
  open,
4443
4465
  onOpenChange,
4444
- deletionType
4466
+ deletionType,
4467
+ count: count2 = 1
4445
4468
  }) {
4469
+ const isPlural = count2 > 1;
4470
+ const itemLabel = deletionType === "item" ? "Item" : "Key";
4471
+ const itemsLabel = deletionType === "item" ? "Items" : "Keys";
4446
4472
  return /* @__PURE__ */ jsxs10(AlertDialog, { open, onOpenChange, children: [
4447
4473
  children && /* @__PURE__ */ jsx20(AlertDialogTrigger, { asChild: true, children }),
4448
4474
  /* @__PURE__ */ jsxs10(AlertDialogContent, { children: [
4449
4475
  /* @__PURE__ */ jsxs10(AlertDialogHeader, { children: [
4450
- /* @__PURE__ */ jsx20(AlertDialogTitle, { children: deletionType === "item" ? "Delete Item" : "Delete Key" }),
4476
+ /* @__PURE__ */ jsx20(AlertDialogTitle, { children: isPlural ? `Delete ${count2} ${itemsLabel}` : `Delete ${itemLabel}` }),
4451
4477
  /* @__PURE__ */ jsxs10(AlertDialogDescription, { className: "mt-5", children: [
4452
- "Are you sure you want to delete this ",
4453
- deletionType,
4478
+ "Are you sure you want to delete ",
4479
+ isPlural ? `these ${count2} ${deletionType}s` : `this ${deletionType}`,
4454
4480
  "?",
4455
4481
  /* @__PURE__ */ jsx20("br", {}),
4456
4482
  "This action cannot be undone."
@@ -4696,6 +4722,36 @@ var InfiniteScroll = ({
4696
4722
  // src/components/databrowser/components/display/display-header.tsx
4697
4723
  import { IconPlus } from "@tabler/icons-react";
4698
4724
 
4725
+ // src/components/ui/tooltip.tsx
4726
+ import * as React10 from "react";
4727
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4728
+ import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
4729
+ var Tooltip = TooltipPrimitive.Root;
4730
+ var TooltipTrigger = TooltipPrimitive.Trigger;
4731
+ var TooltipContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx24(TooltipPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx24(
4732
+ TooltipPrimitive.Content,
4733
+ {
4734
+ ref,
4735
+ sideOffset,
4736
+ className: cn(
4737
+ "z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4738
+ className
4739
+ ),
4740
+ ...props
4741
+ }
4742
+ ) }));
4743
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
4744
+ var SimpleTooltip = ({
4745
+ content,
4746
+ children
4747
+ }) => {
4748
+ if (!content) return /* @__PURE__ */ jsx24(Fragment3, { children });
4749
+ return /* @__PURE__ */ jsxs14(Tooltip, { delayDuration: 400, children: [
4750
+ /* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24("div", { children }) }),
4751
+ /* @__PURE__ */ jsx24(TooltipContent, { side: "top", children: content })
4752
+ ] });
4753
+ };
4754
+
4699
4755
  // src/types/index.ts
4700
4756
  var DATA_TYPES = ["string", "list", "hash", "set", "zset", "json", "stream"];
4701
4757
  var DATA_TYPE_NAMES = {
@@ -4717,15 +4773,15 @@ import {
4717
4773
  IconList,
4718
4774
  IconQuote
4719
4775
  } from "@tabler/icons-react";
4720
- import { jsx as jsx24 } from "react/jsx-runtime";
4776
+ import { jsx as jsx25 } from "react/jsx-runtime";
4721
4777
  var iconsMap = {
4722
- string: /* @__PURE__ */ jsx24(IconQuote, { size: 15, stroke: 1.2 }),
4723
- set: /* @__PURE__ */ jsx24(IconLayersIntersect, { size: 15, stroke: 1.2 }),
4724
- hash: /* @__PURE__ */ jsx24(IconHash, { size: 15, stroke: 1.2 }),
4725
- json: /* @__PURE__ */ jsx24(IconCodeDots, { size: 15, stroke: 1.2 }),
4726
- zset: /* @__PURE__ */ jsx24(IconArrowsSort, { size: 15, stroke: 1.2 }),
4727
- list: /* @__PURE__ */ jsx24(IconList, { size: 15, stroke: 1.2 }),
4728
- stream: /* @__PURE__ */ jsx24(IconList, { size: 15, stroke: 1.2 })
4778
+ string: /* @__PURE__ */ jsx25(IconQuote, { size: 15, stroke: 1.2 }),
4779
+ set: /* @__PURE__ */ jsx25(IconLayersIntersect, { size: 15, stroke: 1.2 }),
4780
+ hash: /* @__PURE__ */ jsx25(IconHash, { size: 15, stroke: 1.2 }),
4781
+ json: /* @__PURE__ */ jsx25(IconCodeDots, { size: 15, stroke: 1.2 }),
4782
+ zset: /* @__PURE__ */ jsx25(IconArrowsSort, { size: 15, stroke: 1.2 }),
4783
+ list: /* @__PURE__ */ jsx25(IconList, { size: 15, stroke: 1.2 }),
4784
+ stream: /* @__PURE__ */ jsx25(IconList, { size: 15, stroke: 1.2 })
4729
4785
  };
4730
4786
  var tagVariants = cva("inline-flex shrink-0 items-center rounded-md justify-center", {
4731
4787
  variants: {
@@ -4749,20 +4805,20 @@ var tagVariants = cva("inline-flex shrink-0 items-center rounded-md justify-cent
4749
4805
  }
4750
4806
  });
4751
4807
  function TypeTag({ className, variant, type }) {
4752
- return /* @__PURE__ */ jsx24("span", { className: cn(tagVariants({ variant, type, className })), children: type === "icon" ? iconsMap[variant] : DATA_TYPE_NAMES[variant] });
4808
+ return /* @__PURE__ */ jsx25("span", { className: cn(tagVariants({ variant, type, className })), children: type === "icon" ? iconsMap[variant] : DATA_TYPE_NAMES[variant] });
4753
4809
  }
4754
4810
 
4755
4811
  // src/components/databrowser/components/display/key-actions.tsx
4756
4812
  import { IconDotsVertical } from "@tabler/icons-react";
4757
4813
 
4758
4814
  // src/components/ui/dropdown-menu.tsx
4759
- import * as React10 from "react";
4815
+ import * as React11 from "react";
4760
4816
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
4761
4817
  import { CheckIcon as CheckIcon2, ChevronRightIcon as ChevronRightIcon2, DotFilledIcon as DotFilledIcon2 } from "@radix-ui/react-icons";
4762
- import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
4818
+ import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
4763
4819
  var DropdownMenu = DropdownMenuPrimitive.Root;
4764
4820
  var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
4765
- var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
4821
+ var DropdownMenuSubTrigger = React11.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs15(
4766
4822
  DropdownMenuPrimitive.SubTrigger,
4767
4823
  {
4768
4824
  ref,
@@ -4774,12 +4830,12 @@ var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, .
4774
4830
  ...props,
4775
4831
  children: [
4776
4832
  children,
4777
- /* @__PURE__ */ jsx25(ChevronRightIcon2, { className: "ml-auto" })
4833
+ /* @__PURE__ */ jsx26(ChevronRightIcon2, { className: "ml-auto" })
4778
4834
  ]
4779
4835
  }
4780
4836
  ));
4781
4837
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
4782
- var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4838
+ var DropdownMenuSubContent = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4783
4839
  DropdownMenuPrimitive.SubContent,
4784
4840
  {
4785
4841
  ref,
@@ -4791,7 +4847,7 @@ var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) =
4791
4847
  }
4792
4848
  ));
4793
4849
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
4794
- var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx25(DropdownMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx25(
4850
+ var DropdownMenuContent = React11.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx26(DropdownMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx26(
4795
4851
  DropdownMenuPrimitive.Content,
4796
4852
  {
4797
4853
  ref,
@@ -4805,12 +4861,12 @@ var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...pr
4805
4861
  }
4806
4862
  ) }));
4807
4863
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
4808
- var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx25(
4864
+ var DropdownMenuItem = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx26(
4809
4865
  DropdownMenuPrimitive.Item,
4810
4866
  {
4811
4867
  ref,
4812
4868
  className: cn(
4813
- "data-[disabled]:opacity-50[&>svg]:size-4 relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none [&>svg]:shrink-0",
4869
+ "data-[disabled]:opacity-50[&>svg]:size-4 relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none [&>svg]:shrink-0",
4814
4870
  inset && "pl-8",
4815
4871
  className
4816
4872
  ),
@@ -4818,7 +4874,7 @@ var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref)
4818
4874
  }
4819
4875
  ));
4820
4876
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
4821
- var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs14(
4877
+ var DropdownMenuCheckboxItem = React11.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs15(
4822
4878
  DropdownMenuPrimitive.CheckboxItem,
4823
4879
  {
4824
4880
  ref,
@@ -4829,13 +4885,13 @@ var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checke
4829
4885
  checked,
4830
4886
  ...props,
4831
4887
  children: [
4832
- /* @__PURE__ */ jsx25("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx25(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx25(CheckIcon2, { className: "h-4 w-4" }) }) }),
4888
+ /* @__PURE__ */ jsx26("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx26(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx26(CheckIcon2, { className: "h-4 w-4" }) }) }),
4833
4889
  children
4834
4890
  ]
4835
4891
  }
4836
4892
  ));
4837
4893
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
4838
- var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs14(
4894
+ var DropdownMenuRadioItem = React11.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs15(
4839
4895
  DropdownMenuPrimitive.RadioItem,
4840
4896
  {
4841
4897
  ref,
@@ -4845,13 +4901,13 @@ var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props
4845
4901
  ),
4846
4902
  ...props,
4847
4903
  children: [
4848
- /* @__PURE__ */ jsx25("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx25(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx25(DotFilledIcon2, { className: "h-2 w-2 fill-current" }) }) }),
4904
+ /* @__PURE__ */ jsx26("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx26(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx26(DotFilledIcon2, { className: "h-2 w-2 fill-current" }) }) }),
4849
4905
  children
4850
4906
  ]
4851
4907
  }
4852
4908
  ));
4853
4909
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
4854
- var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx25(
4910
+ var DropdownMenuLabel = React11.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx26(
4855
4911
  DropdownMenuPrimitive.Label,
4856
4912
  {
4857
4913
  ref,
@@ -4860,7 +4916,7 @@ var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref)
4860
4916
  }
4861
4917
  ));
4862
4918
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
4863
- var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4919
+ var DropdownMenuSeparator = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
4864
4920
  DropdownMenuPrimitive.Separator,
4865
4921
  {
4866
4922
  ref,
@@ -4870,18 +4926,18 @@ var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) =>
4870
4926
  ));
4871
4927
  DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
4872
4928
  var DropdownMenuShortcut = ({ className, ...props }) => {
4873
- return /* @__PURE__ */ jsx25("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
4929
+ return /* @__PURE__ */ jsx26("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
4874
4930
  };
4875
4931
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
4876
4932
 
4877
4933
  // src/components/databrowser/components/display/key-actions.tsx
4878
- import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
4934
+ import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
4879
4935
  function KeyActions({ dataKey, content }) {
4880
4936
  const { mutateAsync: deleteKey } = useDeleteKey();
4881
- return /* @__PURE__ */ jsxs15(DropdownMenu, { modal: false, children: [
4882
- /* @__PURE__ */ jsx26(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(Button, { size: "icon-sm", "aria-label": "Key actions", children: /* @__PURE__ */ jsx26(IconDotsVertical, { className: "size-4 text-zinc-500" }) }) }),
4883
- /* @__PURE__ */ jsxs15(DropdownMenuContent, { className: "", align: "end", children: [
4884
- content && /* @__PURE__ */ jsx26(
4937
+ return /* @__PURE__ */ jsxs16(DropdownMenu, { modal: false, children: [
4938
+ /* @__PURE__ */ jsx27(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx27(Button, { size: "icon-sm", "aria-label": "Key actions", children: /* @__PURE__ */ jsx27(IconDotsVertical, { className: "size-4 text-zinc-500 dark:text-zinc-600" }) }) }),
4939
+ /* @__PURE__ */ jsxs16(DropdownMenuContent, { className: "", align: "end", children: [
4940
+ content && /* @__PURE__ */ jsx27(
4885
4941
  DropdownMenuItem,
4886
4942
  {
4887
4943
  onClick: () => {
@@ -4893,7 +4949,7 @@ function KeyActions({ dataKey, content }) {
4893
4949
  children: "Copy content"
4894
4950
  }
4895
4951
  ),
4896
- /* @__PURE__ */ jsx26(
4952
+ /* @__PURE__ */ jsx27(
4897
4953
  DropdownMenuItem,
4898
4954
  {
4899
4955
  onClick: () => {
@@ -4902,12 +4958,12 @@ function KeyActions({ dataKey, content }) {
4902
4958
  children: "Copy key"
4903
4959
  }
4904
4960
  ),
4905
- /* @__PURE__ */ jsx26(
4961
+ /* @__PURE__ */ jsx27(
4906
4962
  DeleteAlertDialog,
4907
4963
  {
4908
4964
  deletionType: "key",
4909
4965
  onDeleteConfirm: async () => await deleteKey(dataKey),
4910
- children: /* @__PURE__ */ jsx26(
4966
+ children: /* @__PURE__ */ jsx27(
4911
4967
  DropdownMenuItem,
4912
4968
  {
4913
4969
  className: "text-red-500 focus:bg-red-500 focus:text-white",
@@ -4922,7 +4978,7 @@ function KeyActions({ dataKey, content }) {
4922
4978
  }
4923
4979
 
4924
4980
  // src/components/databrowser/components/display/display-header.tsx
4925
- import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
4981
+ import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
4926
4982
  var DisplayHeader = ({
4927
4983
  dataKey,
4928
4984
  type,
@@ -4932,19 +4988,19 @@ var DisplayHeader = ({
4932
4988
  const handleAddItem = () => {
4933
4989
  setSelectedListItem({ key: type === "stream" ? "*" : "", isNew: true });
4934
4990
  };
4935
- return /* @__PURE__ */ jsxs16("div", { className: "rounded-lg bg-zinc-100", children: [
4936
- /* @__PURE__ */ jsxs16("div", { className: "flex min-h-10 items-center justify-between gap-4", children: [
4937
- /* @__PURE__ */ jsx27("h2", { className: "grow truncate text-base", children: dataKey.trim() === "" ? /* @__PURE__ */ jsx27("span", { className: "ml-1 text-zinc-500", children: "(Empty Key)" }) : /* @__PURE__ */ jsx27("span", { className: "font-semibold", children: dataKey }) }),
4938
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1", children: [
4939
- type !== "string" && type !== "json" && /* @__PURE__ */ jsx27(Button, { onClick: handleAddItem, size: "icon-sm", "aria-label": "Add item", children: /* @__PURE__ */ jsx27(IconPlus, { className: "size-4 text-zinc-500" }) }),
4940
- /* @__PURE__ */ jsx27(KeyActions, { dataKey, content })
4991
+ return /* @__PURE__ */ jsxs17("div", { className: "rounded-lg bg-zinc-100", children: [
4992
+ /* @__PURE__ */ jsxs17("div", { className: "flex min-h-10 items-center justify-between gap-4", children: [
4993
+ /* @__PURE__ */ jsx28("h2", { className: "grow truncate text-base", children: dataKey.trim() === "" ? /* @__PURE__ */ jsx28("span", { className: "ml-1 text-zinc-500", children: "(Empty Key)" }) : /* @__PURE__ */ jsx28("span", { className: "font-semibold", children: dataKey }) }),
4994
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
4995
+ type !== "string" && type !== "json" && /* @__PURE__ */ jsx28(SimpleTooltip, { content: "Add item", children: /* @__PURE__ */ jsx28(Button, { onClick: handleAddItem, size: "icon-sm", "aria-label": "Add item", children: /* @__PURE__ */ jsx28(IconPlus, { className: "size-4 text-zinc-500 dark:text-zinc-600" }) }) }),
4996
+ /* @__PURE__ */ jsx28(KeyActions, { dataKey, content })
4941
4997
  ] })
4942
4998
  ] }),
4943
- /* @__PURE__ */ jsxs16("div", { className: "flex h-10 flex-wrap items-center gap-1.5", children: [
4944
- /* @__PURE__ */ jsx27(TypeTag, { variant: type, type: "badge" }),
4945
- /* @__PURE__ */ jsx27(SizeBadge, { dataKey }),
4946
- /* @__PURE__ */ jsx27(LengthBadge, { dataKey, type, content }),
4947
- /* @__PURE__ */ jsx27(HeaderTTLBadge, { dataKey })
4999
+ /* @__PURE__ */ jsxs17("div", { className: "flex h-10 flex-wrap items-center gap-1.5", children: [
5000
+ /* @__PURE__ */ jsx28(TypeTag, { variant: type, type: "badge" }),
5001
+ /* @__PURE__ */ jsx28(SizeBadge, { dataKey }),
5002
+ /* @__PURE__ */ jsx28(LengthBadge, { dataKey, type, content }),
5003
+ /* @__PURE__ */ jsx28(HeaderTTLBadge, { dataKey })
4948
5004
  ] })
4949
5005
  ] });
4950
5006
  };
@@ -4952,36 +5008,6 @@ var DisplayHeader = ({
4952
5008
  // src/components/databrowser/components/display/display-list-edit.tsx
4953
5009
  import { Controller as Controller2, FormProvider, useForm as useForm2, useFormContext } from "react-hook-form";
4954
5010
 
4955
- // src/components/ui/tooltip.tsx
4956
- import * as React11 from "react";
4957
- import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4958
- import { Fragment as Fragment3, jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
4959
- var Tooltip = TooltipPrimitive.Root;
4960
- var TooltipTrigger = TooltipPrimitive.Trigger;
4961
- var TooltipContent = React11.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx28(TooltipPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ jsx28(
4962
- TooltipPrimitive.Content,
4963
- {
4964
- ref,
4965
- sideOffset,
4966
- className: cn(
4967
- "z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4968
- className
4969
- ),
4970
- ...props
4971
- }
4972
- ) }));
4973
- TooltipContent.displayName = TooltipPrimitive.Content.displayName;
4974
- var SimpleTooltip = ({
4975
- content,
4976
- children
4977
- }) => {
4978
- if (!content) return /* @__PURE__ */ jsx28(Fragment3, { children });
4979
- return /* @__PURE__ */ jsxs17(Tooltip, { delayDuration: 400, children: [
4980
- /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28("div", { children }) }),
4981
- /* @__PURE__ */ jsx28(TooltipContent, { side: "top", children: content })
4982
- ] });
4983
- };
4984
-
4985
5011
  // src/components/databrowser/hooks/use-fetch-hash-ttl.ts
4986
5012
  import { useQuery as useQuery7 } from "@tanstack/react-query";
4987
5013
  var FETCH_HASH_FIELD_TTLS_QUERY_KEY = "fetch-hash-field-ttls";
@@ -5179,7 +5205,7 @@ var CustomEditor = ({
5179
5205
  return /* @__PURE__ */ jsxs19(
5180
5206
  "div",
5181
5207
  {
5182
- className: cn("group/editor relative", height === void 0 && "h-full p-2"),
5208
+ className: cn("group/editor relative", height === void 0 && "h-full"),
5183
5209
  style: { height },
5184
5210
  children: [
5185
5211
  isTest ? /* @__PURE__ */ jsx32("input", { "aria-label": "editor", value, onChange: (e) => onChange(e.target.value) }) : editor,
@@ -5306,24 +5332,15 @@ var ListEditForm = ({
5306
5332
  });
5307
5333
  setSelectedListItem(void 0);
5308
5334
  });
5309
- return /* @__PURE__ */ jsx34(FormProvider, { ...form, children: /* @__PURE__ */ jsxs20("form", { onSubmit, className: "flex flex-col gap-2", children: [
5335
+ return /* @__PURE__ */ jsx34(FormProvider, { ...form, children: /* @__PURE__ */ jsxs20("form", { onSubmit, className: "flex h-full flex-col gap-2", children: [
5310
5336
  /* @__PURE__ */ jsxs20("div", { className: "flex grow flex-col gap-2", children: [
5311
- type !== "list" && /* @__PURE__ */ jsx34(
5312
- FormItem,
5313
- {
5314
- readOnly: type === "stream",
5315
- name: "key",
5316
- height: type === "set" ? 250 : 100,
5317
- label: keyLabel,
5318
- data: itemKey
5319
- }
5320
- ),
5321
- type === "zset" ? /* @__PURE__ */ jsx34(NumberFormItem, { name: "value", label: valueLabel }) : type !== "set" && /* @__PURE__ */ jsx34(
5337
+ type === "zset" && /* @__PURE__ */ jsx34(NumberFormItem, { name: "value", label: valueLabel }),
5338
+ type !== "list" && /* @__PURE__ */ jsx34(FormItem, { readOnly: type === "stream", name: "key", label: keyLabel, data: itemKey }),
5339
+ type !== "set" && type !== "zset" && /* @__PURE__ */ jsx34(
5322
5340
  FormItem,
5323
5341
  {
5324
5342
  readOnly: type === "stream",
5325
5343
  name: "value",
5326
- height: type === "list" ? 250 : 100,
5327
5344
  label: valueLabel,
5328
5345
  data: itemValue ?? ""
5329
5346
  }
@@ -5405,14 +5422,23 @@ var FormItem = ({
5405
5422
  readOnly,
5406
5423
  data
5407
5424
  });
5408
- return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
5425
+ return /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-col gap-1", !height && "h-full"), children: [
5409
5426
  /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1 text-xs", children: [
5410
5427
  /* @__PURE__ */ jsx34("span", { className: "font-medium text-zinc-700", children: label }),
5411
5428
  " ",
5412
5429
  /* @__PURE__ */ jsx34("span", { className: "text-zinc-300", children: "/" }),
5413
5430
  selector
5414
5431
  ] }),
5415
- /* @__PURE__ */ jsx34("div", { className: "overflow-hidden rounded-md border border-zinc-300 bg-white p-2 shadow-sm", children: editor })
5432
+ /* @__PURE__ */ jsx34(
5433
+ "div",
5434
+ {
5435
+ className: cn(
5436
+ "overflow-hidden rounded-md border border-zinc-300 bg-white p-2 shadow-sm",
5437
+ !height && "h-full"
5438
+ ),
5439
+ children: editor
5440
+ }
5441
+ )
5416
5442
  ] });
5417
5443
  };
5418
5444
 
@@ -5473,7 +5499,9 @@ var ListItems = ({
5473
5499
  onClick: () => {
5474
5500
  setSelectedListItem({ key });
5475
5501
  },
5476
- className: cn("h-10 border-b border-b-zinc-100 transition-colors hover:bg-zinc-100"),
5502
+ className: cn(
5503
+ "h-10 border-b border-b-zinc-100 transition-colors hover:bg-zinc-100 dark:border-b-zinc-200 dark:hover:bg-zinc-200"
5504
+ ),
5477
5505
  children: [
5478
5506
  /* @__PURE__ */ jsx36(
5479
5507
  "td",
@@ -5495,7 +5523,7 @@ var ListItems = ({
5495
5523
  type !== "stream" && /* @__PURE__ */ jsx36(
5496
5524
  "td",
5497
5525
  {
5498
- className: "w-0 min-w-0 p-0",
5526
+ className: "w-0 min-w-0 p-0 pr-2",
5499
5527
  onClick: (e) => {
5500
5528
  e.stopPropagation();
5501
5529
  },
@@ -5566,7 +5594,7 @@ var EditorDisplayForm = ({
5566
5594
  return /* @__PURE__ */ jsxs22(Fragment6, { children: [
5567
5595
  /* @__PURE__ */ jsxs22("div", { className: "flex grow flex-col gap-1", children: [
5568
5596
  /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center gap-2", children: type === "json" ? /* @__PURE__ */ jsx37("div", {}) : selector }),
5569
- /* @__PURE__ */ jsx37("div", { className: "grow rounded-md border border-zinc-300 bg-white p-1 dark:!bg-[#192321]", children: editor })
5597
+ /* @__PURE__ */ jsx37("div", { className: "grow rounded-md border border-zinc-300 bg-white p-2", children: editor })
5570
5598
  ] }),
5571
5599
  /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center gap-2", children: /* @__PURE__ */ jsxs22("div", { className: "ml-auto flex gap-2", children: [
5572
5600
  form.formState.isDirty && /* @__PURE__ */ jsx37(Button, { onClick: handleCancel, children: "Cancel" }),
@@ -5594,9 +5622,6 @@ var DataDisplay = () => {
5594
5622
  return /* @__PURE__ */ jsx38("div", { className: "h-full p-4", children: !selectedKey ? /* @__PURE__ */ jsx38("div", {}) : !type ? query.isLoading ? /* @__PURE__ */ jsx38("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsx38("span", { className: "text-zinc-500", children: "Loading..." }) }) : /* @__PURE__ */ jsx38("div", {}) : /* @__PURE__ */ jsx38(Fragment7, { children: type === "string" || type === "json" ? /* @__PURE__ */ jsx38(EditorDisplay, { dataKey: selectedKey, type }) : /* @__PURE__ */ jsx38(ListDisplay, { dataKey: selectedKey, type }) }) });
5595
5623
  };
5596
5624
 
5597
- // src/components/databrowser/components/sidebar/index.tsx
5598
- import { IconRefresh } from "@tabler/icons-react";
5599
-
5600
5625
  // src/components/databrowser/components/add-key-modal.tsx
5601
5626
  import { useState as useState9 } from "react";
5602
5627
  import { DialogDescription as DialogDescription2 } from "@radix-ui/react-dialog";
@@ -5737,7 +5762,7 @@ function AddKeyModal() {
5737
5762
  setOpen(open2);
5738
5763
  },
5739
5764
  children: [
5740
- /* @__PURE__ */ jsx40(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx40(Button, { variant: "primary", size: "icon-sm", "aria-label": "Add key", children: /* @__PURE__ */ jsx40(PlusIcon, { className: "size-4" }) }) }),
5765
+ /* @__PURE__ */ jsx40(DialogTrigger, { children: /* @__PURE__ */ jsx40(SimpleTooltip, { content: "Add key", children: /* @__PURE__ */ jsx40(Button, { variant: "primary", size: "icon-sm", "data-testid": "add-key-button", children: /* @__PURE__ */ jsx40(PlusIcon, { className: "size-4" }) }) }) }),
5741
5766
  /* @__PURE__ */ jsxs24(DialogContent, { className: "max-w-[400px]", children: [
5742
5767
  /* @__PURE__ */ jsx40(DialogHeader, { children: /* @__PURE__ */ jsx40(DialogTitle, { children: "Create new key" }) }),
5743
5768
  /* @__PURE__ */ jsx40("div", { className: "sr-only", children: /* @__PURE__ */ jsx40(DialogDescription2, { children: "Create new key" }) }),
@@ -5798,6 +5823,9 @@ var Empty = () => {
5798
5823
  ] }) });
5799
5824
  };
5800
5825
 
5826
+ // src/components/databrowser/components/sidebar/keys-list.tsx
5827
+ import { useRef as useRef3 } from "react";
5828
+
5801
5829
  // src/components/databrowser/components/sidebar-context-menu.tsx
5802
5830
  import { useState as useState10 } from "react";
5803
5831
  import { IconCopy as IconCopy3, IconExternalLink as IconExternalLink2, IconTrash as IconTrash3 } from "@tabler/icons-react";
@@ -5806,19 +5834,22 @@ import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs26 } from "react/jsx-r
5806
5834
  var SidebarContextMenu = ({ children }) => {
5807
5835
  const { mutate: deleteKey } = useDeleteKey();
5808
5836
  const [isAlertOpen, setAlertOpen] = useState10(false);
5809
- const [dataKey, setDataKey] = useState10("");
5810
- const { addTab, setSelectedKey, selectTab, setSearch } = useDatabrowserStore();
5811
- const { search: currentSearch } = useTab();
5837
+ const [contextKeys, setContextKeys] = useState10([]);
5838
+ const { addTab, setSelectedKey: setSelectedKeyGlobal, selectTab, setSearch } = useDatabrowserStore();
5839
+ const { search: currentSearch, selectedKeys, setSelectedKey } = useTab();
5812
5840
  return /* @__PURE__ */ jsxs26(Fragment8, { children: [
5813
5841
  /* @__PURE__ */ jsx42(
5814
5842
  DeleteAlertDialog,
5815
5843
  {
5816
5844
  deletionType: "key",
5845
+ count: contextKeys.length,
5817
5846
  open: isAlertOpen,
5818
5847
  onOpenChange: setAlertOpen,
5819
5848
  onDeleteConfirm: (e) => {
5820
5849
  e.stopPropagation();
5821
- deleteKey(dataKey);
5850
+ for (const key of contextKeys) {
5851
+ deleteKey(key);
5852
+ }
5822
5853
  setAlertOpen(false);
5823
5854
  }
5824
5855
  }
@@ -5831,7 +5862,13 @@ var SidebarContextMenu = ({ children }) => {
5831
5862
  const el = e.target;
5832
5863
  const key = el.closest("[data-key]");
5833
5864
  if (key && key instanceof HTMLElement && key.dataset.key !== void 0) {
5834
- setDataKey(key.dataset.key);
5865
+ const clickedKey = key.dataset.key;
5866
+ if (selectedKeys.includes(clickedKey)) {
5867
+ setContextKeys(selectedKeys);
5868
+ } else {
5869
+ setSelectedKey(clickedKey);
5870
+ setContextKeys([clickedKey]);
5871
+ }
5835
5872
  } else {
5836
5873
  throw new Error("Key not found");
5837
5874
  }
@@ -5844,12 +5881,13 @@ var SidebarContextMenu = ({ children }) => {
5844
5881
  ContextMenuItem,
5845
5882
  {
5846
5883
  onClick: () => {
5847
- navigator.clipboard.writeText(dataKey);
5884
+ navigator.clipboard.writeText(contextKeys[0]);
5848
5885
  toast({
5849
5886
  description: "Key copied to clipboard"
5850
5887
  });
5851
5888
  },
5852
5889
  className: "gap-2",
5890
+ disabled: contextKeys.length !== 1,
5853
5891
  children: [
5854
5892
  /* @__PURE__ */ jsx42(IconCopy3, { size: 16 }),
5855
5893
  "Copy key"
@@ -5861,11 +5899,12 @@ var SidebarContextMenu = ({ children }) => {
5861
5899
  {
5862
5900
  onClick: () => {
5863
5901
  const newTabId = addTab();
5864
- setSelectedKey(newTabId, dataKey);
5902
+ setSelectedKeyGlobal(newTabId, contextKeys[0]);
5865
5903
  setSearch(newTabId, currentSearch);
5866
5904
  selectTab(newTabId);
5867
5905
  },
5868
5906
  className: "gap-2",
5907
+ disabled: contextKeys.length !== 1,
5869
5908
  children: [
5870
5909
  /* @__PURE__ */ jsx42(IconExternalLink2, { size: 16 }),
5871
5910
  "Open in new tab"
@@ -5875,7 +5914,7 @@ var SidebarContextMenu = ({ children }) => {
5875
5914
  /* @__PURE__ */ jsx42(ContextMenuSeparator3, {}),
5876
5915
  /* @__PURE__ */ jsxs26(ContextMenuItem, { onClick: () => setAlertOpen(true), className: "gap-2", children: [
5877
5916
  /* @__PURE__ */ jsx42(IconTrash3, { size: 16 }),
5878
- "Delete key"
5917
+ contextKeys.length > 1 ? `Delete ${contextKeys.length} keys` : "Delete key"
5879
5918
  ] })
5880
5919
  ] })
5881
5920
  ] })
@@ -5886,7 +5925,23 @@ var SidebarContextMenu = ({ children }) => {
5886
5925
  import { Fragment as Fragment9, jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
5887
5926
  var KeysList = () => {
5888
5927
  const { keys } = useKeys();
5889
- return /* @__PURE__ */ jsx43(SidebarContextMenu, { children: /* @__PURE__ */ jsx43(Fragment9, { children: keys.map((data, i) => /* @__PURE__ */ jsx43(KeyItem, { nextKey: keys.at(i + 1)?.[0] ?? "", data }, data[0])) }) });
5928
+ const lastClickedIndexRef = useRef3(null);
5929
+ return /* @__PURE__ */ jsx43(SidebarContextMenu, { children: /* @__PURE__ */ jsxs27(Fragment9, { children: [
5930
+ /* @__PURE__ */ jsx43("div", { className: "h-px" }),
5931
+ keys.map((data, i) => /* @__PURE__ */ jsxs27(Fragment9, { children: [
5932
+ /* @__PURE__ */ jsx43(
5933
+ KeyItem,
5934
+ {
5935
+ index: i,
5936
+ data,
5937
+ allKeys: keys,
5938
+ lastClickedIndexRef
5939
+ },
5940
+ data[0]
5941
+ ),
5942
+ i !== keys.length - 1 && /* @__PURE__ */ jsx43("div", { className: "-z-10 mx-2 h-px bg-zinc-100 dark:bg-zinc-200" })
5943
+ ] }))
5944
+ ] }) });
5890
5945
  };
5891
5946
  var keyStyles = {
5892
5947
  string: "border-sky-400 !bg-sky-50 text-sky-900",
@@ -5897,11 +5952,33 @@ var keyStyles = {
5897
5952
  list: "border-orange-400 !bg-orange-50 text-orange-900",
5898
5953
  stream: "border-green-400 !bg-green-50 text-green-900"
5899
5954
  };
5900
- var KeyItem = ({ data, nextKey }) => {
5901
- const { selectedKey, setSelectedKey } = useTab();
5955
+ var KeyItem = ({
5956
+ data,
5957
+ index,
5958
+ allKeys,
5959
+ lastClickedIndexRef
5960
+ }) => {
5961
+ const { selectedKeys, setSelectedKeys, setSelectedKey } = useTab();
5902
5962
  const [dataKey, dataType] = data;
5903
- const isKeySelected = selectedKey === dataKey;
5904
- const isNextKeySelected = selectedKey === nextKey;
5963
+ const isKeySelected = selectedKeys.includes(dataKey);
5964
+ const handleClick = (e) => {
5965
+ if (e.shiftKey && lastClickedIndexRef.current !== null) {
5966
+ const start = Math.min(lastClickedIndexRef.current, index);
5967
+ const end = Math.max(lastClickedIndexRef.current, index);
5968
+ const rangeKeys = allKeys.slice(start, end + 1).map(([key]) => key);
5969
+ setSelectedKeys(rangeKeys);
5970
+ } else if (e.metaKey || e.ctrlKey) {
5971
+ if (isKeySelected) {
5972
+ setSelectedKeys(selectedKeys.filter((k) => k !== dataKey));
5973
+ } else {
5974
+ setSelectedKeys([...selectedKeys, dataKey]);
5975
+ }
5976
+ lastClickedIndexRef.current = index;
5977
+ } else {
5978
+ setSelectedKey(dataKey);
5979
+ lastClickedIndexRef.current = index;
5980
+ }
5981
+ };
5905
5982
  return /* @__PURE__ */ jsxs27(
5906
5983
  Button,
5907
5984
  {
@@ -5909,24 +5986,51 @@ var KeyItem = ({ data, nextKey }) => {
5909
5986
  variant: isKeySelected ? "default" : "ghost",
5910
5987
  className: cn(
5911
5988
  "relative flex h-10 w-full items-center justify-start gap-2 px-3 py-0 !ring-0 focus-visible:bg-zinc-50",
5912
- "select-none border border-transparent text-left",
5989
+ "-my-px select-none border border-transparent text-left",
5913
5990
  isKeySelected && "shadow-sm",
5914
5991
  isKeySelected && keyStyles[dataType]
5915
5992
  ),
5916
- onClick: () => setSelectedKey(dataKey),
5993
+ onClick: handleClick,
5917
5994
  children: [
5918
5995
  /* @__PURE__ */ jsx43(TypeTag, { variant: dataType, type: "icon" }),
5919
- /* @__PURE__ */ jsx43("p", { className: "truncate whitespace-nowrap", children: dataKey }),
5920
- !isKeySelected && !isNextKeySelected && /* @__PURE__ */ jsx43("span", { className: "absolute -bottom-px left-3 right-3 h-px bg-zinc-100" })
5996
+ /* @__PURE__ */ jsx43("p", { className: "truncate whitespace-nowrap", children: dataKey })
5921
5997
  ]
5922
5998
  }
5923
5999
  );
5924
6000
  };
5925
6001
 
6002
+ // src/components/databrowser/components/sidebar/reload-button.tsx
6003
+ import { useState as useState11 } from "react";
6004
+ import { IconLoader2 as IconLoader22, IconRefresh } from "@tabler/icons-react";
6005
+ import { jsx as jsx44 } from "react/jsx-runtime";
6006
+ var ReloadButton = ({
6007
+ onClick,
6008
+ isLoading: isLoadingProp
6009
+ }) => {
6010
+ const [isLoading, setIsLoading] = useState11(false);
6011
+ const handleClick = () => {
6012
+ setIsLoading(true);
6013
+ onClick();
6014
+ setTimeout(() => {
6015
+ setIsLoading(false);
6016
+ }, 350);
6017
+ };
6018
+ return /* @__PURE__ */ jsx44("div", { children: /* @__PURE__ */ jsx44(SimpleTooltip, { content: "Refresh", children: /* @__PURE__ */ jsx44(
6019
+ Button,
6020
+ {
6021
+ variant: "outline",
6022
+ size: "icon-sm",
6023
+ onClick: handleClick,
6024
+ disabled: isLoading || isLoadingProp,
6025
+ children: isLoading ? /* @__PURE__ */ jsx44(IconLoader22, { className: "animate-spin text-zinc-500", size: 16 }) : /* @__PURE__ */ jsx44(IconRefresh, { className: "text-zinc-500 dark:text-zinc-600", size: 16 })
6026
+ }
6027
+ ) }) });
6028
+ };
6029
+
5926
6030
  // src/components/databrowser/components/sidebar/search-input.tsx
5927
- import { useEffect as useEffect11, useRef as useRef3, useState as useState11 } from "react";
6031
+ import { useEffect as useEffect11, useRef as useRef4, useState as useState12 } from "react";
5928
6032
  import { IconX } from "@tabler/icons-react";
5929
- import { jsx as jsx44, jsxs as jsxs28 } from "react/jsx-runtime";
6033
+ import { jsx as jsx45, jsxs as jsxs28 } from "react/jsx-runtime";
5930
6034
  var dedupeSearchHistory = (history) => {
5931
6035
  const seen = /* @__PURE__ */ new Set();
5932
6036
  return history.filter((item) => {
@@ -5938,11 +6042,11 @@ var dedupeSearchHistory = (history) => {
5938
6042
  var SearchInput = () => {
5939
6043
  const { setSearchKey, search } = useTab();
5940
6044
  const { searchHistory, addSearchHistory } = useDatabrowserStore();
5941
- const [state, setState] = useState11(search.key);
5942
- const [isFocus, setIsFocus] = useState11(false);
5943
- const [focusedIndex, setFocusedIndex] = useState11(-1);
5944
- const inputRef = useRef3(null);
5945
- const historyItemRefs = useRef3([]);
6045
+ const [state, setState] = useState12(search.key);
6046
+ const [isFocus, setIsFocus] = useState12(false);
6047
+ const [focusedIndex, setFocusedIndex] = useState12(-1);
6048
+ const inputRef = useRef4(null);
6049
+ const historyItemRefs = useRef4([]);
5946
6050
  const handleSubmit = (value) => {
5947
6051
  if (value.trim() !== "" && !value.includes("*")) value = `${value}*`;
5948
6052
  addSearchHistory(value);
@@ -5984,12 +6088,12 @@ var SearchInput = () => {
5984
6088
  };
5985
6089
  return /* @__PURE__ */ jsxs28("div", { className: "relative grow", children: [
5986
6090
  /* @__PURE__ */ jsxs28(Popover, { open: isFocus && filteredHistory.length > 0, children: [
5987
- /* @__PURE__ */ jsx44(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx44("div", { children: /* @__PURE__ */ jsx44(
6091
+ /* @__PURE__ */ jsx45(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx45("div", { className: "h-8 rounded-md rounded-l-none border border-zinc-300 font-normal", children: /* @__PURE__ */ jsx45(
5988
6092
  Input,
5989
6093
  {
5990
6094
  ref: inputRef,
5991
6095
  placeholder: "Search",
5992
- className: "rounded-l-none border-zinc-300 font-normal",
6096
+ className: "h-full rounded-l-none border-none pr-6",
5993
6097
  onKeyDown: handleKeyDown,
5994
6098
  onChange: (e) => {
5995
6099
  setState(e.currentTarget.value);
@@ -6003,7 +6107,7 @@ var SearchInput = () => {
6003
6107
  onBlur: () => setIsFocus(false)
6004
6108
  }
6005
6109
  ) }) }),
6006
- /* @__PURE__ */ jsx44(
6110
+ /* @__PURE__ */ jsx45(
6007
6111
  PopoverContent,
6008
6112
  {
6009
6113
  className: "w-[--radix-popover-trigger-width] divide-y px-3 py-2 text-[13px] text-zinc-900",
@@ -6012,7 +6116,7 @@ var SearchInput = () => {
6012
6116
  e.preventDefault();
6013
6117
  e.stopPropagation();
6014
6118
  },
6015
- children: filteredHistory.map((item, index) => /* @__PURE__ */ jsx44("div", { className: "w-full py-[3px]", children: /* @__PURE__ */ jsx44(
6119
+ children: filteredHistory.map((item, index) => /* @__PURE__ */ jsx45("div", { className: "w-full py-[3px]", children: /* @__PURE__ */ jsx45(
6016
6120
  "button",
6017
6121
  {
6018
6122
  ref: (el) => {
@@ -6039,8 +6143,8 @@ var SearchInput = () => {
6039
6143
  setState("");
6040
6144
  },
6041
6145
  children: [
6042
- /* @__PURE__ */ jsx44(IconX, { size: 16 }),
6043
- /* @__PURE__ */ jsx44("span", { className: "sr-only", children: "Clear" })
6146
+ /* @__PURE__ */ jsx45(IconX, { size: 16 }),
6147
+ /* @__PURE__ */ jsx45("span", { className: "sr-only", children: "Clear" })
6044
6148
  ]
6045
6149
  }
6046
6150
  ),
@@ -6049,15 +6153,15 @@ var SearchInput = () => {
6049
6153
  };
6050
6154
 
6051
6155
  // src/components/databrowser/components/sidebar/skeleton-buttons.tsx
6052
- import { jsx as jsx45, jsxs as jsxs29 } from "react/jsx-runtime";
6156
+ import { jsx as jsx46, jsxs as jsxs29 } from "react/jsx-runtime";
6053
6157
  var DEFAULT_SKELETON_COUNT = 6;
6054
- var LoadingSkeleton = () => /* @__PURE__ */ jsx45("div", { className: "block h-full w-full rounded-lg border border-zinc-200 bg-white p-1 pr-3 transition-all", children: Array.from({ length: DEFAULT_SKELETON_COUNT }).fill(0).map((_, idx) => /* @__PURE__ */ jsxs29("div", { className: "flex h-10 items-center gap-2 px-3", children: [
6055
- /* @__PURE__ */ jsx45(Skeleton, { className: "size-5 shrink-0 rounded" }),
6056
- /* @__PURE__ */ jsx45(Skeleton, { className: "h-4 grow rounded" })
6158
+ var LoadingSkeleton = () => /* @__PURE__ */ jsx46("div", { className: "block h-full w-full rounded-lg border border-zinc-200 bg-white p-1 pr-3 transition-all", children: Array.from({ length: DEFAULT_SKELETON_COUNT }).fill(0).map((_, idx) => /* @__PURE__ */ jsxs29("div", { className: "flex h-10 items-center gap-2 px-3", children: [
6159
+ /* @__PURE__ */ jsx46(Skeleton, { className: "size-5 shrink-0 rounded" }),
6160
+ /* @__PURE__ */ jsx46(Skeleton, { className: "h-4 grow rounded" })
6057
6161
  ] }, idx)) });
6058
6162
 
6059
6163
  // src/components/databrowser/components/sidebar/type-selector.tsx
6060
- import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
6164
+ import { jsx as jsx47, jsxs as jsxs30 } from "react/jsx-runtime";
6061
6165
  var ALL_TYPES_KEY = "all";
6062
6166
  function DataTypeSelector() {
6063
6167
  const { search, setSearchType } = useTab();
@@ -6073,9 +6177,9 @@ function DataTypeSelector() {
6073
6177
  },
6074
6178
  value: search.type === void 0 ? ALL_TYPES_KEY : search.type,
6075
6179
  children: [
6076
- /* @__PURE__ */ jsx46(SelectTrigger, { className: "!w-auto select-none whitespace-nowrap rounded-r-none border-r-0 border-zinc-300 pr-8", children: /* @__PURE__ */ jsx46(SelectValue, {}) }),
6077
- /* @__PURE__ */ jsx46(SelectContent, { children: /* @__PURE__ */ jsx46(SelectGroup, { children: [[ALL_TYPES_KEY, "All Types"], ...Object.entries(DATA_TYPE_NAMES)].map(
6078
- ([key, value]) => /* @__PURE__ */ jsx46(SelectItem, { value: key, children: value }, key)
6180
+ /* @__PURE__ */ jsx47(SelectTrigger, { className: "!w-auto select-none whitespace-nowrap rounded-r-none border-r-0 border-zinc-300 pr-8", children: /* @__PURE__ */ jsx47(SelectValue, {}) }),
6181
+ /* @__PURE__ */ jsx47(SelectContent, { children: /* @__PURE__ */ jsx47(SelectGroup, { children: [[ALL_TYPES_KEY, "All Types"], ...Object.entries(DATA_TYPE_NAMES)].map(
6182
+ ([key, value]) => /* @__PURE__ */ jsx47(SelectItem, { value: key, children: value }, key)
6079
6183
  ) }) })
6080
6184
  ]
6081
6185
  }
@@ -6083,19 +6187,17 @@ function DataTypeSelector() {
6083
6187
  }
6084
6188
 
6085
6189
  // src/components/databrowser/components/sidebar/index.tsx
6086
- import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
6190
+ import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
6087
6191
  function Sidebar() {
6088
6192
  const { keys, query } = useKeys();
6089
6193
  return /* @__PURE__ */ jsxs31("div", { className: "flex h-full flex-col gap-2 p-4", children: [
6090
6194
  /* @__PURE__ */ jsxs31("div", { className: "rounded-lg bg-zinc-100", children: [
6091
6195
  /* @__PURE__ */ jsxs31("div", { className: "flex h-10 items-center justify-between pl-1", children: [
6092
- /* @__PURE__ */ jsx47(DisplayDbSize, {}),
6196
+ /* @__PURE__ */ jsx48(DisplayDbSize, {}),
6093
6197
  /* @__PURE__ */ jsxs31("div", { className: "flex gap-1", children: [
6094
- /* @__PURE__ */ jsx47(
6095
- Button,
6198
+ /* @__PURE__ */ jsx48(
6199
+ ReloadButton,
6096
6200
  {
6097
- "aria-label": "Refresh",
6098
- className: "h-7 w-7 px-0 text-zinc-500",
6099
6201
  onClick: () => {
6100
6202
  queryClient.invalidateQueries({
6101
6203
  queryKey: [FETCH_KEYS_QUERY_KEY]
@@ -6113,28 +6215,28 @@ function Sidebar() {
6113
6215
  queryKey: [FETCH_KEY_TYPE_QUERY_KEY]
6114
6216
  });
6115
6217
  },
6116
- children: /* @__PURE__ */ jsx47(Spinner, { isLoading: query.isFetching, children: /* @__PURE__ */ jsx47(IconRefresh, { size: 16 }) })
6218
+ isLoading: query.isFetching
6117
6219
  }
6118
6220
  ),
6119
- /* @__PURE__ */ jsx47(AddKeyModal, {})
6221
+ /* @__PURE__ */ jsx48(AddKeyModal, {})
6120
6222
  ] })
6121
6223
  ] }),
6122
6224
  /* @__PURE__ */ jsxs31("div", { className: "flex h-10 items-center", children: [
6123
- /* @__PURE__ */ jsx47(DataTypeSelector, {}),
6124
- /* @__PURE__ */ jsx47(SearchInput, {})
6225
+ /* @__PURE__ */ jsx48(DataTypeSelector, {}),
6226
+ /* @__PURE__ */ jsx48(SearchInput, {})
6125
6227
  ] })
6126
6228
  ] }),
6127
- query.isLoading && keys.length === 0 ? /* @__PURE__ */ jsx47(LoadingSkeleton, {}) : keys.length > 0 ? (
6229
+ query.isLoading && keys.length === 0 ? /* @__PURE__ */ jsx48(LoadingSkeleton, {}) : keys.length > 0 ? (
6128
6230
  // Infinite scroll already has a loader at the bottom
6129
- /* @__PURE__ */ jsx47(InfiniteScroll, { query, disableRoundedInherit: true, className: "min-h-0", children: /* @__PURE__ */ jsx47(KeysList, {}) })
6130
- ) : /* @__PURE__ */ jsx47(Empty, {})
6231
+ /* @__PURE__ */ jsx48(InfiniteScroll, { query, disableRoundedInherit: true, className: "min-h-0", children: /* @__PURE__ */ jsx48(KeysList, {}) })
6232
+ ) : /* @__PURE__ */ jsx48(Empty, {})
6131
6233
  ] });
6132
6234
  }
6133
6235
 
6134
6236
  // src/components/databrowser/components/databrowser-instance.tsx
6135
- import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
6237
+ import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
6136
6238
  var DatabrowserInstance = ({ hidden }) => {
6137
- return /* @__PURE__ */ jsx48(KeysProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("min-h-0 grow rounded-md bg-zinc-100", hidden && "hidden"), children: [
6239
+ return /* @__PURE__ */ jsx49(KeysProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("min-h-0 grow rounded-md bg-zinc-100", hidden && "hidden"), children: [
6138
6240
  /* @__PURE__ */ jsxs32(
6139
6241
  PanelGroup,
6140
6242
  {
@@ -6142,18 +6244,18 @@ var DatabrowserInstance = ({ hidden }) => {
6142
6244
  direction: "horizontal",
6143
6245
  className: "h-full w-full gap-0.5 text-sm antialiased",
6144
6246
  children: [
6145
- /* @__PURE__ */ jsx48(Panel, { defaultSize: 30, minSize: 30, children: /* @__PURE__ */ jsx48(Sidebar, {}) }),
6146
- /* @__PURE__ */ jsx48(PanelResizeHandle, { className: "group flex h-full w-3 justify-center", children: /* @__PURE__ */ jsx48("div", { className: "h-full border-r border-dashed border-zinc-200 transition-colors group-hover:border-zinc-500" }) }),
6147
- /* @__PURE__ */ jsx48(Panel, { minSize: 40, children: /* @__PURE__ */ jsx48(DataDisplay, {}) })
6247
+ /* @__PURE__ */ jsx49(Panel, { defaultSize: 30, minSize: 30, children: /* @__PURE__ */ jsx49(Sidebar, {}) }),
6248
+ /* @__PURE__ */ jsx49(PanelResizeHandle, { className: "group flex h-full w-3 justify-center", children: /* @__PURE__ */ jsx49("div", { className: "h-full border-r border-dashed border-zinc-200 transition-colors group-hover:border-zinc-500" }) }),
6249
+ /* @__PURE__ */ jsx49(Panel, { minSize: 40, children: /* @__PURE__ */ jsx49(DataDisplay, {}) })
6148
6250
  ]
6149
6251
  }
6150
6252
  ),
6151
- /* @__PURE__ */ jsx48(Toaster, {})
6253
+ /* @__PURE__ */ jsx49(Toaster, {})
6152
6254
  ] }) });
6153
6255
  };
6154
6256
 
6155
6257
  // src/components/databrowser/components/databrowser-tabs.tsx
6156
- import { useCallback as useCallback3, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef5, useState as useState13 } from "react";
6258
+ import { useCallback as useCallback3, useEffect as useEffect13, useMemo as useMemo8, useRef as useRef6, useState as useState14 } from "react";
6157
6259
  import {
6158
6260
  closestCenter,
6159
6261
  DndContext,
@@ -6171,8 +6273,8 @@ import { IconChevronDown as IconChevronDown2, IconMaximize, IconPlus as IconPlus
6171
6273
  import * as React13 from "react";
6172
6274
  import { Command as CommandPrimitive } from "cmdk";
6173
6275
  import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
6174
- import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
6175
- var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
6276
+ import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
6277
+ var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
6176
6278
  CommandPrimitive,
6177
6279
  {
6178
6280
  ref,
@@ -6185,8 +6287,8 @@ var Command = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__
6185
6287
  ));
6186
6288
  Command.displayName = CommandPrimitive.displayName;
6187
6289
  var CommandInput = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs33("div", { className: "flex items-center border-b px-3", "cmdk-input-wrapper": "", children: [
6188
- /* @__PURE__ */ jsx49(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
6189
- /* @__PURE__ */ jsx49(
6290
+ /* @__PURE__ */ jsx50(MagnifyingGlassIcon, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
6291
+ /* @__PURE__ */ jsx50(
6190
6292
  CommandPrimitive.Input,
6191
6293
  {
6192
6294
  ref,
@@ -6199,7 +6301,7 @@ var CommandInput = React13.forwardRef(({ className, ...props }, ref) => /* @__PU
6199
6301
  )
6200
6302
  ] }));
6201
6303
  CommandInput.displayName = CommandPrimitive.Input.displayName;
6202
- var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
6304
+ var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
6203
6305
  CommandPrimitive.List,
6204
6306
  {
6205
6307
  ref,
@@ -6208,9 +6310,9 @@ var CommandList = React13.forwardRef(({ className, ...props }, ref) => /* @__PUR
6208
6310
  }
6209
6311
  ));
6210
6312
  CommandList.displayName = CommandPrimitive.List.displayName;
6211
- var CommandEmpty = React13.forwardRef((props, ref) => /* @__PURE__ */ jsx49(CommandPrimitive.Empty, { ref, className: "py-6 text-center text-sm", ...props }));
6313
+ var CommandEmpty = React13.forwardRef((props, ref) => /* @__PURE__ */ jsx50(CommandPrimitive.Empty, { ref, className: "py-6 text-center text-sm", ...props }));
6212
6314
  CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
6213
- var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
6315
+ var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
6214
6316
  CommandPrimitive.Group,
6215
6317
  {
6216
6318
  ref,
@@ -6222,7 +6324,7 @@ var CommandGroup = React13.forwardRef(({ className, ...props }, ref) => /* @__PU
6222
6324
  }
6223
6325
  ));
6224
6326
  CommandGroup.displayName = CommandPrimitive.Group.displayName;
6225
- var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
6327
+ var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
6226
6328
  CommandPrimitive.Separator,
6227
6329
  {
6228
6330
  ref,
@@ -6231,7 +6333,7 @@ var CommandSeparator = React13.forwardRef(({ className, ...props }, ref) => /* @
6231
6333
  }
6232
6334
  ));
6233
6335
  CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
6234
- var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx49(
6336
+ var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx50(
6235
6337
  CommandPrimitive.Item,
6236
6338
  {
6237
6339
  ref,
@@ -6244,7 +6346,7 @@ var CommandItem = React13.forwardRef(({ className, ...props }, ref) => /* @__PUR
6244
6346
  ));
6245
6347
  CommandItem.displayName = CommandPrimitive.Item.displayName;
6246
6348
  var CommandShortcut = ({ className, ...props }) => {
6247
- return /* @__PURE__ */ jsx49("span", { className: cn("ml-auto text-xs tracking-widest text-zinc-500", className), ...props });
6349
+ return /* @__PURE__ */ jsx50("span", { className: cn("ml-auto text-xs tracking-widest text-zinc-500", className), ...props });
6248
6350
  };
6249
6351
  CommandShortcut.displayName = "CommandShortcut";
6250
6352
 
@@ -6259,19 +6361,19 @@ import {
6259
6361
  } from "@tabler/icons-react";
6260
6362
 
6261
6363
  // src/components/databrowser/components/tab-type-icon.tsx
6262
- import { jsx as jsx50 } from "react/jsx-runtime";
6364
+ import { jsx as jsx51 } from "react/jsx-runtime";
6263
6365
  function TabTypeIcon({ selectedKey }) {
6264
6366
  const { data: keyType, isLoading } = useFetchKeyType(selectedKey);
6265
- if (isLoading) return /* @__PURE__ */ jsx50(Skeleton, { className: "h-5 w-5 rounded" });
6367
+ if (isLoading) return /* @__PURE__ */ jsx51(Skeleton, { className: "h-5 w-5 rounded" });
6266
6368
  if (!keyType || keyType === "none") return;
6267
- return /* @__PURE__ */ jsx50(TypeTag, { variant: keyType, type: "icon" });
6369
+ return /* @__PURE__ */ jsx51(TypeTag, { variant: keyType, type: "icon" });
6268
6370
  }
6269
6371
 
6270
6372
  // src/hooks/use-overflow.ts
6271
- import { useCallback as useCallback2, useEffect as useEffect12, useRef as useRef4, useState as useState12 } from "react";
6373
+ import { useCallback as useCallback2, useEffect as useEffect12, useRef as useRef5, useState as useState13 } from "react";
6272
6374
  var useOverflow = () => {
6273
- const [isOverflow, setIsOverflow] = useState12(false);
6274
- const observerRef = useRef4(null);
6375
+ const [isOverflow, setIsOverflow] = useState13(false);
6376
+ const observerRef = useRef5(null);
6275
6377
  const ref = useCallback2((node) => {
6276
6378
  if (observerRef.current) {
6277
6379
  observerRef.current.disconnect();
@@ -6294,7 +6396,7 @@ var useOverflow = () => {
6294
6396
  };
6295
6397
 
6296
6398
  // src/components/databrowser/components/tab.tsx
6297
- import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
6399
+ import { jsx as jsx52, jsxs as jsxs34 } from "react/jsx-runtime";
6298
6400
  var Tab = ({ id, isList }) => {
6299
6401
  const { active, search, selectedKey, pinned } = useTab();
6300
6402
  const {
@@ -6310,7 +6412,7 @@ var Tab = ({ id, isList }) => {
6310
6412
  const hasPinnedTabs = tabs.some(([, data]) => data.pinned);
6311
6413
  const { ref, isOverflow } = useOverflow();
6312
6414
  const label = search.key || selectedKey;
6313
- const iconNode = search.key ? /* @__PURE__ */ jsx51(IconSearch, { size: 15 }) : selectedKey ? /* @__PURE__ */ jsx51(TabTypeIcon, { selectedKey }) : void 0;
6415
+ const iconNode = search.key ? /* @__PURE__ */ jsx52(IconSearch, { size: 15 }) : selectedKey ? /* @__PURE__ */ jsx52(TabTypeIcon, { selectedKey }) : void 0;
6314
6416
  const tabNode = /* @__PURE__ */ jsxs34(
6315
6417
  "div",
6316
6418
  {
@@ -6324,7 +6426,7 @@ var Tab = ({ id, isList }) => {
6324
6426
  ),
6325
6427
  children: [
6326
6428
  iconNode,
6327
- /* @__PURE__ */ jsx51(
6429
+ /* @__PURE__ */ jsx52(
6328
6430
  "span",
6329
6431
  {
6330
6432
  ref,
@@ -6332,23 +6434,23 @@ var Tab = ({ id, isList }) => {
6332
6434
  children: label || "New Tab"
6333
6435
  }
6334
6436
  ),
6335
- pinned && /* @__PURE__ */ jsx51(IconPin, { size: 14, className: "text-zinc-500" }),
6336
- tabs.length > 1 && !pinned && /* @__PURE__ */ jsx51(
6437
+ pinned && /* @__PURE__ */ jsx52(IconPin, { size: 14, className: "text-zinc-500" }),
6438
+ tabs.length > 1 && !pinned && /* @__PURE__ */ jsx52(
6337
6439
  "button",
6338
6440
  {
6339
6441
  onClick: (e) => {
6340
6442
  e.stopPropagation();
6341
6443
  removeTab(id);
6342
6444
  },
6343
- className: "p-1 text-zinc-300 transition-colors hover:text-zinc-500",
6344
- children: /* @__PURE__ */ jsx51(IconX2, { size: 16 })
6445
+ className: "p-1 text-zinc-300 transition-colors hover:text-zinc-500 dark:text-zinc-400",
6446
+ children: /* @__PURE__ */ jsx52(IconX2, { size: 16 })
6345
6447
  }
6346
6448
  )
6347
6449
  ]
6348
6450
  }
6349
6451
  );
6350
6452
  return /* @__PURE__ */ jsxs34(ContextMenu, { children: [
6351
- /* @__PURE__ */ jsx51(SimpleTooltip, { content: isOverflow ? label : void 0, children: /* @__PURE__ */ jsx51(ContextMenuTrigger, { asChild: true, children: tabNode }) }),
6453
+ /* @__PURE__ */ jsx52(SimpleTooltip, { content: isOverflow ? label : void 0, children: /* @__PURE__ */ jsx52(ContextMenuTrigger, { asChild: true, children: tabNode }) }),
6352
6454
  /* @__PURE__ */ jsxs34(
6353
6455
  ContextMenuContent,
6354
6456
  {
@@ -6357,20 +6459,20 @@ var Tab = ({ id, isList }) => {
6357
6459
  },
6358
6460
  children: [
6359
6461
  /* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => togglePinTab(id), className: "gap-2", children: [
6360
- /* @__PURE__ */ jsx51(IconPin, { size: 16 }),
6462
+ /* @__PURE__ */ jsx52(IconPin, { size: 16 }),
6361
6463
  pinned ? "Unpin Tab" : "Pin Tab"
6362
6464
  ] }),
6363
6465
  /* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => duplicateTab(id), className: "gap-2", children: [
6364
- /* @__PURE__ */ jsx51(IconCopyPlus, { size: 16 }),
6466
+ /* @__PURE__ */ jsx52(IconCopyPlus, { size: 16 }),
6365
6467
  "Duplicate Tab"
6366
6468
  ] }),
6367
- /* @__PURE__ */ jsx51(ContextMenuSeparator, {}),
6469
+ /* @__PURE__ */ jsx52(ContextMenuSeparator, {}),
6368
6470
  /* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => forceRemoveTab(id), className: "gap-2", children: [
6369
- /* @__PURE__ */ jsx51(IconX2, { size: 16 }),
6471
+ /* @__PURE__ */ jsx52(IconX2, { size: 16 }),
6370
6472
  "Close Tab"
6371
6473
  ] }),
6372
6474
  /* @__PURE__ */ jsxs34(ContextMenuItem, { onSelect: () => closeOtherTabs(id), className: "gap-2", children: [
6373
- /* @__PURE__ */ jsx51(IconSquareX, { size: 16 }),
6475
+ /* @__PURE__ */ jsx52(IconSquareX, { size: 16 }),
6374
6476
  "Close Other Tabs"
6375
6477
  ] }),
6376
6478
  /* @__PURE__ */ jsxs34(
@@ -6380,7 +6482,7 @@ var Tab = ({ id, isList }) => {
6380
6482
  className: "gap-2",
6381
6483
  disabled: !hasPinnedTabs,
6382
6484
  children: [
6383
- /* @__PURE__ */ jsx51(IconArrowsMinimize, { size: 16 }),
6485
+ /* @__PURE__ */ jsx52(IconArrowsMinimize, { size: 16 }),
6384
6486
  "Close All But Pinned"
6385
6487
  ]
6386
6488
  }
@@ -6392,10 +6494,10 @@ var Tab = ({ id, isList }) => {
6392
6494
  };
6393
6495
 
6394
6496
  // src/components/databrowser/components/databrowser-tabs.tsx
6395
- import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
6497
+ import { jsx as jsx53, jsxs as jsxs35 } from "react/jsx-runtime";
6396
6498
  var SortableTab = ({ id }) => {
6397
- const [originalWidth, setOriginalWidth] = useState13(null);
6398
- const textRef = useRef5(null);
6499
+ const [originalWidth, setOriginalWidth] = useState14(null);
6500
+ const textRef = useRef6(null);
6399
6501
  const { tabs } = useDatabrowserStore();
6400
6502
  const tabData = tabs.find(([tabId]) => tabId === id)?.[1];
6401
6503
  const isPinned = tabData?.pinned;
@@ -6460,7 +6562,7 @@ var SortableTab = ({ id }) => {
6460
6562
  minWidth: originalWidth ? `${originalWidth}px` : void 0
6461
6563
  } : {}
6462
6564
  };
6463
- return /* @__PURE__ */ jsx52(
6565
+ return /* @__PURE__ */ jsx53(
6464
6566
  "div",
6465
6567
  {
6466
6568
  ref: measureRef,
@@ -6468,7 +6570,7 @@ var SortableTab = ({ id }) => {
6468
6570
  className: isDragging ? "cursor-grabbing" : isPinned ? "cursor-default" : "cursor-grab",
6469
6571
  ...attributes,
6470
6572
  ...isPinned ? {} : listeners2,
6471
- children: /* @__PURE__ */ jsx52(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx52(Tab, { id }) })
6573
+ children: /* @__PURE__ */ jsx53(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx53(Tab, { id }) })
6472
6574
  }
6473
6575
  );
6474
6576
  };
@@ -6481,10 +6583,10 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
6481
6583
  return 0;
6482
6584
  });
6483
6585
  }, [tabs]);
6484
- const scrollRef = useRef5(null);
6485
- const [hasLeftShadow, setHasLeftShadow] = useState13(false);
6486
- const [hasRightShadow, setHasRightShadow] = useState13(false);
6487
- const [isOverflow, setIsOverflow] = useState13(false);
6586
+ const scrollRef = useRef6(null);
6587
+ const [hasLeftShadow, setHasLeftShadow] = useState14(false);
6588
+ const [hasRightShadow, setHasRightShadow] = useState14(false);
6589
+ const [isOverflow, setIsOverflow] = useState14(false);
6488
6590
  useEffect13(() => {
6489
6591
  const el = scrollRef.current;
6490
6592
  if (!el) return;
@@ -6544,16 +6646,16 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
6544
6646
  }
6545
6647
  };
6546
6648
  return /* @__PURE__ */ jsxs35("div", { className: "relative mb-2 shrink-0", children: [
6547
- /* @__PURE__ */ jsx52("div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
6649
+ /* @__PURE__ */ jsx53("div", { className: "absolute bottom-0 left-0 right-0 -z-10 h-[1px] w-full bg-zinc-200" }),
6548
6650
  /* @__PURE__ */ jsxs35("div", { className: "flex translate-y-[1px] items-center gap-1", children: [
6549
6651
  /* @__PURE__ */ jsxs35("div", { className: "relative min-w-0 flex-1", children: [
6550
- /* @__PURE__ */ jsx52(
6652
+ /* @__PURE__ */ jsx53(
6551
6653
  "div",
6552
6654
  {
6553
6655
  className: `tabs-shadow-left pointer-events-none absolute left-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasLeftShadow ? "opacity-100" : "opacity-0"}`
6554
6656
  }
6555
6657
  ),
6556
- /* @__PURE__ */ jsx52(
6658
+ /* @__PURE__ */ jsx53(
6557
6659
  "div",
6558
6660
  {
6559
6661
  className: `tabs-shadow-right pointer-events-none absolute right-0 top-0 z-10 h-full w-6 transition-opacity duration-200 ${hasRightShadow ? "opacity-100" : "opacity-0"}`
@@ -6566,7 +6668,7 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
6566
6668
  onScroll: recomputeShadows,
6567
6669
  className: "scrollbar-hide flex min-w-0 flex-1 items-center gap-1 overflow-x-auto pb-[1px] [&::-webkit-scrollbar]:hidden",
6568
6670
  children: [
6569
- /* @__PURE__ */ jsx52(
6671
+ /* @__PURE__ */ jsx53(
6570
6672
  DndContext,
6571
6673
  {
6572
6674
  sensors,
@@ -6578,25 +6680,25 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
6578
6680
  strategy: MeasuringStrategy.Always
6579
6681
  }
6580
6682
  },
6581
- children: /* @__PURE__ */ jsx52(
6683
+ children: /* @__PURE__ */ jsx53(
6582
6684
  SortableContext,
6583
6685
  {
6584
6686
  items: sortedTabs.map(([id]) => id),
6585
6687
  strategy: horizontalListSortingStrategy,
6586
- children: selectedTab && sortedTabs.map(([id]) => /* @__PURE__ */ jsx52(SortableTab, { id }, id))
6688
+ children: selectedTab && sortedTabs.map(([id]) => /* @__PURE__ */ jsx53(SortableTab, { id }, id))
6587
6689
  }
6588
6690
  )
6589
6691
  }
6590
6692
  ),
6591
- !isOverflow && /* @__PURE__ */ jsx52("div", { className: "flex items-center gap-1 pl-1 pr-1", children: /* @__PURE__ */ jsx52(AddTabButton, {}) })
6693
+ !isOverflow && /* @__PURE__ */ jsx53("div", { className: "flex items-center gap-1 pl-1 pr-1", children: /* @__PURE__ */ jsx53(AddTabButton, {}) })
6592
6694
  ]
6593
6695
  }
6594
6696
  )
6595
6697
  ] }),
6596
6698
  /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-1 pl-1", children: [
6597
- isOverflow && /* @__PURE__ */ jsx52(AddTabButton, {}),
6598
- tabs.length > 1 && /* @__PURE__ */ jsx52(TabsListButton, { tabs, onSelectTab: selectTab }),
6599
- onFullScreenClick && /* @__PURE__ */ jsx52(
6699
+ isOverflow && /* @__PURE__ */ jsx53(AddTabButton, {}),
6700
+ tabs.length > 1 && /* @__PURE__ */ jsx53(TabsListButton, { tabs, onSelectTab: selectTab }),
6701
+ onFullScreenClick && /* @__PURE__ */ jsx53(
6600
6702
  Button,
6601
6703
  {
6602
6704
  "aria-label": "Toggle fullscreen",
@@ -6604,7 +6706,7 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
6604
6706
  size: "icon-sm",
6605
6707
  onClick: onFullScreenClick,
6606
6708
  className: "flex-shrink-0 bg-blue-100 hover:bg-blue-600 hover:text-white",
6607
- children: /* @__PURE__ */ jsx52(IconMaximize, { size: 16 })
6709
+ children: /* @__PURE__ */ jsx53(IconMaximize, { size: 16 })
6608
6710
  }
6609
6711
  )
6610
6712
  ] })
@@ -6623,15 +6725,15 @@ function AddTabButton() {
6623
6725
  tab.scrollIntoView({ behavior: "smooth" });
6624
6726
  }, 20);
6625
6727
  };
6626
- return /* @__PURE__ */ jsx52(
6728
+ return /* @__PURE__ */ jsx53(
6627
6729
  Button,
6628
6730
  {
6629
6731
  "aria-label": "Add new tab",
6630
6732
  variant: "secondary",
6631
6733
  size: "icon-sm",
6632
6734
  onClick: handleAddTab,
6633
- className: "flex-shrink-0",
6634
- children: /* @__PURE__ */ jsx52(IconPlus2, { className: "text-zinc-500", size: 16 })
6735
+ className: "flex-shrink-0 dark:bg-zinc-200",
6736
+ children: /* @__PURE__ */ jsx53(IconPlus2, { className: "text-zinc-500 dark:text-zinc-600", size: 16 })
6635
6737
  }
6636
6738
  );
6637
6739
  }
@@ -6639,7 +6741,7 @@ function TabsListButton({
6639
6741
  tabs,
6640
6742
  onSelectTab
6641
6743
  }) {
6642
- const [open, setOpen] = useState13(false);
6744
+ const [open, setOpen] = useState14(false);
6643
6745
  const sorted = useMemo8(() => {
6644
6746
  return [...tabs].sort(([, a], [, b]) => {
6645
6747
  if (a.pinned && !b.pinned) return -1;
@@ -6658,7 +6760,7 @@ function TabsListButton({
6658
6760
  }, 20);
6659
6761
  };
6660
6762
  return /* @__PURE__ */ jsxs35(Popover, { open, onOpenChange: setOpen, children: [
6661
- /* @__PURE__ */ jsx52(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs35(
6763
+ /* @__PURE__ */ jsx53(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs35(
6662
6764
  Button,
6663
6765
  {
6664
6766
  variant: "secondary",
@@ -6666,14 +6768,14 @@ function TabsListButton({
6666
6768
  className: "h-7 gap-1 px-2",
6667
6769
  "aria-label": "Search in tabs",
6668
6770
  children: [
6669
- /* @__PURE__ */ jsx52("span", { className: "text-xs text-zinc-600", children: tabs.length }),
6670
- /* @__PURE__ */ jsx52(IconChevronDown2, { className: "text-zinc-500", size: 16 })
6771
+ /* @__PURE__ */ jsx53("span", { className: "text-xs text-zinc-600", children: tabs.length }),
6772
+ /* @__PURE__ */ jsx53(IconChevronDown2, { className: "text-zinc-500", size: 16 })
6671
6773
  ]
6672
6774
  }
6673
6775
  ) }),
6674
- /* @__PURE__ */ jsx52(PopoverContent, { className: "w-96 p-0", align: "end", children: /* @__PURE__ */ jsx52(Command, { children: /* @__PURE__ */ jsxs35(CommandList, { children: [
6675
- /* @__PURE__ */ jsx52(CommandEmpty, { children: "No tabs" }),
6676
- /* @__PURE__ */ jsx52(CommandGroup, { children: sorted.map(([_id, item]) => /* @__PURE__ */ jsx52(
6776
+ /* @__PURE__ */ jsx53(PopoverContent, { className: "w-96 p-0", align: "end", children: /* @__PURE__ */ jsx53(Command, { children: /* @__PURE__ */ jsxs35(CommandList, { children: [
6777
+ /* @__PURE__ */ jsx53(CommandEmpty, { children: "No tabs" }),
6778
+ /* @__PURE__ */ jsx53(CommandGroup, { children: sorted.map(([_id, item]) => /* @__PURE__ */ jsx53(
6677
6779
  CommandItem,
6678
6780
  {
6679
6781
  style: {
@@ -6683,7 +6785,7 @@ function TabsListButton({
6683
6785
  onSelect: () => {
6684
6786
  handleSelectTab(item.id);
6685
6787
  },
6686
- children: /* @__PURE__ */ jsx52(TabIdProvider, { value: _id, children: /* @__PURE__ */ jsx52(Tab, { id: _id, isList: true }) })
6788
+ children: /* @__PURE__ */ jsx53(TabIdProvider, { value: _id, children: /* @__PURE__ */ jsx53(Tab, { id: _id, isList: true }) })
6687
6789
  },
6688
6790
  item.id
6689
6791
  )) })
@@ -6692,7 +6794,7 @@ function TabsListButton({
6692
6794
  }
6693
6795
 
6694
6796
  // src/components/databrowser/index.tsx
6695
- import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
6797
+ import { jsx as jsx54, jsxs as jsxs36 } from "react/jsx-runtime";
6696
6798
  var RedisBrowser = ({
6697
6799
  token,
6698
6800
  url,
@@ -6702,11 +6804,11 @@ var RedisBrowser = ({
6702
6804
  theme = "light"
6703
6805
  }) => {
6704
6806
  const credentials = useMemo9(() => ({ token, url }), [token, url]);
6705
- const rootRef = useRef6(null);
6807
+ const rootRef = useRef7(null);
6706
6808
  useEffect14(() => {
6707
6809
  queryClient.resetQueries();
6708
6810
  }, [credentials.url]);
6709
- return /* @__PURE__ */ jsx53(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx53(RedisProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx53(DarkModeProvider, { theme, children: /* @__PURE__ */ jsx53(DatabrowserProvider, { storage, rootRef, children: /* @__PURE__ */ jsx53(TooltipProvider, { children: /* @__PURE__ */ jsx53(
6811
+ return /* @__PURE__ */ jsx54(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx54(RedisProvider, { redisCredentials: credentials, children: /* @__PURE__ */ jsx54(DarkModeProvider, { theme, children: /* @__PURE__ */ jsx54(DatabrowserProvider, { storage, rootRef, children: /* @__PURE__ */ jsx54(TooltipProvider, { children: /* @__PURE__ */ jsx54(
6710
6812
  RedisBrowserRoot,
6711
6813
  {
6712
6814
  hideTabs,
@@ -6727,15 +6829,15 @@ var RedisBrowserRoot = ({
6727
6829
  }, [theme]);
6728
6830
  return (
6729
6831
  /* ups-db is the custom class used to prefix every style in the css bundle */
6730
- /* @__PURE__ */ jsx53(
6832
+ /* @__PURE__ */ jsx54(
6731
6833
  "div",
6732
6834
  {
6733
6835
  className: `ups-db ${theme === "dark" ? "dark" : ""}`,
6734
6836
  style: { height: "100%" },
6735
6837
  ref: rootRef,
6736
6838
  children: /* @__PURE__ */ jsxs36("div", { className: "flex h-full flex-col text-zinc-700", children: [
6737
- !hideTabs && /* @__PURE__ */ jsx53(DatabrowserTabs, { onFullScreenClick }),
6738
- /* @__PURE__ */ jsx53(DatabrowserInstances, {})
6839
+ !hideTabs && /* @__PURE__ */ jsx54(DatabrowserTabs, { onFullScreenClick }),
6840
+ /* @__PURE__ */ jsx54(DatabrowserInstances, {})
6739
6841
  ] })
6740
6842
  }
6741
6843
  )
@@ -6748,7 +6850,7 @@ var DatabrowserInstances = () => {
6748
6850
  else if (!selectedTab) selectTab(tabs[0][0]);
6749
6851
  }, [tabs, selectedTab, addTab, selectTab]);
6750
6852
  if (!selectedTab) return;
6751
- return tabs.map(([id]) => /* @__PURE__ */ jsx53(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx53(DatabrowserInstance, { hidden: id !== selectedTab }) }, id));
6853
+ return tabs.map(([id]) => /* @__PURE__ */ jsx54(TabIdProvider, { value: id, children: /* @__PURE__ */ jsx54(DatabrowserInstance, { hidden: id !== selectedTab }) }, id));
6752
6854
  };
6753
6855
  export {
6754
6856
  RedisBrowser