@hectasquare/medusa-plugin-category-tree 1.0.0 → 1.0.1

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.
@@ -5,6 +5,6 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const ui_1 = require("@medusajs/ui");
6
6
  const icons_1 = require("@medusajs/icons");
7
7
  const CanvasDock = ({ salesChannels, selectedStorefront, onSelectStorefront, direction, onToggleDirection, searchQuery, onSearchChange, onExpandAll, onCollapseAll, onFocusRoot, onFitView, onOpenCreateRoot, dirtyCount, isSaving, onSave, onReset, }) => {
8
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2 items-center pointer-events-auto", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2.5 px-3.5 py-2 bg-white/90 dark:bg-neutral-900/90 backdrop-blur-md border border-ui-border-base rounded-2xl shadow-xl transition-all", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 border-r border-ui-border-base pr-2.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-[11px] font-semibold text-ui-fg-muted uppercase tracking-wider", children: "Store:" }), (0, jsx_runtime_1.jsxs)("select", { value: selectedStorefront, onChange: (e) => onSelectStorefront(e.target.value), className: "text-xs bg-ui-bg-subtle text-ui-fg-base border border-ui-border-base rounded-lg px-2 py-1 font-medium focus:outline-none cursor-pointer", children: [(0, jsx_runtime_1.jsx)("option", { value: "all", children: "All Storefronts" }), salesChannels.map((sc) => ((0, jsx_runtime_1.jsx)("option", { value: sc.id, children: sc.name }, sc.id)))] })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center border-r border-ui-border-base pr-2.5", children: (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: direction === "TB" ? "Switch to Mind Map (Left-to-Right)" : "Switch to Vertical Tree (Top-to-Bottom)", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onToggleDirection, className: "flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-ui-bg-subtle text-ui-fg-base hover:bg-ui-bg-base border border-ui-border-base transition-colors", children: (0, jsx_runtime_1.jsx)("span", { children: direction === "TB" ? "⬇ Vertical" : "➡ Mind Map" }) }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative w-40 sm:w-48", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Search categories\u2026", value: searchQuery, onChange: (e) => onSearchChange(e.target.value), className: "w-full text-xs pl-7 pr-2.5 py-1 rounded-lg bg-ui-bg-subtle border border-ui-border-base text-ui-fg-base focus:bg-ui-bg-base focus:border-ui-border-interactive focus:outline-none transition-all placeholder:text-ui-fg-muted" }), (0, jsx_runtime_1.jsx)(icons_1.MagnifyingGlass, { className: "absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-ui-fg-muted pointer-events-none" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 border-l border-ui-border-base pl-2.5", children: [(0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Expand All Categories", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onExpandAll, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Expand" }) }), (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Collapse All Subcategories", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onCollapseAll, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Collapse" }) }), (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Focus on Root Categories", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onFocusRoot, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Root" }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1 border-l border-ui-border-base pl-2.5", children: (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Fit View (Center)", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onFitView, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.ArrowsPointingOut, { className: "w-3.5 h-3.5" }) }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "border-l border-ui-border-base pl-2.5", children: (0, jsx_runtime_1.jsxs)(ui_1.Button, { size: "small", variant: "secondary", onClick: onOpenCreateRoot, className: "flex items-center gap-1 text-xs h-7", children: [(0, jsx_runtime_1.jsx)(icons_1.Plus, { className: "w-3.5 h-3.5" }), (0, jsx_runtime_1.jsx)("span", { children: "New Root" })] }) })] }), dirtyCount > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 px-4 py-1.5 bg-blue-600 text-white rounded-full shadow-lg text-xs font-medium animate-in fade-in slide-in-from-top-2 duration-200", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "w-2 h-2 rounded-full bg-white animate-pulse" }), (0, jsx_runtime_1.jsxs)("span", { children: [dirtyCount, " categor", dirtyCount === 1 ? "y" : "ies", " repositioned"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 border-l border-blue-400 pl-2", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onReset, disabled: isSaving, className: "px-2 py-0.5 rounded hover:bg-blue-700 transition-colors text-blue-100 hover:text-white", children: "Reset" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onSave, disabled: isSaving, className: "px-3 py-0.5 rounded-full bg-white text-blue-700 font-semibold hover:bg-blue-50 transition-colors shadow-xs", children: isSaving ? "Saving…" : "Save Hierarchy" })] })] }))] }));
8
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-2 items-center pointer-events-auto", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2.5 px-3.5 py-2 bg-white/90 dark:bg-neutral-900/90 backdrop-blur-md border border-ui-border-base rounded-2xl shadow-xl transition-all", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1.5 border-r border-ui-border-base pr-2.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-[11px] font-semibold text-ui-fg-muted uppercase tracking-wider", children: "Store:" }), (0, jsx_runtime_1.jsxs)("select", { value: selectedStorefront, onChange: (e) => onSelectStorefront(e.target.value), className: "text-xs bg-ui-bg-subtle text-ui-fg-base border border-ui-border-base rounded-lg px-2 py-1 font-medium focus:outline-none cursor-pointer", children: [(0, jsx_runtime_1.jsx)("option", { value: "all", children: "All Storefronts" }), salesChannels.map((sc) => ((0, jsx_runtime_1.jsx)("option", { value: sc.id, children: sc.name }, sc.id)))] })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center border-r border-ui-border-base pr-2.5", children: (0, jsx_runtime_1.jsx)("button", { type: "button", title: direction === "TB" ? "Switch to Mind Map (Left-to-Right)" : "Switch to Vertical Tree (Top-to-Bottom)", onClick: onToggleDirection, className: "flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-ui-bg-subtle text-ui-fg-base hover:bg-ui-bg-base border border-ui-border-base transition-colors", children: (0, jsx_runtime_1.jsx)("span", { children: direction === "TB" ? "⬇ Vertical" : "➡ Mind Map" }) }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative w-40 sm:w-48", children: [(0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Search categories\u2026", value: searchQuery, onChange: (e) => onSearchChange(e.target.value), className: "w-full text-xs pl-7 pr-2.5 py-1 rounded-lg bg-ui-bg-subtle border border-ui-border-base text-ui-fg-base focus:bg-ui-bg-base focus:border-ui-border-interactive focus:outline-none transition-all placeholder:text-ui-fg-muted" }), (0, jsx_runtime_1.jsx)(icons_1.MagnifyingGlass, { className: "absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-ui-fg-muted pointer-events-none" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 border-l border-ui-border-base pl-2.5", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", title: "Expand All Categories", onClick: onExpandAll, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Expand" }), (0, jsx_runtime_1.jsx)("button", { type: "button", title: "Collapse All Subcategories", onClick: onCollapseAll, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Collapse" }), (0, jsx_runtime_1.jsx)("button", { type: "button", title: "Focus on Root Categories", onClick: onFocusRoot, className: "px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: "Root" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center gap-1 border-l border-ui-border-base pl-2.5", children: (0, jsx_runtime_1.jsx)("button", { type: "button", title: "Fit View (Center)", onClick: onFitView, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.ArrowsPointingOut, { className: "w-3.5 h-3.5" }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "border-l border-ui-border-base pl-2.5", children: (0, jsx_runtime_1.jsxs)(ui_1.Button, { size: "small", variant: "secondary", onClick: onOpenCreateRoot, className: "flex items-center gap-1 text-xs h-7", children: [(0, jsx_runtime_1.jsx)(icons_1.Plus, { className: "w-3.5 h-3.5" }), (0, jsx_runtime_1.jsx)("span", { children: "New Root" })] }) })] }), dirtyCount > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3 px-4 py-1.5 bg-blue-600 text-white rounded-full shadow-lg text-xs font-medium animate-in fade-in slide-in-from-top-2 duration-200", children: [(0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-1.5", children: [(0, jsx_runtime_1.jsx)("span", { className: "w-2 h-2 rounded-full bg-white animate-pulse" }), (0, jsx_runtime_1.jsxs)("span", { children: [dirtyCount, " categor", dirtyCount === 1 ? "y" : "ies", " repositioned"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-1 border-l border-blue-400 pl-2", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onReset, disabled: isSaving, className: "px-2 py-0.5 rounded hover:bg-blue-700 transition-colors text-blue-100 hover:text-white", children: "Reset" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onSave, disabled: isSaving, className: "px-3 py-0.5 rounded-full bg-white text-blue-700 font-semibold hover:bg-blue-50 transition-colors shadow-xs", children: isSaving ? "Saving…" : "Save Hierarchy" })] })] }))] }));
9
9
  };
10
10
  exports.CanvasDock = CanvasDock;
@@ -4,7 +4,6 @@ exports.CategoryNode = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_2 = require("@xyflow/react");
7
- const ui_1 = require("@medusajs/ui");
8
7
  const icons_1 = require("@medusajs/icons");
9
8
  const tier_bars_1 = require("./tier-bars");
10
9
  exports.CategoryNode = (0, react_1.memo)(({ id, data, selected }) => {
@@ -27,15 +26,15 @@ exports.CategoryNode = (0, react_1.memo)(({ id, data, selected }) => {
27
26
  onToggleCollapse(id);
28
27
  }, className: `ml-auto px-1.5 py-0.5 rounded text-[10px] font-medium flex items-center gap-0.5 transition-colors ${isCollapsed
29
28
  ? "bg-blue-50 text-blue-700 border border-blue-200 dark:bg-blue-950/60 dark:text-blue-300 dark:border-blue-800"
30
- : "bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-300"}`, title: isCollapsed ? "Click to expand subcategories" : "Click to collapse subcategories", children: [(0, jsx_runtime_1.jsx)("span", { children: isCollapsed ? "▸" : "▾" }), (0, jsx_runtime_1.jsx)("span", { children: isCollapsed ? `+${hiddenDescendantCount || category.children_count}` : category.children_count || "sub" })] }))] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "absolute -top-3 right-2 hidden group-hover:flex items-center gap-1 px-1.5 py-0.5 bg-ui-bg-base/95 backdrop-blur-sm border border-ui-border-base rounded-full shadow-md z-20", children: [(0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Add Subcategory", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
31
- e.stopPropagation();
32
- onAddChild(category);
33
- }, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.Plus, { className: "w-3.5 h-3.5" }) }) }), (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Edit Category", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
34
- e.stopPropagation();
35
- onEdit(category);
36
- }, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.PencilSquare, { className: "w-3.5 h-3.5" }) }) }), category.parent_category_id && ((0, jsx_runtime_1.jsx)(ui_1.Tooltip, { content: "Promote to Root (Detach)", children: (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: (e) => {
37
- e.stopPropagation();
38
- onDetach(id);
39
- }, className: "p-1 text-ui-fg-subtle hover:text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-950/50 rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.ArrowUturnLeft, { className: "w-3.5 h-3.5" }) }) }))] }), (0, jsx_runtime_1.jsx)(react_2.Handle, { type: "source", position: isTB ? react_2.Position.Bottom : react_2.Position.Right, className: "!w-2.5 !h-2.5 !bg-ui-border-interactive !border-2 !border-white dark:!border-neutral-900 transition-transform group-hover:scale-125" })] }));
29
+ : "bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-300"}`, title: isCollapsed ? "Click to expand subcategories" : "Click to collapse subcategories", children: [(0, jsx_runtime_1.jsx)("span", { children: isCollapsed ? "▸" : "▾" }), (0, jsx_runtime_1.jsx)("span", { children: isCollapsed ? `+${hiddenDescendantCount || category.children_count}` : category.children_count || "sub" })] }))] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "absolute -top-3 right-2 hidden group-hover:flex items-center gap-1 px-1.5 py-0.5 bg-ui-bg-base/95 backdrop-blur-sm border border-ui-border-base rounded-full shadow-md z-20", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", title: "Add Subcategory", onClick: (e) => {
30
+ e.stopPropagation();
31
+ onAddChild(category);
32
+ }, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.Plus, { className: "w-3.5 h-3.5" }) }), (0, jsx_runtime_1.jsx)("button", { type: "button", title: "Edit Category", onClick: (e) => {
33
+ e.stopPropagation();
34
+ onEdit(category);
35
+ }, className: "p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.PencilSquare, { className: "w-3.5 h-3.5" }) }), category.parent_category_id && ((0, jsx_runtime_1.jsx)("button", { type: "button", title: "Promote to Root (Detach)", onClick: (e) => {
36
+ e.stopPropagation();
37
+ onDetach(id);
38
+ }, className: "p-1 text-ui-fg-subtle hover:text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-950/50 rounded-full transition-colors", children: (0, jsx_runtime_1.jsx)(icons_1.ArrowUturnLeft, { className: "w-3.5 h-3.5" }) }))] }), (0, jsx_runtime_1.jsx)(react_2.Handle, { type: "source", position: isTB ? react_2.Position.Bottom : react_2.Position.Right, className: "!w-2.5 !h-2.5 !bg-ui-border-interactive !border-2 !border-white dark:!border-neutral-900 transition-transform group-hover:scale-125" })] }));
40
39
  });
41
40
  exports.CategoryNode.displayName = "CategoryNode";
@@ -238,6 +238,6 @@ const CanvasInner = () => {
238
238
  } })] }));
239
239
  };
240
240
  const CategoryTreeCanvas = () => {
241
- return ((0, jsx_runtime_1.jsx)(react_2.ReactFlowProvider, { children: (0, jsx_runtime_1.jsx)(CanvasInner, {}) }));
241
+ return ((0, jsx_runtime_1.jsx)(ui_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(react_2.ReactFlowProvider, { children: (0, jsx_runtime_1.jsx)(CanvasInner, {}) }) }));
242
242
  };
243
243
  exports.CategoryTreeCanvas = CategoryTreeCanvas;
@@ -4,9 +4,10 @@ exports.config = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const admin_sdk_1 = require("@medusajs/admin-sdk");
6
6
  const icons_1 = require("@medusajs/icons");
7
+ const ui_1 = require("@medusajs/ui");
7
8
  const category_tree_canvas_1 = require("../../components/category-tree/category-tree-canvas");
8
9
  const CategoryTreePage = () => {
9
- return (0, jsx_runtime_1.jsx)(category_tree_canvas_1.CategoryTreeCanvas, {});
10
+ return ((0, jsx_runtime_1.jsx)(ui_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(category_tree_canvas_1.CategoryTreeCanvas, {}) }));
10
11
  };
11
12
  exports.config = (0, admin_sdk_1.defineRouteConfig)({
12
13
  label: "Category Tree",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hectasquare/medusa-plugin-category-tree",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AAA Interactive Category Tree & Mind Map for Medusa v2 Admin with drag-and-drop reparenting, tier indicators, superscript ranks, multi-storefront filtering, and NotebookLM-style subtree collapse.",
5
5
  "author": "HectaSquare Team",
6
6
  "license": "MIT",
@@ -1,5 +1,5 @@
1
1
  import React from "react"
2
- import { Button, Tooltip } from "@medusajs/ui"
2
+ import { Button } from "@medusajs/ui"
3
3
  import {
4
4
  ArrowsPointingOut,
5
5
  MagnifyingGlass,
@@ -74,15 +74,14 @@ export const CanvasDock: React.FC<CanvasDockProps> = ({
74
74
  </div>
75
75
 
76
76
  <div className="flex items-center border-r border-ui-border-base pr-2.5">
77
- <Tooltip content={direction === "TB" ? "Switch to Mind Map (Left-to-Right)" : "Switch to Vertical Tree (Top-to-Bottom)"}>
78
- <button
79
- type="button"
80
- onClick={onToggleDirection}
81
- className="flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-ui-bg-subtle text-ui-fg-base hover:bg-ui-bg-base border border-ui-border-base transition-colors"
82
- >
83
- <span>{direction === "TB" ? "⬇ Vertical" : "➡ Mind Map"}</span>
84
- </button>
85
- </Tooltip>
77
+ <button
78
+ type="button"
79
+ title={direction === "TB" ? "Switch to Mind Map (Left-to-Right)" : "Switch to Vertical Tree (Top-to-Bottom)"}
80
+ onClick={onToggleDirection}
81
+ className="flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-lg bg-ui-bg-subtle text-ui-fg-base hover:bg-ui-bg-base border border-ui-border-base transition-colors"
82
+ >
83
+ <span>{direction === "TB" ? "⬇ Vertical" : "➡ Mind Map"}</span>
84
+ </button>
86
85
  </div>
87
86
 
88
87
  <div className="relative w-40 sm:w-48">
@@ -97,47 +96,43 @@ export const CanvasDock: React.FC<CanvasDockProps> = ({
97
96
  </div>
98
97
 
99
98
  <div className="flex items-center gap-1 border-l border-ui-border-base pl-2.5">
100
- <Tooltip content="Expand All Categories">
101
- <button
102
- type="button"
103
- onClick={onExpandAll}
104
- className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
105
- >
106
- Expand
107
- </button>
108
- </Tooltip>
109
-
110
- <Tooltip content="Collapse All Subcategories">
111
- <button
112
- type="button"
113
- onClick={onCollapseAll}
114
- className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
115
- >
116
- Collapse
117
- </button>
118
- </Tooltip>
119
-
120
- <Tooltip content="Focus on Root Categories">
121
- <button
122
- type="button"
123
- onClick={onFocusRoot}
124
- className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
125
- >
126
- Root
127
- </button>
128
- </Tooltip>
99
+ <button
100
+ type="button"
101
+ title="Expand All Categories"
102
+ onClick={onExpandAll}
103
+ className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
104
+ >
105
+ Expand
106
+ </button>
107
+
108
+ <button
109
+ type="button"
110
+ title="Collapse All Subcategories"
111
+ onClick={onCollapseAll}
112
+ className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
113
+ >
114
+ Collapse
115
+ </button>
116
+
117
+ <button
118
+ type="button"
119
+ title="Focus on Root Categories"
120
+ onClick={onFocusRoot}
121
+ className="px-2 py-1 text-xs font-medium text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
122
+ >
123
+ Root
124
+ </button>
129
125
  </div>
130
126
 
131
127
  <div className="flex items-center gap-1 border-l border-ui-border-base pl-2.5">
132
- <Tooltip content="Fit View (Center)">
133
- <button
134
- type="button"
135
- onClick={onFitView}
136
- className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
137
- >
138
- <ArrowsPointingOut className="w-3.5 h-3.5" />
139
- </button>
140
- </Tooltip>
128
+ <button
129
+ type="button"
130
+ title="Fit View (Center)"
131
+ onClick={onFitView}
132
+ className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-md transition-colors"
133
+ >
134
+ <ArrowsPointingOut className="w-3.5 h-3.5" />
135
+ </button>
141
136
  </div>
142
137
 
143
138
  <div className="border-l border-ui-border-base pl-2.5">
@@ -1,6 +1,6 @@
1
1
  import React, { memo } from "react"
2
2
  import { Handle, Position } from "@xyflow/react"
3
- import { Text, Tooltip } from "@medusajs/ui"
3
+ import { Text } from "@medusajs/ui"
4
4
  import { Plus, PencilSquare, Folder, ArrowUturnLeft } from "@medusajs/icons"
5
5
  import { TierBars } from "./tier-bars"
6
6
  import { CategoryNodeData } from "./types"
@@ -134,45 +134,42 @@ export const CategoryNode = memo(({ id, data, selected }: CategoryNodeProps) =>
134
134
  </div>
135
135
 
136
136
  <div className="absolute -top-3 right-2 hidden group-hover:flex items-center gap-1 px-1.5 py-0.5 bg-ui-bg-base/95 backdrop-blur-sm border border-ui-border-base rounded-full shadow-md z-20">
137
- <Tooltip content="Add Subcategory">
138
- <button
139
- type="button"
140
- onClick={(e) => {
141
- e.stopPropagation()
142
- onAddChild(category)
143
- }}
144
- className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors"
145
- >
146
- <Plus className="w-3.5 h-3.5" />
147
- </button>
148
- </Tooltip>
137
+ <button
138
+ type="button"
139
+ title="Add Subcategory"
140
+ onClick={(e) => {
141
+ e.stopPropagation()
142
+ onAddChild(category)
143
+ }}
144
+ className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors"
145
+ >
146
+ <Plus className="w-3.5 h-3.5" />
147
+ </button>
148
+
149
+ <button
150
+ type="button"
151
+ title="Edit Category"
152
+ onClick={(e) => {
153
+ e.stopPropagation()
154
+ onEdit(category)
155
+ }}
156
+ className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors"
157
+ >
158
+ <PencilSquare className="w-3.5 h-3.5" />
159
+ </button>
149
160
 
150
- <Tooltip content="Edit Category">
161
+ {category.parent_category_id && (
151
162
  <button
152
163
  type="button"
164
+ title="Promote to Root (Detach)"
153
165
  onClick={(e) => {
154
166
  e.stopPropagation()
155
- onEdit(category)
167
+ onDetach(id)
156
168
  }}
157
- className="p-1 text-ui-fg-subtle hover:text-ui-fg-base hover:bg-ui-bg-subtle rounded-full transition-colors"
169
+ className="p-1 text-ui-fg-subtle hover:text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-950/50 rounded-full transition-colors"
158
170
  >
159
- <PencilSquare className="w-3.5 h-3.5" />
171
+ <ArrowUturnLeft className="w-3.5 h-3.5" />
160
172
  </button>
161
- </Tooltip>
162
-
163
- {category.parent_category_id && (
164
- <Tooltip content="Promote to Root (Detach)">
165
- <button
166
- type="button"
167
- onClick={(e) => {
168
- e.stopPropagation()
169
- onDetach(id)
170
- }}
171
- className="p-1 text-ui-fg-subtle hover:text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-950/50 rounded-full transition-colors"
172
- >
173
- <ArrowUturnLeft className="w-3.5 h-3.5" />
174
- </button>
175
- </Tooltip>
176
173
  )}
177
174
  </div>
178
175
 
@@ -13,7 +13,7 @@ import {
13
13
  ReactFlowProvider,
14
14
  } from "@xyflow/react"
15
15
  import "@xyflow/react/dist/style.css"
16
- import { toast } from "@medusajs/ui"
16
+ import { toast, TooltipProvider } from "@medusajs/ui"
17
17
 
18
18
  import { CategoryNode } from "./category-node"
19
19
  import { CustomSmoothStepEdge } from "./custom-edge"
@@ -390,8 +390,10 @@ const CanvasInner: React.FC = () => {
390
390
 
391
391
  export const CategoryTreeCanvas: React.FC = () => {
392
392
  return (
393
- <ReactFlowProvider>
394
- <CanvasInner />
395
- </ReactFlowProvider>
393
+ <TooltipProvider>
394
+ <ReactFlowProvider>
395
+ <CanvasInner />
396
+ </ReactFlowProvider>
397
+ </TooltipProvider>
396
398
  )
397
399
  }
@@ -1,9 +1,14 @@
1
1
  import { defineRouteConfig } from "@medusajs/admin-sdk"
2
2
  import { Folder } from "@medusajs/icons"
3
+ import { TooltipProvider } from "@medusajs/ui"
3
4
  import { CategoryTreeCanvas } from "../../components/category-tree/category-tree-canvas"
4
5
 
5
6
  const CategoryTreePage = () => {
6
- return <CategoryTreeCanvas />
7
+ return (
8
+ <TooltipProvider>
9
+ <CategoryTreeCanvas />
10
+ </TooltipProvider>
11
+ )
7
12
  }
8
13
 
9
14
  export const config = defineRouteConfig({