### Install SimpleKit via npm Package Source: https://github.com/nonsequitoria/simplekit/blob/main/README.md This method involves installing the SimpleKit library as a dependency in your Node.js project using npm. It's straightforward for projects already using a TypeScript build process but may require manual updates and makes navigating the source code less direct. ```bash npm install simplekit ``` -------------------------------- ### SimpleKit Canvas Mode: Basic Setup and Interaction Source: https://context7.com/nonsequitoria/simplekit/llms.txt Demonstrates the basic setup for SimpleKit's Canvas Mode, including setting up draw and event listeners. It shows how to manually handle mouse events for dragging a circle and rendering the UI each frame. No external dependencies beyond the simplekit library are required. ```typescript import { startSimpleKit, setSKDrawCallback, setSKEventListener, setSKAnimationCallback, SKMouseEvent, skTime } from "simplekit/canvas-mode"; // Application state let circleX = 200; let circleY = 200; let isDragging = false; // Handle all user input events setSKEventListener((event) => { if (event instanceof SKMouseEvent) { switch (event.type) { case "mousedown": // Check if click is inside circle (manual hit testing) const dx = event.x - circleX; const dy = event.y - circleY; if (Math.sqrt(dx * dx + dy * dy) <= 25) { isDragging = true; } break; case "mouseup": isDragging = false; break; case "mousemove": if (isDragging) { circleX = event.x; circleY = event.y; } break; } } }); // Render UI every frame setSKDrawCallback((gc) => { // Clear canvas gc.clearRect(0, 0, gc.canvas.width, gc.canvas.height); // Draw draggable circle gc.beginPath(); gc.arc(circleX, circleY, 25, 0, Math.PI * 2); gc.fillStyle = isDragging ? "red" : "blue"; gc.fill(); gc.strokeStyle = "black"; gc.lineWidth = 2; gc.stroke(); // Draw instructions gc.font = "16px sans-serif"; gc.fillStyle = "black"; gc.fillText("Click and drag the circle", 10, 30); }); // Optional: Animation callback for time-based updates setSKAnimationCallback((time) => { // time is the current timestamp from the windowing system // Use for animations or time-based updates }); // Start the toolkit const result = startSimpleKit(); if (result) { console.log(`Canvas initialized: ${result.width}x${result.height}`); } ``` -------------------------------- ### Handle Keyboard Input with Textfield in TypeScript Source: https://context7.com/nonsequitoria/simplekit/llms.txt This example demonstrates how to create a text input field and display its content in real-time on a label. It includes event listeners for text changes and focus events. Dependencies include `simplekit/imperative-mode`. ```typescript import { startSimpleKit, setSKRoot, SKContainer, SKTextfield, SKLabel, Layout } from "simplekit/imperative-mode"; const root = new SKContainer({ layoutMethod: new Layout.FillRowLayout({ gap: 10 }) }); // Create label and textfield const label = new SKLabel({ text: "Name:" }); const nameField = new SKTextfield({ text: "", fill: "white", border: "black" }); nameField.fillWidth = 1; // Expand to fill available space // Create output label const outputLabel = new SKLabel({ text: "You typed: " }); // Handle text changes nameField.addEventListener("textchanged", () => { outputLabel.text = `You typed: ${nameField.text}`; }); // Handle keyboard focus nameField.addEventListener("focusin", () => { console.log("Textfield focused - ready for input"); }); nameField.addEventListener("focusout", () => { console.log("Textfield lost focus"); }); root.addChild(label); root.addChild(nameField); root.addChild(outputLabel); setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Start Imperative Mode Application with SimpleKit Source: https://github.com/nonsequitoria/simplekit/blob/main/README.md Launches SimpleKit in imperative mode, providing a full widget toolkit including a widget tree, event dispatch, built-in widgets (buttons, labels), and layout systems. This mode mirrors classic UI toolkits like JavaFX. ```javascript import { startSimpleKit, setSKRoot, SKContainer, SKButton } from "simplekit/imperative-mode"; // Create a container to hold our widgets const root = new SKContainer(); // Create a button const button = new SKButton({ text: "Click me!" }); // Handle button click actions button.addEventListener("action", () => { console.log("🎉 Button clicked!"); }); // Add button to root root.addChild(button); // Use the root container as the widget tree root setSKRoot(root); // Start SimpleKit startSimpleKit(); ``` -------------------------------- ### Start Canvas Mode Application with SimpleKit Source: https://github.com/nonsequitoria/simplekit/blob/main/README.md Initiates SimpleKit in canvas mode, allowing manual creation of interactive applications. It requires setting up custom event listeners and draw callbacks to define application behavior and rendering. This mode is for understanding fundamental building blocks. ```javascript import { startSimpleKit, setSKDrawCallback, setSKEventListener } from "simplekit/canvas-mode"; // Set up your event handler setSKEventListener((event) => { if (event.type === "click") { console.log("🎯 Canvas clicked!"); } }); // Set up your draw function setSKDrawCallback((gc) => { // Draw your UI elements here gc.fillStyle = "blue"; gc.fillRect(100, 100, 50, 50); }); // Start SimpleKit startSimpleKit(); ``` -------------------------------- ### Link SimpleKit using npm Link Source: https://github.com/nonsequitoria/simplekit/blob/main/README.md This approach allows you to use a locally cloned SimpleKit repository as if it were installed via npm. It's beneficial for easier source code access and development but can sometimes lead to TypeScript type issues and isn't easily shareable in package.json. ```bash npm link npm link simplekit ``` -------------------------------- ### SimpleKit Canvas Mode: Custom Event Translation Source: https://context7.com/nonsequitoria/simplekit/llms.txt Illustrates how to create and register custom event translators in SimpleKit's Canvas Mode. This example adds a 'longpress' event by translating low-level mouse events. It requires the simplekit library and demonstrates event handling with custom event types. ```typescript import { startSimpleKit, setSKEventListener, addSKEventTranslator, SKEvent, SKMouseEvent, FundamentalEvent } from "simplekit/canvas-mode"; // Create a long press event translator class LongPressTranslator { private pressStartTime = 0; private isPressed = false; private hasTriggered = false; private readonly threshold = 500; // ms update(fe: FundamentalEvent): SKEvent | null { if (fe.type === "mousedown") { this.pressStartTime = fe.timeStamp; this.isPressed = true; this.hasTriggered = false; } else if (fe.type === "mouseup") { this.isPressed = false; this.hasTriggered = false; } else if (this.isPressed && !this.hasTriggered) { const elapsed = fe.timeStamp - this.pressStartTime; if (elapsed >= this.threshold) { this.hasTriggered = true; return new SKEvent("longpress", fe.timeStamp); } } return null; } } // Register the custom translator addSKEventTranslator(new LongPressTranslator()); // Listen for both standard and custom events setSKEventListener((event) => { if (event.type === "longpress") { console.log("Long press detected!"); } else if (event.type === "click") { console.log("Regular click"); } }); startSimpleKit(); ``` -------------------------------- ### Build Nested UI Containers with Imperative Mode in SimpleKit Source: https://context7.com/nonsequitoria/simplekit/llms.txt Demonstrates building a hierarchical UI using SimpleKit's imperative mode. It showcases creating containers for layout, adding labels and buttons, and arranging them vertically and horizontally. No external dependencies beyond the 'simplekit/imperative-mode' library are required. ```typescript import { startSimpleKit, setSKRoot, SKContainer, SKButton, SKLabel, Layout } from "simplekit/imperative-mode"; // Main vertical layout const root = new SKContainer({ fill: "white" }); // Header with title const header = new SKContainer({ layoutMethod: new Layout.CentredLayout(), fill: "navy", border: "black" }); header.padding = 15; const title = new SKLabel({ text: "My Application", fill: "navy", border: "white" }); title.font = "24px bold sans-serif"; header.addChild(title); header.fillWidth = 1; header.fillHeight = 0; // Toolbar with buttons const toolbar = new SKContainer({ layoutMethod: new Layout.FillRowLayout({ gap: 10 }), fill: "lightgray", border: "black" }); toolbar.padding = 10; toolbar.fillWidth = 1; toolbar.fillHeight = 0; const newBtn = new SKButton({ text: "New" }); const openBtn = new SKButton({ text: "Open" }); const saveBtn = new SKButton({ text: "Save" }); newBtn.addEventListener("action", () => console.log("New clicked")); openBtn.addEventListener("action", () => console.log("Open clicked")); saveBtn.addEventListener("action", () => console.log("Save clicked")); toolbar.addChild(newBtn); toolbar.addChild(openBtn); toolbar.addChild(saveBtn); // Content area const content = new SKContainer({ layoutMethod: new Layout.CentredLayout(), fill: "white", border: "black" }); content.fillWidth = 1; content.fillHeight = 1; // Expand to fill remaining space const contentLabel = new SKLabel({ text: "Content goes here", fill: "white" }); content.addChild(contentLabel); // Assemble UI root.layoutMethod = new Layout.FillRowLayout({ gap: 0 }); root.addChild(header); root.addChild(toolbar); root.addChild(content); setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Handle Global Events with SimpleKit Imperative Mode Source: https://context7.com/nonsequitoria/simplekit/llms.txt This snippet demonstrates how to set up a global event listener in SimpleKit's Imperative Mode to monitor all UI events, such as mouse and keyboard interactions. It logs events to the console for debugging purposes. Dependencies include the 'simplekit/imperative-mode' library. ```typescript import { startSimpleKit, setSKRoot, setSKEventListener, SKContainer, SKButton, SKTextfield, SKMouseEvent, SKKeyboardEvent } from "simplekit/imperative-mode"; // Global event listener for logging/debugging setSKEventListener((event) => { if (event instanceof SKMouseEvent) { console.log(`Mouse event: ${event.type} at (${event.x}, ${event.y})`); } else if (event instanceof SKKeyboardEvent) { console.log(`Keyboard event: ${event.type}, key: ${event.key}`); } else if (event.type === "resize") { console.log("Window resized - layout will update"); } }); const root = new SKContainer(); const button = new SKButton({ text: "Test Button" }); button.addEventListener("action", () => { console.log("Button action fired (widget level)"); }); const textfield = new SKTextfield({ text: "Type here" }); textfield.addEventListener("textchanged", () => { console.log(`Text changed to: ${textfield.text}`); }); button.x = 50; button.y = 50; textfield.x = 50; textfield.y = 100; root.addChild(button); root.addChild(textfield); setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Add SimpleKit as Git Submodule Source: https://github.com/nonsequitoria/simplekit/blob/main/README.md Ideal for monorepos where multiple projects need a consistent SimpleKit version. This method adds SimpleKit as a Git submodule, allowing direct access to its source code within your repository structure. It requires initialization and updates after cloning and specific configuration in your project's package.json. ```bash git submodule add https://github.com/nonsequitoria/simplekit.git simplekit git submodule init git submodule update ``` ```json { "dependencies": { "simplekit": "file:../simplekit" } } ``` ```bash git config --global alias.pullall '!git pull && git submodule update --init --recursive' git pullall ``` -------------------------------- ### Arrange Widgets Automatically with Layout Managers in TypeScript Source: https://context7.com/nonsequitoria/simplekit/llms.txt This code snippet illustrates how to use different layout managers (FillRowLayout, WrapRowLayout, CentredLayout) provided by SimpleKit to automatically arrange widgets within containers. Dependencies include `simplekit/imperative-mode`. ```typescript import { startSimpleKit, setSKRoot, SKContainer, SKButton, SKLabel, Layout } from "simplekit/imperative-mode"; // FillRowLayout - distribute space proportionally const fillContainer = new SKContainer({ layoutMethod: new Layout.FillRowLayout({ gap: 10 }), fill: "lightgray", border: "black" }); fillContainer.padding = 10; const btn1 = new SKButton({ text: "Fixed" }); const btn2 = new SKButton({ text: "Fill 1" }); btn2.fillWidth = 1; // Takes 1 part of available space const btn3 = new SKButton({ text: "Fill 2" }); btn3.fillWidth = 2; // Takes 2 parts of available space fillContainer.addChild(btn1); fillContainer.addChild(btn2); fillContainer.addChild(btn3); // WrapRowLayout - wrap elements to next row when out of space const wrapContainer = new SKContainer({ layoutMethod: new Layout.WrapRowLayout({ gap: 5 }), fill: "lightyellow", border: "black" }); wrapContainer.padding = 10; for (let i = 0; i < 10; i++) { wrapContainer.addChild(new SKButton({ text: `Btn ${i + 1}` })); } // CentredLayout - center elements in container const centredContainer = new SKContainer({ layoutMethod: new Layout.CentredLayout(), fill: "lightgreen" }); const centredLabel = new SKLabel({ text: "I'm centered!", fill: "white", border: "black" }); centredLabel.padding = 20; centredContainer.addChild(centredLabel); // Root with fixed layout for manual positioning const root = new SKContainer(); fillContainer.x = 10; fillContainer.y = 10; wrapContainer.x = 10; wrapContainer.y = 100; centredContainer.x = 10; centredContainer.y = 200; root.addChild(fillContainer); root.addChild(wrapContainer); root.addChild(centredContainer); setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Dynamically Update UI with SimpleKit Imperative Mode Source: https://context7.com/nonsequitoria/simplekit/llms.txt This code shows how to dynamically modify the widget tree at runtime in SimpleKit's Imperative Mode. It allows adding, removing, and clearing widgets from the UI using buttons. It utilizes layout managers and event listeners for interactive UI updates. Dependencies include the 'simplekit/imperative-mode' library. ```typescript import { startSimpleKit, setSKRoot, SKContainer, SKButton, SKLabel, Layout } from "simplekit/imperative-mode"; const root = new SKContainer({ layoutMethod: new Layout.FillRowLayout({ gap: 10 }) }); root.padding = 10; let counter = 0; // Add button const addBtn = new SKButton({ text: "Add Widget" }); addBtn.addEventListener("action", () => { counter++; const newLabel = new SKLabel({ text: `Item ${counter}`, fill: "lightblue", border: "black" }); newLabel.padding = 10; root.addChild(newLabel); console.log(`Added item ${counter}`); }); // Remove button const removeBtn = new SKButton({ text: "Remove Widget" }); removeBtn.addEventListener("action", () => { const children = root.children; if (children.length > 2) { // Keep the buttons root.removeChild(children[children.length - 1]); console.log("Removed last item"); } }); // Clear button const clearBtn = new SKButton({ text: "Clear All" }); clearBtn.addEventListener("action", () => { // Remove all children root.clearChildren(); // Re-add the control buttons root.addChild(addBtn); root.addChild(removeBtn); root.addChild(clearBtn); counter = 0; console.log("Cleared all items"); }); root.addChild(addBtn); root.addChild(removeBtn); root.addChild(clearBtn); setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Perform 2D Vector Math Operations in SimpleKit Source: https://context7.com/nonsequitoria/simplekit/llms.txt Provides utility functions for common 2D vector and point operations. It covers creating points and vectors, calculating distances and directions between points, and performing vector arithmetic like addition, scaling, normalization, and dot/cross products. Requires 'simplekit/utility'. ```typescript import { Point2, Vector2, point, vector } from "simplekit/utility"; // Create points const p1 = point(100, 150); const p2 = new Point2(200, 250); // Vector from two points const direction = p2.subtract(p1); console.log(`Direction: (${direction.x}, ${direction.y})`); // Vector operations const v1 = vector(3, 4); const magnitude = v1.magnitude(); // 5 const normalized = v1.normalize(); // (0.6, 0.8) const v2 = vector(1, 0); const dotProduct = v1.dot(v2); // 3 const crossProduct = v1.cross(v2); // -4 // Vector arithmetic const v3 = v1.add(v2); // (4, 4) const v4 = v1.multiply(2); // (6, 8) // Move point by vector const newPoint = p1.add(v1); // (103, 154) ``` -------------------------------- ### Create Interactive Button with Event Handling in TypeScript Source: https://context7.com/nonsequitoria/simplekit/llms.txt This snippet shows how to create a clickable button that increments a counter displayed on a label. It utilizes SimpleKit's imperative mode for UI construction and event handling. Dependencies include `simplekit/imperative-mode`. ```typescript import { startSimpleKit, setSKRoot, SKContainer, SKButton, SKLabel } from "simplekit/imperative-mode"; // Create root container const root = new SKContainer(); // Create a button const clickButton = new SKButton({ text: "Click Me!", fill: "lightblue", border: "navy" }); // Counter label let clickCount = 0; const counterLabel = new SKLabel({ text: "Clicks: 0", align: "centre" }); // Handle button action event clickButton.addEventListener("action", (event) => { clickCount++; counterLabel.text = `Clicks: ${clickCount}`; console.log(`Button clicked ${clickCount} times`); }); // Add widgets to container root.addChild(clickButton); root.addChild(counterLabel); // Position elements (with fixed layout) clickButton.x = 100; clickButton.y = 100; counterLabel.x = 100; counterLabel.y = 150; // Set root and start setSKRoot(root); startSimpleKit(); ``` -------------------------------- ### Implement Mouse Hit Testing on Rectangles with SimpleKit Source: https://context7.com/nonsequitoria/simplekit/llms.txt Shows how to detect if a mouse cursor is inside or on the edge of a rectangle using SimpleKit's utility functions. It integrates with the canvas mode to provide visual feedback based on the hit test results and logs click events. Requires 'simplekit/utility' and 'simplekit/canvas-mode'. ```typescript import { insideHitTestRectangle, edgeHitTestRectangle } from "simplekit/utility"; import { startSimpleKit, setSKDrawCallback, setSKEventListener, SKMouseEvent } from "simplekit/canvas-mode"; // Rectangle definition const rect = { x: 100, y: 100, w: 150, h: 80, strokeWidth: 5 }; let mouseState = "outside"; setSKEventListener((event) => { if (event instanceof SKMouseEvent) { const mx = event.x; const my = event.y; // Check if mouse is inside rectangle const inside = insideHitTestRectangle( mx, my, rect.x, rect.y, rect.w, rect.h ); // Check if mouse is on edge of rectangle const onEdge = edgeHitTestRectangle( mx, my, rect.x, rect.y, rect.w, rect.h, rect.strokeWidth ); if (onEdge) { mouseState = "edge"; } else if (inside) { mouseState = "inside"; } else { mouseState = "outside"; } if (event.type === "click") { console.log(`Clicked: ${mouseState}`); } } }); setSKDrawCallback((gc) => { gc.clearRect(0, 0, gc.canvas.width, gc.canvas.height); // Draw rectangle with different colors based on hit test gc.fillStyle = mouseState === "inside" ? "lightblue" : "lightgray"; gc.strokeStyle = mouseState === "edge" ? "red" : "black"; gc.lineWidth = rect.strokeWidth; gc.fillRect(rect.x, rect.y, rect.w, rect.h); gc.strokeRect(rect.x, rect.y, rect.w, rect.h); // Status text gc.fillStyle = "black"; gc.font = "16px sans-serif"; gc.fillText(`Mouse: ${mouseState}`, 10, 30); }); startSimpleKit(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.