@babylonjs/shared-ui-components 6.4.1 → 6.5.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.
@@ -8,7 +8,7 @@ import { NodeLedger } from "./nodeLedger.js";
|
|
8
8
|
export class SearchBoxComponent extends React.Component {
|
9
9
|
constructor(props) {
|
10
10
|
super(props);
|
11
|
-
this.state = { isVisible: false, filter: "" };
|
11
|
+
this.state = { isVisible: false, filter: "", selectedIndex: 0 };
|
12
12
|
this._handleEscKey = (evt) => {
|
13
13
|
if (evt.key === "Escape") {
|
14
14
|
this.hide();
|
@@ -17,7 +17,7 @@ export class SearchBoxComponent extends React.Component {
|
|
17
17
|
this.props.stateManager.onSearchBoxRequiredObservable.add((loc) => {
|
18
18
|
this._targetX = loc.x;
|
19
19
|
this._targetY = loc.y;
|
20
|
-
this.setState({ isVisible: true, filter: "" });
|
20
|
+
this.setState({ isVisible: true, filter: "", selectedIndex: 0 });
|
21
21
|
this.props.stateManager.hostDocument.addEventListener("keydown", this._handleEscKey);
|
22
22
|
});
|
23
23
|
}
|
@@ -41,7 +41,15 @@ export class SearchBoxComponent extends React.Component {
|
|
41
41
|
}
|
42
42
|
onKeyDown(evt) {
|
43
43
|
if (evt.code === "Enter" && this._nodes.length > 0) {
|
44
|
-
this.onNewNodeRequested(this._nodes[
|
44
|
+
this.onNewNodeRequested(this._nodes[this.state.selectedIndex]);
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
if (evt.code === "ArrowDown" && this._nodes.length > 0) {
|
48
|
+
this.setState({ selectedIndex: Math.min(this.state.selectedIndex + 1, this._nodes.length - 1) });
|
49
|
+
return;
|
50
|
+
}
|
51
|
+
if (evt.code === "ArrowUp" && this._nodes.length > 0) {
|
52
|
+
this.setState({ selectedIndex: Math.max(this.state.selectedIndex - 1, 0) });
|
45
53
|
return;
|
46
54
|
}
|
47
55
|
}
|
@@ -76,8 +84,8 @@ export class SearchBoxComponent extends React.Component {
|
|
76
84
|
else if (targetY < 10) {
|
77
85
|
locStyle.top = "10px";
|
78
86
|
}
|
79
|
-
return (_jsxs("div", { id: "graph-search-container", children: [_jsx("div", { id: "graph-search-picking-blocker", onClick: () => this.hide() }), _jsxs("div", { id: "graph-search-box", style: locStyle, children: [_jsx("div", { className: "graph-search-box-title", children: "Add a node" }), _jsx("input", { type: "text", placeholder: "Search...", onChange: (evt) => this.onFilterChange(evt), onKeyDown: (evt) => this.onKeyDown(evt), value: this.state.filter, className: "graph-search-box-filter", autoFocus: true, tabIndex: 0 }), _jsx("div", { className: "graph-search-box-list", children: this._nodes.map((name) => {
|
80
|
-
return (_jsx("div", { className: "graph-search-box-list-item ", onClick: () => this.onNewNodeRequested(name), children: NodeLedger.NameFormatter(name) }, name));
|
87
|
+
return (_jsxs("div", { id: "graph-search-container", children: [_jsx("div", { id: "graph-search-picking-blocker", onClick: () => this.hide() }), _jsxs("div", { id: "graph-search-box", style: locStyle, children: [_jsx("div", { className: "graph-search-box-title", children: "Add a node" }), _jsx("input", { type: "text", placeholder: "Search...", onChange: (evt) => this.onFilterChange(evt), onKeyDown: (evt) => this.onKeyDown(evt), value: this.state.filter, className: "graph-search-box-filter", autoFocus: true, tabIndex: 0 }), _jsx("div", { className: "graph-search-box-list", children: this._nodes.map((name, i) => {
|
88
|
+
return (_jsx("div", { className: "graph-search-box-list-item " + (this.state.selectedIndex === i ? "selected " : ""), onClick: () => this.onNewNodeRequested(name), children: NodeLedger.NameFormatter(name) }, name));
|
81
89
|
}) })] })] }));
|
82
90
|
}
|
83
91
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"searchBox.js","sourceRoot":"","sources":["../../../../dev/sharedUiComponents/src/nodeGraphSystem/searchBox.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from \"react\";\r\nimport type { StateManager } from \"./stateManager\";\r\nimport \"./searchBox.scss\";\r\nimport { NodeLedger } from \"./nodeLedger\";\r\n\r\nexport interface ISearchBoxComponentProps {\r\n stateManager: StateManager;\r\n}\r\n\r\n/**\r\n * The search box component.\r\n */\r\nexport class SearchBoxComponent extends React.Component<ISearchBoxComponentProps, { isVisible: boolean; filter: string }> {\r\n private _handleEscKey: (evt: KeyboardEvent) => void;\r\n private _targetX: number;\r\n private _targetY: number;\r\n private _nodes: string[];\r\n\r\n constructor(props: ISearchBoxComponentProps) {\r\n super(props);\r\n\r\n this.state = { isVisible: false, filter: \"\" };\r\n\r\n this._handleEscKey = (evt: KeyboardEvent) => {\r\n if (evt.key === \"Escape\") {\r\n this.hide();\r\n }\r\n };\r\n\r\n this.props.stateManager.onSearchBoxRequiredObservable.add((loc) => {\r\n this._targetX = loc.x;\r\n this._targetY = loc.y;\r\n this.setState({ isVisible: true, filter: \"\" });\r\n this.props.stateManager.hostDocument!.addEventListener(\"keydown\", this._handleEscKey);\r\n });\r\n }\r\n\r\n hide() {\r\n this.setState({ isVisible: false });\r\n this.props.stateManager.modalIsDisplayed = false;\r\n this.props.stateManager.hostDocument!.removeEventListener(\"keydown\", this._handleEscKey);\r\n }\r\n\r\n onFilterChange(evt: React.ChangeEvent<HTMLInputElement>) {\r\n this.setState({ filter: evt.target.value });\r\n }\r\n\r\n onNewNodeRequested(name: string) {\r\n this.props.stateManager.onNewBlockRequiredObservable.notifyObservers({\r\n type: name,\r\n targetX: this._targetX,\r\n targetY: this._targetY,\r\n needRepositioning: true,\r\n smartAdd: true,\r\n });\r\n\r\n this.hide();\r\n }\r\n\r\n onKeyDown(evt: React.KeyboardEvent) {\r\n if (evt.code === \"Enter\" && this._nodes.length > 0) {\r\n this.onNewNodeRequested(this._nodes[0]);\r\n return;\r\n }\r\n }\r\n\r\n render() {\r\n if (!this.state.isVisible) {\r\n return null;\r\n }\r\n\r\n const expectedWidth = 300;\r\n const expectedHeight = 400;\r\n\r\n // Sort and deduplicate the node names.\r\n this._nodes = Array.from(new Set(NodeLedger.RegisteredNodeNames.sort()));\r\n\r\n if (this.state.filter) {\r\n const filter = this.state.filter.toLowerCase().trim();\r\n this._nodes = this._nodes.filter((name) => NodeLedger.NameFormatter(name).toLowerCase().includes(filter));\r\n }\r\n\r\n const containerRect = this.props.stateManager.hostDocument.getElementById(\"graph-canvas\")!.getBoundingClientRect();\r\n const targetX = this._targetX - (expectedWidth / 2 + containerRect.x);\r\n const targetY = this._targetY - (expectedHeight / 2 + containerRect.y);\r\n const locStyle = {\r\n left: targetX + \"px\",\r\n top: targetY + \"px\",\r\n };\r\n\r\n if (targetX + expectedWidth > containerRect.width) {\r\n locStyle.left = containerRect.width - expectedWidth - 10 + \"px\";\r\n } else if (targetX < 10) {\r\n locStyle.left = \"10px\";\r\n }\r\n\r\n if (targetY + expectedHeight > containerRect.height) {\r\n locStyle.top = containerRect.height - expectedHeight - 10 + \"px\";\r\n } else if (targetY < 10) {\r\n locStyle.top = \"10px\";\r\n }\r\n\r\n return (\r\n <div id=\"graph-search-container\">\r\n <div id=\"graph-search-picking-blocker\" onClick={() => this.hide()}></div>\r\n <div id=\"graph-search-box\" style={locStyle}>\r\n <div className=\"graph-search-box-title\">Add a node</div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Search...\"\r\n onChange={(evt) => this.onFilterChange(evt)}\r\n onKeyDown={(evt) => this.onKeyDown(evt)}\r\n value={this.state.filter}\r\n className=\"graph-search-box-filter\"\r\n autoFocus={true}\r\n tabIndex={0}\r\n />\r\n <div className=\"graph-search-box-list\">\r\n {this._nodes.map((name) => {\r\n return (\r\n <div className=\"graph-search-box-list-item \" onClick={() => this.onNewNodeRequested(name)} key={name}>\r\n {NodeLedger.NameFormatter(name)}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
|
1
|
+
{"version":3,"file":"searchBox.js","sourceRoot":"","sources":["../../../../dev/sharedUiComponents/src/nodeGraphSystem/searchBox.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from \"react\";\r\nimport type { StateManager } from \"./stateManager\";\r\nimport \"./searchBox.scss\";\r\nimport { NodeLedger } from \"./nodeLedger\";\r\n\r\nexport interface ISearchBoxComponentProps {\r\n stateManager: StateManager;\r\n}\r\n\r\n/**\r\n * The search box component.\r\n */\r\nexport class SearchBoxComponent extends React.Component<ISearchBoxComponentProps, { isVisible: boolean; filter: string; selectedIndex: number }> {\r\n private _handleEscKey: (evt: KeyboardEvent) => void;\r\n private _targetX: number;\r\n private _targetY: number;\r\n private _nodes: string[];\r\n\r\n constructor(props: ISearchBoxComponentProps) {\r\n super(props);\r\n\r\n this.state = { isVisible: false, filter: \"\", selectedIndex: 0 };\r\n\r\n this._handleEscKey = (evt: KeyboardEvent) => {\r\n if (evt.key === \"Escape\") {\r\n this.hide();\r\n }\r\n };\r\n\r\n this.props.stateManager.onSearchBoxRequiredObservable.add((loc) => {\r\n this._targetX = loc.x;\r\n this._targetY = loc.y;\r\n this.setState({ isVisible: true, filter: \"\", selectedIndex: 0 });\r\n this.props.stateManager.hostDocument!.addEventListener(\"keydown\", this._handleEscKey);\r\n });\r\n }\r\n\r\n hide() {\r\n this.setState({ isVisible: false });\r\n this.props.stateManager.modalIsDisplayed = false;\r\n this.props.stateManager.hostDocument!.removeEventListener(\"keydown\", this._handleEscKey);\r\n }\r\n\r\n onFilterChange(evt: React.ChangeEvent<HTMLInputElement>) {\r\n this.setState({ filter: evt.target.value });\r\n }\r\n\r\n onNewNodeRequested(name: string) {\r\n this.props.stateManager.onNewBlockRequiredObservable.notifyObservers({\r\n type: name,\r\n targetX: this._targetX,\r\n targetY: this._targetY,\r\n needRepositioning: true,\r\n smartAdd: true,\r\n });\r\n\r\n this.hide();\r\n }\r\n\r\n onKeyDown(evt: React.KeyboardEvent) {\r\n if (evt.code === \"Enter\" && this._nodes.length > 0) {\r\n this.onNewNodeRequested(this._nodes[this.state.selectedIndex]);\r\n return;\r\n }\r\n\r\n if (evt.code === \"ArrowDown\" && this._nodes.length > 0) {\r\n this.setState({ selectedIndex: Math.min(this.state.selectedIndex + 1, this._nodes.length - 1) });\r\n return;\r\n }\r\n\r\n if (evt.code === \"ArrowUp\" && this._nodes.length > 0) {\r\n this.setState({ selectedIndex: Math.max(this.state.selectedIndex - 1, 0) });\r\n return;\r\n }\r\n }\r\n\r\n render() {\r\n if (!this.state.isVisible) {\r\n return null;\r\n }\r\n\r\n const expectedWidth = 300;\r\n const expectedHeight = 400;\r\n\r\n // Sort and deduplicate the node names.\r\n this._nodes = Array.from(new Set(NodeLedger.RegisteredNodeNames.sort()));\r\n\r\n if (this.state.filter) {\r\n const filter = this.state.filter.toLowerCase().trim();\r\n this._nodes = this._nodes.filter((name) => NodeLedger.NameFormatter(name).toLowerCase().includes(filter));\r\n }\r\n\r\n const containerRect = this.props.stateManager.hostDocument.getElementById(\"graph-canvas\")!.getBoundingClientRect();\r\n const targetX = this._targetX - (expectedWidth / 2 + containerRect.x);\r\n const targetY = this._targetY - (expectedHeight / 2 + containerRect.y);\r\n const locStyle = {\r\n left: targetX + \"px\",\r\n top: targetY + \"px\",\r\n };\r\n\r\n if (targetX + expectedWidth > containerRect.width) {\r\n locStyle.left = containerRect.width - expectedWidth - 10 + \"px\";\r\n } else if (targetX < 10) {\r\n locStyle.left = \"10px\";\r\n }\r\n\r\n if (targetY + expectedHeight > containerRect.height) {\r\n locStyle.top = containerRect.height - expectedHeight - 10 + \"px\";\r\n } else if (targetY < 10) {\r\n locStyle.top = \"10px\";\r\n }\r\n\r\n return (\r\n <div id=\"graph-search-container\">\r\n <div id=\"graph-search-picking-blocker\" onClick={() => this.hide()}></div>\r\n <div id=\"graph-search-box\" style={locStyle}>\r\n <div className=\"graph-search-box-title\">Add a node</div>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Search...\"\r\n onChange={(evt) => this.onFilterChange(evt)}\r\n onKeyDown={(evt) => this.onKeyDown(evt)}\r\n value={this.state.filter}\r\n className=\"graph-search-box-filter\"\r\n autoFocus={true}\r\n tabIndex={0}\r\n />\r\n <div className=\"graph-search-box-list\">\r\n {this._nodes.map((name, i) => {\r\n return (\r\n <div\r\n className={\"graph-search-box-list-item \" + (this.state.selectedIndex === i ? \"selected \" : \"\")}\r\n onClick={() => this.onNewNodeRequested(name)}\r\n key={name}\r\n >\r\n {NodeLedger.NameFormatter(name)}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
|