diff --git a/package-lock.json b/package-lock.json index d3f3054..2f107cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "name": "reactapp", "version": "0.0.0", "dependencies": { + "@blockly/continuous-toolbox": "^5.0.8", + "@blockly/toolbox-search": "^1.2.3", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.15", @@ -1976,6 +1978,25 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@blockly/continuous-toolbox": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.8.tgz", + "integrity": "sha512-QPoxXca9KDDQJPA5ye5yWoE9NL+Gi+Cs90p0jtH59spUHDYFnU4Z29ZK3RSqajQ0PzklJw49O/nLH2GDqvprXg==", + "engines": { + "node": ">=8.17.0" + }, + "peerDependencies": { + "blockly": "^10.0.0" + } + }, + "node_modules/@blockly/toolbox-search": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@blockly/toolbox-search/-/toolbox-search-1.2.3.tgz", + "integrity": "sha512-puNoUVMMDgNdFzM561bh5FD7dS2xGkT3zk2biC0kn5PCEsZWD9kP99lAEwagxl7SZde8ec5Iq8YALQBhKHQvaw==", + "peerDependencies": { + "blockly": "^10.0.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -11079,6 +11100,18 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@blockly/continuous-toolbox": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@blockly/continuous-toolbox/-/continuous-toolbox-5.0.8.tgz", + "integrity": "sha512-QPoxXca9KDDQJPA5ye5yWoE9NL+Gi+Cs90p0jtH59spUHDYFnU4Z29ZK3RSqajQ0PzklJw49O/nLH2GDqvprXg==", + "requires": {} + }, + "@blockly/toolbox-search": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@blockly/toolbox-search/-/toolbox-search-1.2.3.tgz", + "integrity": "sha512-puNoUVMMDgNdFzM561bh5FD7dS2xGkT3zk2biC0kn5PCEsZWD9kP99lAEwagxl7SZde8ec5Iq8YALQBhKHQvaw==", + "requires": {} + }, "@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", diff --git a/package.json b/package.json index 9ad3a61..2af3696 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,8 @@ "test": "jest" }, "dependencies": { + "@blockly/continuous-toolbox": "^5.0.8", + "@blockly/toolbox-search": "^1.2.3", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.14.15", diff --git a/src/components/BlockCategories/Logic.jsx b/src/components/BlockCategories/Logic.jsx index 811ca6b..b95783b 100644 --- a/src/components/BlockCategories/Logic.jsx +++ b/src/components/BlockCategories/Logic.jsx @@ -1,6 +1,7 @@ // LogicCategory.jsx export const Logic = ` - + + `; diff --git a/src/components/BlockCategories/Loops.jsx b/src/components/BlockCategories/Loops.jsx index 12a20c8..a6c943e 100644 --- a/src/components/BlockCategories/Loops.jsx +++ b/src/components/BlockCategories/Loops.jsx @@ -1,6 +1,6 @@ // LoopsCategory.jsx export const Loops= ` - + diff --git a/src/components/BlockCategories/Math.jsx b/src/components/BlockCategories/Math.jsx index 79d110b..24ac3a3 100644 --- a/src/components/BlockCategories/Math.jsx +++ b/src/components/BlockCategories/Math.jsx @@ -1,6 +1,6 @@ // MathCategory.jsx export const Math = ` - + diff --git a/src/components/BlockCategories/Motion.jsx b/src/components/BlockCategories/Motion.jsx index 0c061a4..9179495 100644 --- a/src/components/BlockCategories/Motion.jsx +++ b/src/components/BlockCategories/Motion.jsx @@ -1,5 +1,5 @@ export const MoveSpriteBlock = ` - + `; diff --git a/src/components/BlockCategories/Search.jsx b/src/components/BlockCategories/Search.jsx new file mode 100644 index 0000000..3504347 --- /dev/null +++ b/src/components/BlockCategories/Search.jsx @@ -0,0 +1,9 @@ +// SearchCategory.jsx +import "@blockly/toolbox-search"; + +export const Search = ` + + +`; + + diff --git a/src/components/BlockCategories/Text.jsx b/src/components/BlockCategories/Text.jsx index 4396eac..ece809a 100644 --- a/src/components/BlockCategories/Text.jsx +++ b/src/components/BlockCategories/Text.jsx @@ -1,6 +1,6 @@ // TextCategory.jsx export const Text = ` - + diff --git a/src/components/BlocklyComponent.jsx b/src/components/BlocklyComponent.jsx index 3fb0bf2..6a71a54 100644 --- a/src/components/BlocklyComponent.jsx +++ b/src/components/BlocklyComponent.jsx @@ -5,6 +5,7 @@ import { Logic } from './BlockCategories/Logic'; import { Loops } from './BlockCategories/Loops'; import { Math } from './BlockCategories/Math'; import { Text } from './BlockCategories/Text'; +import { Search } from './BlockCategories/Search'; import initializeBlockly from './InitializeBlockly'; // import the function const BlocklyComponent = () => { @@ -21,6 +22,7 @@ const BlocklyComponent = () => { ${Loops} ${Math} ${Text} + ${Search} `; initializeBlockly(toolboxXml); // Initialize Blockly using the separate function diff --git a/src/components/Functions/Autcomplete.js b/src/components/Functions/Autcomplete.js new file mode 100644 index 0000000..a804044 --- /dev/null +++ b/src/components/Functions/Autcomplete.js @@ -0,0 +1,37 @@ +// Autocomplete function using datalist +export function InitializeAutocomplete(inp, arr) { + + // Create a datalist element + var dataList = document.createElement("datalist"); + dataList.id = inp.id + "autocomplete-datalist"; + document.body.appendChild(dataList); + + // Add options to the datalist + arr.forEach(function (option) { + var optionElement = document.createElement("option"); + optionElement.value = option; + dataList.appendChild(optionElement); + }); + + // Set the datalist attribute on the input + inp.setAttribute("list", dataList.id); + inp.addEventListener("input", function (e) { + var val = this.value.trim().toLowerCase(); + + // Filter options based on the input value + var filteredOptions = arr.filter(function (option) { + return option.toLowerCase().includes(val); + }); + // Remove existing options from datalist + dataList.innerHTML = ""; + // Add filtered options to datalist + filteredOptions.forEach(function (option) { + var optionElement = document.createElement("option"); + optionElement.value = option; + dataList.appendChild(optionElement); + }); + }); +} + +// Add options to the datalist for the autocomplete function to use +export const autocompleteArray = ["if", "do", "repeat", "while", "for", "else", "function"]; \ No newline at end of file diff --git a/src/components/InitializeBlockly.jsx b/src/components/InitializeBlockly.jsx index 2c96352..e6aa8a5 100644 --- a/src/components/InitializeBlockly.jsx +++ b/src/components/InitializeBlockly.jsx @@ -1,9 +1,22 @@ import Blockly from "blockly/core"; import "blockly/blocks"; +import { + ContinuousToolbox, + ContinuousFlyout, + ContinuousMetrics, +} from '@blockly/continuous-toolbox'; +import { InitializeAutocomplete, autocompleteArray} from "./Functions/Autcomplete"; const InitializeBlockly = (toolboxXml) => { const workspace = Blockly.inject("blocklyDiv", { + plugins: { + 'toolbox': ContinuousToolbox, + 'flyoutsVerticalToolbox': ContinuousFlyout, + 'metricsManager': ContinuousMetrics, + }, toolbox: toolboxXml, + renderer: "zelos", + theme: "zelos", zoom: { controls: false, // Disable default controls wheel: true, @@ -38,6 +51,13 @@ const InitializeBlockly = (toolboxXml) => { blocklyDiv.appendChild(customResetButton.button); blocklyDiv.appendChild(customZoomOutButton.button); + // Select the Search input + const toolboxSearchInput = document.querySelector('.blocklyToolboxContents input[type="search"]'); + toolboxSearchInput.classList.add("autocomplete-input"); // Add a class for styling if needed + + // Call the autocomplete function with the selected input and array of words + InitializeAutocomplete(toolboxSearchInput, autocompleteArray); + return workspace; }; diff --git a/src/index.css b/src/index.css index 3fcad91..e4f492d 100644 --- a/src/index.css +++ b/src/index.css @@ -22,4 +22,72 @@ body { margin: 5px 0; /* Space between categories */ border-radius: 5px; /* Optional rounded corners */ padding: 5px; /* Some padding */ +} + + +.blocklyToolboxDiv{ + padding: 0; + overflow-x: hidden; + width: 18vw; + max-width: 160px; + min-width: 110px; + +} + +.blocklyTreeRow { + border: 2px solid #463434; /* Add border */ + margin: 5px 0; /* Space between categories */ + border-radius: 15px; /* Optional rounded corners */ + padding: 5px; /* Some padding */ + height: 3; +} + +.blocklyToolboxContents{ + /* justify-content: center; */ + border: 0.1px solid #8a8888; /* Add border */ + background-color: #ece8e8; + + +} + +.blocklyTreeRowContentContainer{ + height: 10%; +} + +.autocomplete-input { + /* Add more styles as needed */ + position: relative; + border: 2px solid #463434; /* Border color */ + border-radius: 15px; /* Rounded corners */ + padding: 8px; /* Padding inside the input */ + outline: none; /* Remove the default focus border */ + transition: border-color 0.3s; /* Smooth transition for border color */ + width: 107%; + /* Add box shadow for a subtle lift effect */ + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + text-align: left; + top:-7px; + margin-bottom: -15px; + /* height: ; */ + /*left: 2px;*/ + right:10px; + height:30px; +} + +.autocomplete-input:focus { + border-color: #2980b9; +} + +.categoryBubble{ + /* display: none; */ + position: relative; + margin-top: -26px; + margin-left: -0px; + margin-bottom: -2.5px; + top :21px; + border-radius: 13px 0px 0px 13px; + height: 20px; + border: none; + height: 28px; + padding: 0; } \ No newline at end of file