Skip to content

Commit 2ea4030

Browse files
committed
improved examples script
1 parent b0423d8 commit 2ea4030

File tree

8 files changed

+67
-124
lines changed

8 files changed

+67
-124
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ storybook-static
2020
/packages/docs/.cache
2121
/packages/docs/public
2222
/packages/docs/docs/md-test
23+
/packages/docs/docs/examples.mdx
2324
/examples/*/dist

examples/basic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "@headless-tree/example-basic",
3+
"description": "Basic example of Headless Tree with React",
34
"private": true,
45
"version": "0.0.0",
56
"type": "module",

examples/basic/readme.MD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Headless Tree Sample: basic
1+
# Basic example of Headless Tree with React
22

33
To run this example:
44

55
- `npm install` to install dependencies
66
- `npm start` to start the dev server
77

8-
You can run this sample from [Stackblitz](https://stackblitz.com/github/lukasbach/headless-tree/tree/main/examples/basic?embed=1&theme=dark&preset=node&file=src/main.tsx) or [CodeSandbox](https://codesandbox.io/p/devbox/github/lukasbach/headless-tree/tree/main/examples/basic?embed=1&theme=dark&file=src/main.tsx). The source code is available on [GitHub](https://github.com/lukasbach/headless-tree/tree/main/examples/basic).
8+
You can run this sample from [Stackblitz](https://stackblitz.com/github/lukasbach/headless-tree/tree/main/examples/basic?preset=node&file=src/main.tsx) or [CodeSandbox](https://codesandbox.io/p/devbox/github/lukasbach/headless-tree/tree/main/examples/basic?file=src/main.tsx). The source code is available on [GitHub](https://github.com/lukasbach/headless-tree/tree/main/examples/basic).
99

examples/basic/src/main.tsx

Lines changed: 28 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,17 @@
1-
import { Fragment, StrictMode } from "react";
1+
import { StrictMode } from "react";
22
import { createRoot } from "react-dom/client";
33
import "./style.css";
44
import {
5-
DragTarget,
6-
ItemInstance,
5+
asyncDataLoaderFeature,
76
createOnDropHandler,
87
dragAndDropFeature,
98
hotkeysCoreFeature,
10-
insertItemsAtTarget,
119
keyboardDragAndDropFeature,
12-
removeItemsFromParents,
13-
renamingFeature,
14-
searchFeature,
1510
selectionFeature,
16-
syncDataLoaderFeature,
1711
} from "@headless-tree/core";
1812
import { AssistiveTreeDescription, useTree } from "@headless-tree/react";
1913
import cx from "classnames";
20-
import { DemoItem, data, syncDataLoader } from "./data";
21-
22-
let newItemId = 0;
23-
const insertNewItem = (dataTransfer: DataTransfer) => {
24-
const newId = `new-${newItemId++}`;
25-
data[newId] = {
26-
name: dataTransfer.getData("text/plain"),
27-
};
28-
return newId;
29-
};
30-
31-
const onDropForeignDragObject = (
32-
dataTransfer: DataTransfer,
33-
target: DragTarget<DemoItem>,
34-
) => {
35-
const newId = insertNewItem(dataTransfer);
36-
insertItemsAtTarget([newId], target, (item, newChildrenIds) => {
37-
data[item.getId()].children = newChildrenIds;
38-
});
39-
};
40-
const onCompleteForeignDrop = (items: ItemInstance<DemoItem>[]) =>
41-
removeItemsFromParents(items, (item, newChildren) => {
42-
item.getItemData().children = newChildren;
43-
});
44-
const onRename = (item: ItemInstance<DemoItem>, value: string) => {
45-
data[item.getId()].name = value;
46-
};
47-
const getCssClass = (item: ItemInstance<DemoItem>) =>
48-
cx("treeitem", {
49-
focused: item.isFocused(),
50-
expanded: item.isExpanded(),
51-
selected: item.isSelected(),
52-
folder: item.isFolder(),
53-
drop: item.isDragTarget(),
54-
searchmatch: item.isMatchingSearch(),
55-
});
14+
import { DemoItem, asyncDataLoader, data } from "./data";
5615

5716
export const Tree = () => {
5817
const tree = useTree<DemoItem>({
@@ -61,96 +20,48 @@ export const Tree = () => {
6120
selectedItems: ["banana", "orange"],
6221
},
6322
rootItemId: "root",
64-
getItemName: (item) => item.getItemData().name,
65-
isItemFolder: (item) => !!item.getItemData().children,
23+
getItemName: (item) => item.getItemData()?.name,
24+
isItemFolder: (item) => !!item.getItemData()?.children,
6625
canReorder: true,
6726
onDrop: createOnDropHandler((item, newChildren) => {
6827
data[item.getId()].children = newChildren;
6928
}),
70-
onRename,
71-
onDropForeignDragObject,
72-
onCompleteForeignDrop,
73-
createForeignDragObject: (items) => ({
74-
format: "text/plain",
75-
data: items.map((item) => item.getId()).join(","),
76-
}),
77-
canDropForeignDragObject: (_, target) => target.item.isFolder(),
7829
indent: 20,
79-
dataLoader: syncDataLoader,
30+
dataLoader: asyncDataLoader,
8031
features: [
81-
syncDataLoaderFeature,
32+
asyncDataLoaderFeature,
8233
selectionFeature,
8334
hotkeysCoreFeature,
8435
dragAndDropFeature,
8536
keyboardDragAndDropFeature,
86-
renamingFeature,
87-
searchFeature,
8837
],
8938
});
9039

9140
return (
92-
<>
93-
{tree.isSearchOpen() && (
94-
<div className="searchbox">
95-
<input {...tree.getSearchInputElementProps()} />
96-
<span>({tree.getSearchMatchingItems().length} matches)</span>
97-
</div>
98-
)}
99-
<div {...tree.getContainerProps()} className="tree">
100-
<AssistiveTreeDescription tree={tree} />
101-
{tree.getItems().map((item) => (
102-
<Fragment key={item.getId()}>
103-
{item.isRenaming() ? (
104-
<div
105-
className="renaming-item"
106-
style={{ marginLeft: `${item.getItemMeta().level * 20}px` }}
107-
>
108-
<input {...item.getRenameInputProps()} />
109-
</div>
110-
) : (
111-
<button
112-
{...item.getProps()}
113-
style={{ paddingLeft: `${item.getItemMeta().level * 20}px` }}
114-
>
115-
<div className={getCssClass(item)}>{item.getItemName()}</div>
116-
</button>
117-
)}
118-
</Fragment>
119-
))}
120-
<div style={tree.getDragLineStyle()} className="dragline" />
121-
</div>
122-
123-
<div className="actionbar">
124-
<div
125-
className="foreign-dragsource"
126-
draggable
127-
onDragStart={(e) => {
128-
e.dataTransfer.setData("text/plain", "hello world");
129-
}}
130-
>
131-
Drag me into the tree!
132-
</div>
133-
<div
134-
className="foreign-dropzone"
135-
onDrop={(e) => {
136-
alert(JSON.stringify(e.dataTransfer.getData("text/plain")));
137-
console.log(e.dataTransfer.getData("text/plain"));
138-
}}
139-
onDragOver={(e) => e.preventDefault()}
140-
>
141-
Drop items here!
142-
</div>
143-
<button className="actionbtn" onClick={() => tree.openSearch()}>
144-
Search items
145-
</button>
41+
<div {...tree.getContainerProps()} className="tree">
42+
<AssistiveTreeDescription tree={tree} />
43+
{tree.getItems().map((item) => (
14644
<button
147-
className="actionbtn"
148-
onClick={() => tree.getItemInstance("fruit").startRenaming()}
45+
key={item.getId()}
46+
{...item.getProps()}
47+
style={{ paddingLeft: `${item.getItemMeta().level * 20}px` }}
14948
>
150-
Rename Fruit
49+
<div
50+
className={cx("treeitem", {
51+
focused: item.isFocused(),
52+
expanded: item.isExpanded(),
53+
selected: item.isSelected(),
54+
folder: item.isFolder(),
55+
drop: item.isDragTarget(),
56+
searchmatch: item.isMatchingSearch(),
57+
})}
58+
>
59+
{item.getItemName()}
60+
</div>
15161
</button>
152-
</div>
153-
</>
62+
))}
63+
<div style={tree.getDragLineStyle()} className="dragline" />
64+
</div>
15465
);
15566
};
15667

examples/react-compiler/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "@headless-tree/example-react-compiler",
3+
"description": "Headless Tree with React Compiler enabled",
34
"private": true,
45
"version": "0.0.0",
56
"type": "module",

examples/react-compiler/readme.MD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Headless Tree Sample: react-compiler
1+
# Headless Tree with React Compiler enabled
22

33
To run this example:
44

55
- `npm install` to install dependencies
66
- `npm start` to start the dev server
77

8-
You can run this sample from [Stackblitz](https://stackblitz.com/github/lukasbach/headless-tree/tree/main/examples/react-compiler?embed=1&theme=dark&preset=node&file=src/main.tsx) or [CodeSandbox](https://codesandbox.io/p/devbox/github/lukasbach/headless-tree/tree/main/examples/react-compiler?embed=1&theme=dark&file=src/main.tsx). The source code is available on [GitHub](https://github.com/lukasbach/headless-tree/tree/main/examples/react-compiler).
8+
You can run this sample from [Stackblitz](https://stackblitz.com/github/lukasbach/headless-tree/tree/main/examples/react-compiler?preset=node&file=src/main.tsx) or [CodeSandbox](https://codesandbox.io/p/devbox/github/lukasbach/headless-tree/tree/main/examples/react-compiler?file=src/main.tsx). The source code is available on [GitHub](https://github.com/lukasbach/headless-tree/tree/main/examples/react-compiler).
99

scripts/prepare.mjs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ await fs.copy(
2525

2626
// ------ EXAMPLES REDUNDANT FILES COPYING ------
2727
const samples = await glob('./examples/*/package.json');
28+
let samplesList = "";
2829

