@tangle-network/ui 11.51.18 → 11.51.19

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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 11.51.19
2
+
3
+ ### Patch Changes
4
+
5
+ - 76fef41: `DropdownMenuContent` returns focus to its trigger without the keyboard focus ring when the menu closed after a pointer choice. Radix restores focus with a plain `focus()`, which Chromium draws as `:focus-visible`. Every bordered trigger therefore kept a ring after a mouse selection until focus moved elsewhere. A keyboard choice still shows the ring.
6
+ - 09487a5: Menu separators (`DropdownMenuSeparator`, `ContextMenuSeparator`, `SelectSeparator`) draw in `--border-strong` instead of `--border`. On the dark popover the old line measured 1.1:1 against its surface and disappeared, so a closing action such as Billing read as one more choice in the list above it. It now measures 1.8:1 in dark and 2.3:1 in light.
7
+
1
8
  ## 11.51.18
2
9
 
3
10
  ### Patch Changes
@@ -73,7 +73,7 @@ const ContextMenuLabel = React.forwardRef(({ className, inset, ...props }, ref)
73
73
  ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
74
74
  const ContextMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(ContextMenuPrimitive.Separator, {
75
75
  ref,
76
- className: cn("-mx-1 my-1 h-px bg-border", className),
76
+ className: cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className),
77
77
  ...props
78
78
  }));
79
79
  ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
@@ -11,6 +11,8 @@ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
11
11
  const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
12
12
  const DropdownMenuSub = DropdownMenuPrimitive.Sub;
13
13
  const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
14
+ const menuRow = cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50");
15
+ const menuSurface = cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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");
14
16
  const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.SubTrigger, {
15
17
  ref,
16
18
  className: cn("flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]", "data-[state=open]:bg-[var(--ix-sel-bg)]", ixRow, inset && "pl-8", className),
@@ -20,26 +22,37 @@ const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, .
20
22
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
21
23
  const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, {
22
24
  ref,
23
- className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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", className),
25
+ className: cn(menuSurface, className),
24
26
  ...props
25
27
  }));
26
28
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
27
- const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
29
+ const DropdownMenuContent = React.forwardRef(({ className, sideOffset = 4, onPointerDown, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
28
30
  ref,
29
31
  sideOffset,
30
- className: cn("z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]", "data-[state=closed]:animate-out data-[state=open]:animate-in", "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-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", className),
32
+ onPointerDown: (event) => {
33
+ event.currentTarget.dataset.pointer = "";
34
+ onPointerDown?.(event);
35
+ },
36
+ onCloseAutoFocus: (event) => {
37
+ const content = event.currentTarget;
38
+ onCloseAutoFocus?.(event);
39
+ if (content.dataset.pointer === void 0 || event.defaultPrevented || document.activeElement !== document.body) return;
40
+ event.preventDefault();
41
+ document.getElementById(content.getAttribute("aria-labelledby") ?? "")?.focus({ focusVisible: false });
42
+ },
43
+ className: cn(menuSurface, className),
31
44
  ...props
32
45
  }) }));
33
46
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
34
47
  const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
35
48
  ref,
36
- className: cn("relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", inset && "pl-8", className),
49
+ className: cn(menuRow, "px-2", inset && "pl-8", className),
37
50
  ...props
38
51
  }));
