@plannotator/ui 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,51 +1,58 @@
1
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
1
+ import { Menu as MenuPrimitive } from "@base-ui/react/menu";
2
2
  import { Check, ChevronRight, Circle } from "lucide-react";
3
3
  import type * as React from "react";
4
4
 
5
5
  import { cn } from "../../lib/utils";
6
6
 
7
7
  /**
8
- * DropdownMenu — Radix-backed menu primitive (shadcn-style). Replaces the plan app's
8
+ * DropdownMenu — Base UI Menu-backed primitive (shadcn-style). Replaces the plan app's
9
9
  * hand-rolled Approve dropdown / label picker / header menus. Icons via lucide-react.
10
10
  */
11
- function DropdownMenu({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
12
- return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
11
+ function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {
12
+ return <MenuPrimitive.Root {...props} />;
13
13
  }
14
14
 
15
- function DropdownMenuPortal({
16
- ...props
17
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
18
- return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
15
+ function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
16
+ return <MenuPrimitive.Portal {...props} />;
19
17
  }
20
18
 
21
- function DropdownMenuTrigger({
22
- ...props
23
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
24
- return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
19
+ function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
20
+ return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
25
21
  }
26
22
 
23
+ const dropdownMenuPopupClassName =
24
+ "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground origin-[var(--transform-origin)] transition-[opacity,scale] duration-150 data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95";
25
+
27
26
  function DropdownMenuContent({
28
27
  className,
28
+ side,
29
29
  sideOffset = 4,
30
+ align,
31
+ alignOffset,
30
32
  ...props
31
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
33
+ }: MenuPrimitive.Popup.Props &
34
+ Pick<MenuPrimitive.Positioner.Props, "side" | "sideOffset" | "align" | "alignOffset">) {
32
35
  return (
33
- <DropdownMenuPrimitive.Portal>
34
- <DropdownMenuPrimitive.Content
35
- data-slot="dropdown-menu-content"
36
+ <MenuPrimitive.Portal>
37
+ <MenuPrimitive.Positioner
38
+ className="isolate z-50 outline-none"
39
+ side={side}
36
40
  sideOffset={sideOffset}
37
- className={cn(
38
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out 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",
39
- className,
40
- )}
41
- {...props}
42
- />
43
- </DropdownMenuPrimitive.Portal>
41
+ align={align}
42
+ alignOffset={alignOffset}
43
+ >
44
+ <MenuPrimitive.Popup
45
+ data-slot="dropdown-menu-content"
46
+ className={cn(dropdownMenuPopupClassName, "shadow-md", className)}
47
+ {...props}
48
+ />
49
+ </MenuPrimitive.Positioner>
50
+ </MenuPrimitive.Portal>
44
51
  );
45
52
  }
46
53
 
47
- function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
48
- return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
54
+ function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {
55
+ return <MenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
49
56
  }
50
57
 
51
58
  function DropdownMenuItem({
@@ -53,17 +60,17 @@ function DropdownMenuItem({
53
60
  inset,
54
61
  variant = "default",
55
62
  ...props
56
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
63
+ }: MenuPrimitive.Item.Props & {
57
64
  inset?: boolean;
58
65
  variant?: "default" | "destructive";
59
66
  }) {
60
67
  return (
61
- <DropdownMenuPrimitive.Item
68
+ <MenuPrimitive.Item
62
69
  data-slot="dropdown-menu-item"
63
70
  data-inset={inset}
64
71
  data-variant={variant}
65
72
  className={cn(
66
- "relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1.5 font-medium outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
73
+ "relative flex cursor-default select-none items-center gap-2 rounded-md px-2 py-1.5 font-medium outline-hidden data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:data-[highlighted]:bg-destructive/10 data-[variant=destructive]:data-[highlighted]:text-destructive dark:data-[variant=destructive]:data-[highlighted]:bg-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
67
74
  className,
68
75
  )}
69
76
  {...props}
@@ -76,54 +83,52 @@ function DropdownMenuCheckboxItem({
76
83
  children,
77
84
  checked,
78
85
  ...props
79
- }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {
86
+ }: MenuPrimitive.CheckboxItem.Props) {
80
87
  return (
81
- <DropdownMenuPrimitive.CheckboxItem
88
+ <MenuPrimitive.CheckboxItem
82
89
  data-slot="dropdown-menu-checkbox-item"
83
90
  className={cn(
84
- "relative flex cursor-default select-none items-center gap-2 rounded-md py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
91
+ "relative flex cursor-default select-none items-center gap-2 rounded-md py-1.5 pl-8 pr-2 text-sm outline-hidden data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
85
92
  className,
86
93
  )}
87
94
  checked={checked}
88
95
  {...props}
89
96
  >
90
97
  <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
91
- <DropdownMenuPrimitive.ItemIndicator>
98
+ <MenuPrimitive.CheckboxItemIndicator>
92
99
  <Check className="size-4" />
93
- </DropdownMenuPrimitive.ItemIndicator>
100
+ </MenuPrimitive.CheckboxItemIndicator>
94
101
  </span>
95
102
  {children}
96
- </DropdownMenuPrimitive.CheckboxItem>
103
+ </MenuPrimitive.CheckboxItem>
97
104
  );
98
105
  }
99
106
 
100
- function DropdownMenuRadioGroup({
101
- ...props
102
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
103
- return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
107
+ function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
108
+ return <MenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
104
109
  }
105
110
 
106
111
  function DropdownMenuRadioItem({
107
112
  className,
108
113
  children,
109
114
  ...props
110
- }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {
115
+ }: MenuPrimitive.RadioItem.Props) {
111
116
  return (
112
- <DropdownMenuPrimitive.RadioItem
117
+ <MenuPrimitive.RadioItem
113
118
  data-slot="dropdown-menu-radio-item"
114
119
  className={cn(
115
- "relative flex cursor-default select-none items-center gap-2 rounded-md py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
120
+ "relative flex cursor-default select-none items-center gap-2 rounded-md py-1.5 pl-8 pr-2 text-sm outline-hidden data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
116
121
  className,
117
122
  )}
118
123
  {...props}
119
124
  >
120
125
  <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
121
- <DropdownMenuPrimitive.ItemIndicator>
126
+ <MenuPrimitive.RadioItemIndicator>
122
127
  <Circle className="size-2 fill-current" />
123
- </DropdownMenuPrimitive.ItemIndicator>
128
+ </MenuPrimitive.RadioItemIndicator>
124
129
  </span>
125
130
  {children}
126
- </DropdownMenuPrimitive.RadioItem>
131
+ </MenuPrimitive.RadioItem>
127
132
  );
128
133
  }
129
134
 
@@ -131,9 +136,9 @@ function DropdownMenuLabel({
131
136
  className,
132
137
  inset,
133
138
  ...props
134
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }) {
139
+ }: MenuPrimitive.GroupLabel.Props & { inset?: boolean }) {
135
140
  return (
136
- <DropdownMenuPrimitive.Label
141
+ <MenuPrimitive.GroupLabel
137
142
  data-slot="dropdown-menu-label"
138
143
  data-inset={inset}
139
144
  className={cn("px-2 py-1.5 font-medium data-[inset]:pl-8", className)}
@@ -142,12 +147,9 @@ function DropdownMenuLabel({
142
147
  );
143
148
  }
144
149
 
145
- function DropdownMenuSeparator({
146
- className,
147
- ...props
148
- }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
150
+ function DropdownMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
149
151
  return (
150
- <DropdownMenuPrimitive.Separator
152
+ <MenuPrimitive.Separator
151
153
  data-slot="dropdown-menu-separator"
152
154
  className={cn("-mx-1 my-1 h-px bg-border", className)}
153
155
  {...props}
@@ -179,8 +181,8 @@ function DropdownMenuShortcut({
179
181
  );
180
182
  }
181
183
 
182
- function DropdownMenuSub({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
183
- return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
184
+ function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
185
+ return <MenuPrimitive.SubmenuRoot {...props} />;
184
186
  }
185
187
 
186
188
  function DropdownMenuSubTrigger({
@@ -188,36 +190,48 @@ function DropdownMenuSubTrigger({
188
190
  inset,
189
191
  children,
190
192
  ...props
191
- }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }) {
193
+ }: MenuPrimitive.SubmenuTrigger.Props & { inset?: boolean }) {
192
194
  return (
193
- <DropdownMenuPrimitive.SubTrigger
195
+ <MenuPrimitive.SubmenuTrigger
194
196
  data-slot="dropdown-menu-sub-trigger"
195
197
  data-inset={inset}
196
198
  className={cn(
197
- "flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
199
+ "flex cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-hidden data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[inset]:pl-8 data-[popup-open]:bg-accent data-[popup-open]:text-accent-foreground",
198
200
  className,
199
201
  )}
200
202
  {...props}
201
203
  >
202
204
  {children}
203
205
  <ChevronRight className="ml-auto size-4" />
204
- </DropdownMenuPrimitive.SubTrigger>
206
+ </MenuPrimitive.SubmenuTrigger>
205
207
  );
206
208
  }
207
209
 
208
210
  function DropdownMenuSubContent({
209
211
  className,
212
+ side = "right",
213
+ sideOffset = 0,
214
+ align = "start",
215
+ alignOffset = -3,
210
216
  ...props
211
- }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
217
+ }: MenuPrimitive.Popup.Props &
218
+ Pick<MenuPrimitive.Positioner.Props, "side" | "sideOffset" | "align" | "alignOffset">) {
212
219
  return (
213
- <DropdownMenuPrimitive.SubContent
214
- data-slot="dropdown-menu-sub-content"
215
- className={cn(
216
- "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out 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",
217
- className,
218
- )}
219
- {...props}
220
- />
220
+ <MenuPrimitive.Portal>
221
+ <MenuPrimitive.Positioner
222
+ className="isolate z-50 outline-none"
223
+ side={side}
224
+ sideOffset={sideOffset}
225
+ align={align}
226
+ alignOffset={alignOffset}
227
+ >
228
+ <MenuPrimitive.Popup
229
+ data-slot="dropdown-menu-sub-content"
230
+ className={cn(dropdownMenuPopupClassName, "shadow-lg", className)}
231
+ {...props}
232
+ />
233
+ </MenuPrimitive.Positioner>
234
+ </MenuPrimitive.Portal>
221
235
  );
222
236
  }
223
237
 
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import * as TabsPrimitive from "@radix-ui/react-tabs";
2
+ import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
3
3
  import { cn } from "../../lib/utils";
4
4
 
5
5
  const Tabs = TabsPrimitive.Root;
@@ -14,18 +14,18 @@ const TabsList = React.forwardRef<
14
14
  {...props}
15
15
  />
16
16
  ));
17
- TabsList.displayName = TabsPrimitive.List.displayName;
17
+ TabsList.displayName = "TabsList";
18
18
 
19
19
  const TabsTrigger = React.forwardRef<
20
- React.ComponentRef<typeof TabsPrimitive.Trigger>,
21
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
20
+ React.ComponentRef<typeof TabsPrimitive.Tab>,
21
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Tab>
22
22
  >(({ className, ...props }, ref) => (
23
- <TabsPrimitive.Trigger
23
+ <TabsPrimitive.Tab
24
24
  ref={ref}
25
25
  className={cn(
26
26
  "inline-flex items-center gap-2 rounded-md px-3 py-1.5 text-[13px] font-medium text-foreground",
27
27
  "hover:bg-surface-1",
28
- "data-[state=active]:bg-primary/10 data-[state=active]:text-foreground",
28
+ "data-active:bg-primary/10 data-active:text-foreground",
29
29
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50",
30
30
  "disabled:pointer-events-none disabled:opacity-50",
31
31
  className,
@@ -33,14 +33,14 @@ const TabsTrigger = React.forwardRef<
33
33
  {...props}
34
34
  />
35
35
  ));
36
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
36
+ TabsTrigger.displayName = "TabsTrigger";
37
37
 
38
38
  const TabsContent = React.forwardRef<
39
- React.ComponentRef<typeof TabsPrimitive.Content>,
40
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
39
+ React.ComponentRef<typeof TabsPrimitive.Panel>,
40
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Panel>
41
41
  >(({ className, ...props }, ref) => (
42
- <TabsPrimitive.Content ref={ref} className={cn("flex-1 outline-none", className)} {...props} />
42
+ <TabsPrimitive.Panel ref={ref} className={cn("flex-1 outline-none", className)} {...props} />
43
43
  ));
44
- TabsContent.displayName = TabsPrimitive.Content.displayName;
44
+ TabsContent.displayName = "TabsContent";
45
45
 
46
46
  export { Tabs, TabsList, TabsTrigger, TabsContent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plannotator/ui",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./components/*": "./components/*.tsx",
@@ -47,7 +47,7 @@
47
47
  "!test-setup"
48
48
  ],
49
49
  "dependencies": {
50
- "@plannotator/atomic-editor": "^0.5.0",
50
+ "@base-ui/react": "^1.6.0",
51
51
  "@codemirror/autocomplete": "^6.20.3",
52
52
  "@codemirror/commands": "^6.10.3",
53
53
  "@codemirror/lang-javascript": "^6.2.5",
@@ -62,18 +62,13 @@
62
62
  "@codemirror/view": "^6.43.0",
63
63
  "@fontsource-variable/geist-mono": "5.2.7",
64
64
  "@fontsource-variable/inter": "^5.2.8",
65
- "@pierre/diffs": "1.2.8",
66
65
  "@lezer/common": "^1.5.2",
67
66
  "@lezer/highlight": "^1.2.3",
67
+ "@pierre/diffs": "1.2.8",
68
+ "@plannotator/atomic-editor": "^0.5.0",
68
69
  "@plannotator/core": "0.22.0",
69
70
  "@plannotator/markdown-editor": "^0.2.0",
70
71
  "@plannotator/web-highlighter": "^0.8.1",
71
- "@radix-ui/react-dialog": "^1.1.15",
72
- "@radix-ui/react-dropdown-menu": "^2.1.16",
73
- "@radix-ui/react-popover": "^1.1.15",
74
- "@radix-ui/react-slot": "^1.2.4",
75
- "@radix-ui/react-tabs": "^1.1.13",
76
- "@radix-ui/react-tooltip": "^1.2.8",
77
72
  "@tanstack/react-table": "^8.21.3",
78
73
  "@viz-js/viz": "^3.25.0",
79
74
  "class-variance-authority": "^0.7.1",
@@ -93,8 +88,7 @@
93
88
  "peerDependencies": {
94
89
  "react": "^19.2.3",
95
90
  "react-dom": "^19.2.3",
96
- "tailwindcss": "^4.1.18",
97
- "tailwindcss-animate": "^1.0.7"
91
+ "tailwindcss": "^4.1.18"
98
92
  },
99
93
  "devDependencies": {
100
94
  "@happy-dom/global-registrator": "^20.10.1",
@@ -105,7 +99,6 @@
105
99
  "react": "^19.2.3",
106
100
  "react-dom": "^19.2.3",
107
101
  "tailwindcss": "^4.1.18",
108
- "tailwindcss-animate": "^1.0.7",
109
102
  "typescript": "~5.8.2",
110
103
  "vite": "^6.2.0"
111
104
  },