2930
for (const sample of samples) {
31+
const pkg = await fs.readJSON(sample);
3032
const sampleName = /\.\/examples\/(.*)\/package.json/.exec(sample)[1];
3133
await fs.copy(
3234
path.join(__dirname, "../packages/sb-react/.storybook/style.css"),
@@ -41,10 +43,19 @@ for (const sample of samples) {
4143
const stackblitz = `https://stackblitz.com/github/lukasbach/headless-tree/tree/main/examples/${sampleName}?preset=node&file=src/main.tsx`;
4244
const codesandbox = `https://codesandbox.io/p/devbox/github/lukasbach/headless-tree/tree/main/examples/${sampleName}?file=src/main.tsx`;
4345
const github = `https://github.com/lukasbach/headless-tree/tree/main/examples/${sampleName}`;
46+
samplesList += `- ${pkg.description}: [Stackblitz](${stackblitz}), [CodeSandbox](${codesandbox}), [GitHub](${github})\n`;
4447
await fs.writeFile(
4548
path.join(__dirname, `../examples/${sampleName}/readme.MD`),
46-
`# Headless Tree Sample: ${sampleName}\n\nTo run this example:\n\n- \`npm install\` to install dependencies\n- \`npm start\` to start the dev server\n\n`
49+
`# ${pkg.description}\n\nTo run this example:\n\n- \`npm install\` to install dependencies\n- \`npm start\` to start the dev server\n\n`
4750
+ `You can run this sample from [Stackblitz](${stackblitz}) or [CodeSandbox](${codesandbox}). The source code is available on [GitHub](${github}).\n\n`,
4851
{ encoding: "utf8" }
49-
)
50-
}
52+
);
53+
}
54+
55+
await fs.writeFile(
56+
path.join(__dirname, "../packages/docs/docs/examples.mdx"),
57+
`---\nslug: "/examples"\ntitle: "Sandboxes"\ncategory: intro\ntemplate: page\nsidebar_position: 1\n---\n` +
58+
`# Example Sandboxes\n\nThis is a collection of example integrations for the Headless Tree library. You can ` +
59+
`use them as basis to quickly scaffold an app with Headless Tree, get started with experimenting with the ` +
60+
`capabilities of HT or to create minimalistic bug-reproductions for issue reports.\n\n${samplesList}\n\n`
61+
);

