@sqlrooms/schema-tree 0.27.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,19 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
React components for rendering DuckDB database/schema/table/column trees in SQLRooms apps.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Installation
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```bash
|
|
6
|
+
npm install @sqlrooms/schema-tree @sqlrooms/duckdb @sqlrooms/ui
|
|
7
|
+
```
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
- Column type badges
|
|
9
|
-
- Context menus for actions (e.g. copying column names)
|
|
10
|
-
- Customizable node rendering
|
|
11
|
-
- Hover states and visual feedback
|
|
9
|
+
## What this package provides
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
- `TableSchemaTree` for rendering full schema hierarchies
|
|
12
|
+
- node components (`DatabaseTreeNode`, `SchemaTreeNode`, `TableTreeNode`, `ColumnTreeNode`)
|
|
13
|
+
- `TreeNodeActionsMenu` for context-style node actions
|
|
14
|
+
- `defaultRenderTableSchemaNode` for quick customization
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
- `ColumnTreeNode`: Specialized node for displaying column information
|
|
17
|
-
- `TreeNodeActionsMenu`: Reusable menu component for node actions
|
|
16
|
+
## Basic usage
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
```tsx
|
|
19
|
+
import {TableSchemaTree} from '@sqlrooms/schema-tree';
|
|
20
|
+
import {useRoomStore} from './store';
|
|
21
|
+
|
|
22
|
+
export function SchemaExplorer() {
|
|
23
|
+
const schemaTrees = useRoomStore((state) => state.db.schemaTrees ?? []);
|
|
24
|
+
|
|
25
|
+
if (!schemaTrees.length) {
|
|
26
|
+
return <div className="p-2 text-sm">No schema loaded yet.</div>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<TableSchemaTree
|
|
31
|
+
className="h-full"
|
|
32
|
+
schemaTrees={schemaTrees}
|
|
33
|
+
skipSingleDatabaseOrSchema
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Custom node rendering
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import {DbSchemaNode} from '@sqlrooms/duckdb';
|
|
43
|
+
import {defaultRenderTableSchemaNode, TableSchemaTree} from '@sqlrooms/schema-tree';
|
|
44
|
+
|
|
45
|
+
const renderNode = (node: DbSchemaNode, isOpen: boolean) => (
|
|
46
|
+
<div className={isOpen ? 'opacity-100' : 'opacity-90'}>
|
|
47
|
+
{defaultRenderTableSchemaNode(node)}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
<TableSchemaTree schemaTrees={schemaTrees} renderNode={renderNode} />;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Notes
|
|
55
|
+
|
|
56
|
+
- `schemaTrees` comes from the DuckDB slice (`state.db.schemaTrees`).
|
|
57
|
+
- Call `state.db.refreshTableSchemas()` after table changes to keep the tree up to date.
|
|
58
|
+
- This package is used by SQLRooms SQL editor table-structure panels.
|
|
@@ -3,6 +3,6 @@ import { cn, Slot } from '@sqlrooms/ui';
|
|
|
3
3
|
export function BaseTreeNode(props) {
|
|
4
4
|
const { className, asChild, children } = props;
|
|
5
5
|
const Comp = asChild ? Slot : 'div';
|
|
6
|
-
return (_jsx(Comp, { className: cn('hover:bg-foreground/10 h-[22px] w-full
|
|
6
|
+
return (_jsx(Comp, { className: cn('hover:bg-foreground/10 h-[22px] w-full grow cursor-pointer rounded-sm p-px select-none', className), children: _jsx("div", { className: cn('group relative flex w-full items-center overflow-hidden', className), children: _jsx("div", { className: "absolute flex h-full w-full items-center whitespace-nowrap", children: children }) }) }));
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=BaseTreeNode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseTreeNode.js","sourceRoot":"","sources":["../../src/nodes/BaseTreeNode.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAE,IAAI,EAAC,MAAM,cAAc,CAAC;AAGtC,MAAM,UAAU,YAAY,CAC1B,KAIE;IAEF,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACpC,OAAO,CACL,KAAC,IAAI,IACH,SAAS,EAAE,EAAE,CACX,
|
|
1
|
+
{"version":3,"file":"BaseTreeNode.js","sourceRoot":"","sources":["../../src/nodes/BaseTreeNode.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAE,IAAI,EAAC,MAAM,cAAc,CAAC;AAGtC,MAAM,UAAU,YAAY,CAC1B,KAIE;IAEF,MAAM,EAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAC,GAAG,KAAK,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACpC,OAAO,CACL,KAAC,IAAI,IACH,SAAS,EAAE,EAAE,CACX,wFAAwF,EACxF,SAAS,CACV,YAED,cACE,SAAS,EAAE,EAAE,CACX,yDAAyD,EACzD,SAAS,CACV,YAED,cAAK,SAAS,EAAC,4DAA4D,YACxE,QAAQ,GACL,GACF,GACD,CACR,CAAC;AACJ,CAAC","sourcesContent":["import {cn, Slot} from '@sqlrooms/ui';\nimport {PropsWithChildren} from 'react';\n\nexport function BaseTreeNode<T>(\n props: PropsWithChildren<{\n className?: string;\n nodeObject: T;\n asChild?: boolean;\n }>,\n) {\n const {className, asChild, children} = props;\n const Comp = asChild ? Slot : 'div';\n return (\n <Comp\n className={cn(\n 'hover:bg-foreground/10 h-[22px] w-full grow cursor-pointer rounded-sm p-px select-none',\n className,\n )}\n >\n <div\n className={cn(\n 'group relative flex w-full items-center overflow-hidden',\n className,\n )}\n >\n <div className=\"absolute flex h-full w-full items-center whitespace-nowrap\">\n {children}\n </div>\n </div>\n </Comp>\n );\n}\n"]}
|
|
@@ -15,7 +15,7 @@ import { forwardRef, } from 'react';
|
|
|
15
15
|
*/
|
|
16
16
|
export const TreeNodeActionsMenu = (props) => {
|
|
17
17
|
const { children } = props;
|
|
18
|
-
return (_jsx("div", { className: "absolute right-0
|
|
18
|
+
return (_jsx("div", { className: "absolute top-px right-0 h-full opacity-0 outline-hidden group-hover:opacity-100", children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("div", { className: "bg-muted text-muted-foreground hover:text-foreground flex h-full w-7 items-center justify-center p-0 outline-hidden transition-colors", children: _jsx(EllipsisVerticalIcon, { size: "15px", className: "relative top-[-1px]" }) }) }), _jsx(DropdownMenuContent, { align: "start", side: "bottom", children: children })] }) }));
|
|
19
19
|
};
|
|
20
20
|
export const TreeNodeActionsMenuItem = forwardRef(({ className, ...props }, ref) => {
|
|
21
21
|
const { onClick } = props;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeNodeActionsMenu.js","sourceRoot":"","sources":["../../src/nodes/TreeNodeActionsMenu.tsx"],"names":[],"mappings":";AAAA,4DAA4D;AAE5D,OAAO,EACL,EAAE,EACF,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAClD,OAAO,EAIL,UAAU,GAEX,MAAM,OAAO,CAAC;AAMf;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiC,CAAC,KAAK,EAAE,EAAE;IACzE,MAAM,EAAC,QAAQ,EAAC,GAAG,KAAK,CAAC;IACzB,OAAO,CACL,cAAK,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"TreeNodeActionsMenu.js","sourceRoot":"","sources":["../../src/nodes/TreeNodeActionsMenu.tsx"],"names":[],"mappings":";AAAA,4DAA4D;AAE5D,OAAO,EACL,EAAE,EACF,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,oBAAoB,EAAC,MAAM,cAAc,CAAC;AAClD,OAAO,EAIL,UAAU,GAEX,MAAM,OAAO,CAAC;AAMf;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiC,CAAC,KAAK,EAAE,EAAE;IACzE,MAAM,EAAC,QAAQ,EAAC,GAAG,KAAK,CAAC;IACzB,OAAO,CACL,cAAK,SAAS,EAAC,iFAAiF,YAC9F,MAAC,YAAY,eACX,KAAC,mBAAmB,IAAC,OAAO,kBAC1B,cAAK,SAAS,EAAC,uIAAuI,YACpJ,KAAC,oBAAoB,IAAC,IAAI,EAAC,MAAM,EAAC,SAAS,EAAC,qBAAqB,GAAG,GAChE,GACc,EACtB,KAAC,mBAAmB,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,EAAC,QAAQ,YAC7C,QAAQ,GACW,IACT,GACX,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAG/C,CAAC,EAAC,SAAS,EAAE,GAAG,KAAK,EAAC,EAAE,GAAG,EAAE,EAAE;IAC/B,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,CAAC;IACxB,OAAO,CACL,KAAC,gBAAgB,IACf,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,eAAe,EAAE,SAAS,CAAC,KACrC,KAAK,EACT,OAAO,EACL,OAAO;YACL,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE;gBACN,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,qCAAqC;gBAC5D,OAAO,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;YACH,CAAC,CAAC,SAAS,GAEf,CACH,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC","sourcesContent":["// Copyright 2022 Foursquare Labs, Inc. All Rights Reserved.\n\nimport {\n cn,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@sqlrooms/ui';\nimport {EllipsisVerticalIcon} from 'lucide-react';\nimport {\n ComponentPropsWithoutRef,\n ElementRef,\n FC,\n forwardRef,\n PropsWithChildren,\n} from 'react';\n\nexport type TreeNodeActionsMenuProps = PropsWithChildren<{\n className?: string;\n}>;\n\n/**\n * Component that renders a tree node \"more actions\" menu.\n * The menu items are passed as children.\n *\n * The menu is hidden by default and is shown when the user hovers over the node.\n * For this to work the parent element must have the `group` class.\n * It should also have classes `relative overflow-hidden`.\n *\n * @param children - The menu items.\n */\nexport const TreeNodeActionsMenu: FC<TreeNodeActionsMenuProps> = (props) => {\n const {children} = props;\n return (\n <div className=\"absolute top-px right-0 h-full opacity-0 outline-hidden group-hover:opacity-100\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <div className=\"bg-muted text-muted-foreground hover:text-foreground flex h-full w-7 items-center justify-center p-0 outline-hidden transition-colors\">\n <EllipsisVerticalIcon size=\"15px\" className=\"relative top-[-1px]\" />\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" side=\"bottom\">\n {children}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n\nexport const TreeNodeActionsMenuItem = forwardRef<\n ElementRef<typeof DropdownMenuItem>,\n ComponentPropsWithoutRef<typeof DropdownMenuItem>\n>(({className, ...props}, ref) => {\n const {onClick} = props;\n return (\n <DropdownMenuItem\n ref={ref}\n className={cn('gap-2 text-xs', className)}\n {...props}\n onClick={\n onClick\n ? (evt) => {\n evt.stopPropagation(); // prevent the tree node from closing\n onClick(evt);\n }\n : undefined\n }\n />\n );\n});\nTreeNodeActionsMenuItem.displayName = 'TreeNodeActionsMenuItem';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/schema-tree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"author": "SQLRooms Contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
"typedoc": "typedoc"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@sqlrooms/data-table": "0.
|
|
29
|
-
"@sqlrooms/duckdb": "0.
|
|
30
|
-
"@sqlrooms/ui": "0.
|
|
31
|
-
"@sqlrooms/utils": "0.
|
|
28
|
+
"@sqlrooms/data-table": "0.28.0",
|
|
29
|
+
"@sqlrooms/duckdb": "0.28.0",
|
|
30
|
+
"@sqlrooms/ui": "0.28.0",
|
|
31
|
+
"@sqlrooms/utils": "0.28.0",
|
|
32
32
|
"lucide-react": "^0.556.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"@types/react": "^19.1.13",
|
|
40
40
|
"@types/react-dom": "^19.1.9"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "dcac54f8adf77240e293c93d224a0ce9fd8142a9"
|
|
43
43
|
}
|