diff --git a/src/components/block-selector/SelectorBlocks.tsx b/src/components/block-selector/SelectorBlocks.tsx
new file mode 100644
index 0000000..1ba439e
--- /dev/null
+++ b/src/components/block-selector/SelectorBlocks.tsx
@@ -0,0 +1,77 @@
+import { useContext, useMemo } from "react";
+import { Container, Graphics, Sprite, Stage } from "@pixi/react";
+import * as PIXI from "pixi.js";
+
+import { BlocksIcon } from "lucide-react";
+
+import constants from "@/constants";
+import { TexturesContext } from "@/context/Textures";
+
+import _blockData from "@/data/blocks/programmer-art/data.json";
+const blockData: BlockData = _blockData;
+
+interface Props {
+ stageWidth: number;
+ searchInput: string;
+}
+
+function SelectorBlocks({ stageWidth, searchInput }: Props) {
+ const { textures } = useContext(TexturesContext);
+
+ const blocksPerColumn = Math.floor(stageWidth / (32 + 1));
+ const blocks = useMemo(() => Object.keys(blockData).filter((value) => value.includes(searchInput)), [searchInput]);
+
+ const textureCache = useMemo(() => {
+ return (blockName: string) => {
+ let texture = textures[`${blockName}.png`];
+ if (!texture) {
+ const baseTexture = new PIXI.BaseTexture(constants.MISSING_TEXTURE);
+ texture = new PIXI.Texture(baseTexture);
+ }
+
+ return texture;
+ };
+ }, [textures]);
+
+ const onMouseMove = (e: React.MouseEvent) => {
+ console.log(e.clientX, e.clientY);
+ };
+
+ if (blocks.length == 0) {
+ return (
+
+
+ No blocks found
+
+ );
+ }
+
+ return (
+
+
+ {blocks.map((block, index) => {
+ const texture = textureCache(block);
+ const x = (index % blocksPerColumn) * (32 + 2);
+ const y = Math.floor(index / blocksPerColumn) * (32 + 2);
+
+ return ;
+ })}
+
+ {
+ g.clear();
+ g.lineStyle(1, 0xffffff, 1);
+ g.drawRect(0, 0, 16, 16);
+ }}
+ />
+
+
+ );
+}
+
+export default SelectorBlocks;
diff --git a/src/components/block-selector/index.tsx b/src/components/block-selector/index.tsx
new file mode 100644
index 0000000..30c40c4
--- /dev/null
+++ b/src/components/block-selector/index.tsx
@@ -0,0 +1,29 @@
+import { useEffect, useRef, useState } from "react";
+
+import { Input } from "@/components/ui/input";
+
+import SelectorBlocks from "./SelectorBlocks";
+
+function BlockSelector() {
+ const divRef = useRef(null);
+ const [stageWidth, setStageWidth] = useState(0);
+ const [searchInput, setSearchInput] = useState("");
+
+ useEffect(() => {
+ if (divRef.current) {
+ setStageWidth(divRef.current.clientWidth);
+ }
+ }, []);
+
+ return (
+
+
setSearchInput(e.target.value)} />
+
+
+
+
+
+ );
+}
+
+export default BlockSelector;
diff --git a/src/components/canvas/Blocks.tsx b/src/components/canvas/Blocks.tsx
index 23107a8..6d9b51e 100644
--- a/src/components/canvas/Blocks.tsx
+++ b/src/components/canvas/Blocks.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useState } from "react";
+import { useEffect, useRef } from "react";
import * as PIXI from "pixi.js";
import { useApp } from "@pixi/react";
diff --git a/src/pages/AppPage.tsx b/src/pages/AppPage.tsx
index d72f566..86e521e 100644
--- a/src/pages/AppPage.tsx
+++ b/src/pages/AppPage.tsx
@@ -1,13 +1,14 @@
import { CanvasProvider } from "@/context/Canvas";
-import { ImageProvider } from "../context/Image";
+import { ImageProvider } from "@/context/Image";
import { LoadingProvider } from "@/context/Loading";
-import { SettingsProvider } from "../context/Settings";
-import { TexturesProvider } from "../context/Textures";
-import { ToolProvider } from "../context/Tool";
+import { SettingsProvider } from "@/context/Settings";
+import { TexturesProvider } from "@/context/Textures";
+import { ToolProvider } from "@/context/Tool";
-import Menubar from "../components/menubar";
-import Toolbar from "../components/toolbar";
-import Canvas from "../components/canvas/Canvas";
+import Menubar from "@/components/menubar";
+import Toolbar from "@/components/toolbar";
+import Canvas from "@/components/canvas/Canvas";
+import BlockSelector from "@/components/block-selector";
function AppPage() {
return (
@@ -17,10 +18,11 @@ function AppPage() {
-
+
+