39
52
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
40
53
  const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.CheckboxItem, {
41
54
  ref,
42
- className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
55
+ className: cn(menuRow, "pr-2 pl-8", className),
43
56
  checked,
44
57
  ...props,
45
58
  children: [/* @__PURE__ */ jsx("span", {
@@ -50,7 +63,7 @@ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checke
50
63
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
51
64
  const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.RadioItem, {
52
65
  ref,
53
- className: cn("relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]", "focus:text-foreground", ixRow, "data-[disabled]:pointer-events-none data-[disabled]:opacity-50", className),
66
+ className: cn(menuRow, "pr-2 pl-8", className),
54
67
  ...props,
55
68
  children: [/* @__PURE__ */ jsx("span", {
56
69
  className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center",
@@ -66,7 +79,7 @@ const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref)
66
79
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
67
80
  const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, {
68
81
  ref,
69
- className: cn("-mx-1 my-1 h-px bg-border", className),
82
+ className: cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className),
70
83
  ...props
71
84
  }));
72
85
  DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
@@ -67,7 +67,7 @@ const SelectItem = React.forwardRef(({ className, children, ...props }, ref) =>
67
67
  SelectItem.displayName = SelectPrimitive.Item.displayName;
68
68
  const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Separator, {
69
69
  ref,
70
- className: cn("-mx-1 my-1 h-px bg-border", className),
70
+ className: cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className),
71
71
  ...props
72
72
  }));
73
73
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/ui",
3
- "version": "11.51.18",
3
+ "version": "11.51.19",
4
4
  "description": "Generic React UI components for Tangle products — primitives, chat, run, files, editor, markdown.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -140,7 +140,7 @@ const ContextMenuSeparator = React.forwardRef<
140
140
  React.ElementRef<typeof ContextMenuPrimitive.Separator>,
141
141
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
142
142
  >(({ className, ...props }, ref) => (
143
- <ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-border", className)} {...props} />
143
+ <ContextMenuPrimitive.Separator ref={ref} className={cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className)} {...props} />
144
144
  ));
145
145
  ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
146
146
 
@@ -16,6 +16,22 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
16
16
 
17
17
  const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18
18
 
19
+ // One surface for a menu and its submenus, one row for its items.
20
+ const menuRow = cn(
21
+ "relative flex cursor-pointer select-none items-center rounded-md py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]",
22
+ "focus:text-foreground",
23
+ ixRow,
24
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
25
+ );
26
+ const menuSurface = cn(
27
+ "z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]",
28
+ "data-[state=closed]:animate-out data-[state=open]:animate-in",
29
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
30
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
31
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
32
+ "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
33
+ );
34
+
19
35
  const DropdownMenuSubTrigger = React.forwardRef<
20
36
  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
21
37
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
@@ -46,15 +62,7 @@ const DropdownMenuSubContent = React.forwardRef<
46
62
  >(({ className, ...props }, ref) => (
47
63
  <DropdownMenuPrimitive.SubContent
48
64
  ref={ref}
49
- className={cn(
50
- "z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]",
51
- "data-[state=closed]:animate-out data-[state=open]:animate-in",
52
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
53
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
54
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
55
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
56
- className,
57
- )}
65
+ className={cn(menuSurface, className)}
58
66
  {...props}
59
67
  />
60
68
  ));
@@ -64,20 +72,21 @@ DropdownMenuSubContent.displayName =
64
72
  const DropdownMenuContent = React.forwardRef<
65
73
  React.ElementRef<typeof DropdownMenuPrimitive.Content>,
66
74
  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
67
- >(({ className, sideOffset = 4, ...props }, ref) => (
75
+ >(({ className, sideOffset = 4, onPointerDown, onCloseAutoFocus, ...props }, ref) => (
68
76
  <DropdownMenuPrimitive.Portal>
69
77
  <DropdownMenuPrimitive.Content
70
78
  ref={ref}
71
79
  sideOffset={sideOffset}
72
- className={cn(
73
- "z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border bg-popover p-1 text-popover-foreground shadow-[var(--edge-highlight),var(--shadow-card)]",
74
- "data-[state=closed]:animate-out data-[state=open]:animate-in",
75
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
76
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
77
- "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2",
78
- "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
79
- className,
80
- )}
80
+ // A choice made with a pointer returns focus to the trigger without the keyboard ring.
81
+ onPointerDown={(event) => { event.currentTarget.dataset.pointer = ""; onPointerDown?.(event); }}
82
+ onCloseAutoFocus={(event) => {
83
+ const content = event.currentTarget as HTMLElement;
84
+ onCloseAutoFocus?.(event);
85
+ if (content.dataset.pointer === undefined || event.defaultPrevented || document.activeElement !== document.body) return;
86
+ event.preventDefault();
87
+ document.getElementById(content.getAttribute("aria-labelledby") ?? "")?.focus({ focusVisible: false });
88
+ }}
89
+ className={cn(menuSurface, className)}
81
90
  {...props}
82
91
  />
83
92
  </DropdownMenuPrimitive.Portal>
@@ -92,14 +101,7 @@ const DropdownMenuItem = React.forwardRef<
92
101
  >(({ className, inset, ...props }, ref) => (
93
102
  <DropdownMenuPrimitive.Item
94
103
  ref={ref}
95
- className={cn(
96
- "relative flex cursor-pointer select-none items-center rounded-md px-2 py-1.5 text-sm outline-none transition-[color,background-color,box-shadow]",
97
- "focus:text-foreground",
98
- ixRow,
99
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
100
- inset && "pl-8",
101
- className,
102
- )}
104
+ className={cn(menuRow, "px-2", inset && "pl-8", className)}
103
105
  {...props}
104
106
  />
105
107
  ));
@@ -111,13 +113,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
111
113
  >(({ className, children, checked, ...props }, ref) => (
112
114
  <DropdownMenuPrimitive.CheckboxItem
113
115
  ref={ref}
114
- className={cn(
115
- "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]",
116
- "focus:text-foreground",
117
- ixRow,
118
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
119
- className,
120
- )}
116
+ className={cn(menuRow, "pr-2 pl-8", className)}
121
117
  checked={checked}
122
118
  {...props}
123
119
  >
@@ -138,13 +134,7 @@ const DropdownMenuRadioItem = React.forwardRef<
138
134
  >(({ className, children, ...props }, ref) => (
139
135
  <DropdownMenuPrimitive.RadioItem
140
136
  ref={ref}
141
- className={cn(
142
- "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pr-2 pl-8 text-sm outline-none transition-[color,background-color,box-shadow]",
143
- "focus:text-foreground",
144
- ixRow,
145
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
146
- className,
147
- )}
137
+ className={cn(menuRow, "pr-2 pl-8", className)}
148
138
  {...props}
149
139
  >
150
140
  <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
@@ -181,7 +171,7 @@ const DropdownMenuSeparator = React.forwardRef<
181
171
  >(({ className, ...props }, ref) => (
182
172
  <DropdownMenuPrimitive.Separator
183
173
  ref={ref}
184
- className={cn("-mx-1 my-1 h-px bg-border", className)}
174
+ className={cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className)}
185
175
  {...props}
186
176
  />
187
177
  ));
@@ -156,7 +156,7 @@ const SelectSeparator = React.forwardRef<
156
156
  >(({ className, ...props }, ref) => (
157
157
  <SelectPrimitive.Separator
158
158
  ref={ref}
159
- className={cn("-mx-1 my-1 h-px bg-border", className)}
159
+ className={cn("-mx-1 my-1 h-px bg-[var(--border-strong)]", className)}
160
160
  {...props}
161
161
  />
162
162
  ));