yarn.lock

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4150,6 +4150,24 @@ __metadata:
41504150
languageName: unknown
41514151
linkType: soft
41524152

4153+
"@headless-tree/example-comprehensive@workspace:examples/comprehensive":
4154+
version: 0.0.0-use.local
4155+
resolution: "@headless-tree/example-comprehensive@workspace:examples/comprehensive"
4156+
dependencies:
4157+
"@headless-tree/core": "npm:^1.0.0"
4158+
"@headless-tree/react": "npm:^1.0.0"
4159+
"@types/react": "npm:^19.0.10"
4160+
"@types/react-dom": "npm:^19.0.4"
4161+
"@vitejs/plugin-react": "npm:^4.3.4"
4162+
classnames: "npm:^2.3.2"
4163+
globals: "npm:^16.0.0"
4164+
react: "npm:^19.0.0"
4165+
react-dom: "npm:^19.0.0"
4166+
typescript: "npm:~5.7.2"
4167+
vite: "npm:^6.3.1"
4168+
languageName: unknown
4169+
linkType: soft
4170+
41534171
"@headless-tree/example-react-compiler@workspace:examples/react-compiler":
41544172
version: 0.0.0-use.local
41554173
resolution: "@headless-tree/example-react-compiler@workspace:examples/react-compiler"

0 commit comments

Comments
 (0)