npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rbxts/tutorial-ui-highlight

v0.1.1

Published

A React-based tutorial UI highlighting system for Roblox TypeScript projects. Create interactive tutorials with customizable overlay highlighting and step-by-step guidance.

Readme

@rbxts/tutorial-ui-highlight

A React-based tutorial UI highlighting system for Roblox TypeScript projects. Create interactive tutorials with customizable overlay highlighting and step-by-step guidance.

Features

  • 🎯 Precise UI Element Highlighting - Automatically highlights specific UI elements with dark overlay around them
  • ⚛️ React Integration - Built specifically for React-based Roblox TypeScript projects
  • 🎨 Customizable Styling - Configure background colors, transparency, and interaction behavior
  • 📱 Responsive - Automatically adapts to different screen sizes and camera changes
  • 🔄 Step Management - Easy step-by-step tutorial progression with automatic cleanup
  • 🎮 Interactive Controls - Optional click-through prevention for guided experiences

Installation

npm install @rbxts/tutorial-ui-highlight

Peer Dependencies

Make sure you have the required peer dependencies installed:

npm install @rbxts/charm @rbxts/react-charm @rbxts/react @rbxts/react-roblox

Quick Start

1. Set up the Highlight Component

Add the HighlightGui component to your main UI:

import React from "@rbxts/react";
import { HighlightGui } from "@rbxts/tutorial-ui-highlight";

export function App() {
	return (
		<>
			{/* Your existing UI */}
			<YourMainUI />

			{/* Add the highlight overlay */}
			<HighlightGui />
		</>
	);
}

2. Register UI Elements

Use the useReportUiRectRef hook to register elements you want to highlight:

import { TutorialUiHightlight } from "@rbxts/tutorial-ui-highlight";

function MyButton() {
	const buttonRef = TutorialUiHightlight.useReportUiRectRef("my-button");

	return (
		<textbutton
			ref={buttonRef}
			Text="Click me!"
			Size={UDim2.fromOffset(200, 50)}
			// ... other props
		/>
	);
}

3. Start a Tutorial

import { TutorialUiHightlight } from "@rbxts/tutorial-ui-highlight";

// Start a tutorial sequence
TutorialUiHightlight.SetTutorial(["my-button", "next-step", "final-step"]);

// Resolve steps as the user progresses
TutorialUiHightlight.Resolve("my-button");

API Reference

Core Functions

SetTutorial(steps: string[])

Starts a new tutorial with the specified steps.

TutorialUiHightlight.SetTutorial(["step1", "step2", "step3"]);

Resolve(id: string)

Completes a tutorial step and moves to the next one.

TutorialUiHightlight.Resolve("step1");

StopTutorial()

Immediately stops the current tutorial and clears all remaining steps.

// Stop tutorial (e.g., if user clicks "Skip Tutorial")
TutorialUiHightlight.StopTutorial();

ReportGuiInstance(instance: GuiBase2d, id: string)

Manually register a GUI instance for highlighting.

RemoveGuiInstance(id: string)

Unregister a GUI instance.

Configuration

SetGlobalConfig(config: IStepData)

Set default configuration for all tutorial steps.

TutorialUiHightlight.SetGlobalConfig({
	BgColor3: Color3.fromRGB(0, 0, 0),
	BgTransparency: 0.5,
	CanClickCenter: false,
});

SetStepConfig(step: string, config: IStepData)

Set configuration for a specific step.

TutorialUiHightlight.SetStepConfig("important-step", {
	BgColor3: Color3.fromRGB(255, 0, 0),
	BgTransparency: 0.2,
	CanClickCenter: true,
});

React Hooks

useReportUiRectRef<T>(id: string, ref?: React.MutableRefObject<T>)

Returns a ref callback that automatically registers/unregisters the element. The optional ref parameter allows you to still maintain your own reference to the element if needed.

// Basic usage - just for tutorial highlighting
const myRef = TutorialUiHightlight.useReportUiRectRef("my-element");

// Advanced usage - when you need both tutorial highlighting AND your own ref
const myElementRef = useRef<TextButton>();
const tutorialRef = TutorialUiHightlight.useReportUiRectRef("my-element", myElementRef);

return (
	<textbutton
		ref={tutorialRef}
		// Now you can also access the element via myElementRef.current
	/>
);

useIsTutorialActive(): boolean

Returns whether any tutorial is currently active. Use this to disable other UI elements during tutorials.

function MyButton() {
	const isTutorialActive = TutorialUiHightlight.useIsTutorialActive();

	return (
		<textbutton
			Text="My Button"
			// Disable button during tutorial unless it's part of the tutorial
			Event={{
				MouseButton1Click: isTutorialActive ? undefined : handleClick,
			}}
			BackgroundTransparency={isTutorialActive ? 0.5 : 0}
		/>
	);
}

useCurrentTutorialStep(): string | undefined

Returns the current tutorial step ID. Use this to show contextual UI overlays or "Next" buttons for steps that don't require clicking.

function TutorialOverlay() {
	const currentStep = TutorialUiHightlight.useCurrentTutorialStep();
	const isTutorialActive = TutorialUiHightlight.useIsTutorialActive();

	if (!isTutorialActive || !currentStep) return null;

	// Show "Next" button for read-only steps
	const isReadOnlyStep = currentStep === "read-instructions";

	return (
		<frame>
			{isReadOnlyStep && (
				<textbutton
					Text="Next"
					Position={UDim2.fromScale(0.9, 0.9)}
					Event={{
						MouseButton1Click: () => TutorialUiHightlight.Resolve(currentStep),
					}}
				/>
			)}

			{/* Step-specific instructions */}
			{currentStep === "click-settings" && (
				<textlabel Text="Click the Settings button to continue" />
			)}
		</frame>
	);
}

Interfaces

interface IStepData {
	BgColor3: Color3; // Background overlay color
	BgTransparency: number; // Background transparency (0-1)
	CanClickCenter: boolean; // Whether the highlighted area is clickable
}

interface IPartData {
	Position: UDim2;
	Size: UDim2;
	AnchorPoint: Vector2;
}

Complete Example

// TutorialExample.tsx
import React, { useState } from "@rbxts/react";
import { TutorialUiHightlight, HighlightGui } from "@rbxts/tutorial-ui-highlight";

enum TutorialSteps {
	OpenMenu = "open-menu",
	ClickSettings = "click-settings",
	CloseMenu = "close-menu",
}

function TutorialExample() {
	const [menuOpen, setMenuOpen] = useState(false);

	// Register refs
	const menuButtonRef = TutorialUiHightlight.useReportUiRectRef(TutorialSteps.OpenMenu);
	const settingsButtonRef = TutorialUiHightlight.useReportUiRectRef(TutorialSteps.ClickSettings);
	const closeButtonRef = TutorialUiHightlight.useReportUiRectRef(TutorialSteps.CloseMenu);

	// Start tutorial
	const startTutorial = () => {
		TutorialUiHightlight.SetTutorial([
			TutorialSteps.OpenMenu,
			TutorialSteps.ClickSettings,
			TutorialSteps.CloseMenu,
		]);
	};

	return (
		<screengui>
			{/* Tutorial overlay */}
			<HighlightGui />

			{/* Main UI */}
			<textbutton
				ref={menuButtonRef}
				Text="Open Menu"
				Position={UDim2.fromScale(0.1, 0.1)}
				Size={UDim2.fromOffset(100, 50)}
				Event={{
					MouseButton1Click: () => {
						setMenuOpen(true);
						TutorialUiHightlight.Resolve(TutorialSteps.OpenMenu);
					},
				}}
			/>

			{menuOpen && (
				<frame Position={UDim2.fromScale(0.3, 0.3)} Size={UDim2.fromOffset(200, 300)}>
					<textbutton
						ref={settingsButtonRef}
						Text="Settings"
						Size={UDim2.fromOffset(150, 40)}
						Event={{
							MouseButton1Click: () => {
								TutorialUiHightlight.Resolve(TutorialSteps.ClickSettings);
							},
						}}
					/>

					<textbutton
						ref={closeButtonRef}
						Text="Close"
						Position={UDim2.fromScale(0, 0.8)}
						Size={UDim2.fromOffset(150, 40)}
						Event={{
							MouseButton1Click: () => {
								setMenuOpen(false);
								TutorialUiHightlight.Resolve(TutorialSteps.CloseMenu);
							},
						}}
					/>
				</frame>
			)}

			<textbutton
				Text="Start Tutorial"
				Position={UDim2.fromScale(0.8, 0.1)}
				Size={UDim2.fromOffset(120, 50)}
				Event={{ MouseButton1Click: startTutorial }}
			/>
		</screengui>
	);
}

Configuration Examples

Custom Step Styling

// Make a step have a red overlay with low transparency
TutorialUiHightlight.SetStepConfig("critical-step", {
	BgColor3: Color3.fromRGB(139, 0, 0),
	BgTransparency: 0.1,
	CanClickCenter: false,
});

// Make another step completely non-interactive
TutorialUiHightlight.SetStepConfig("read-only-step", {
	BgColor3: Color3.fromRGB(0, 0, 0),
	BgTransparency: 0.7,
	CanClickCenter: false,
});

Global Configuration

// Set up global defaults
TutorialUiHightlight.SetGlobalConfig({
	BgColor3: Color3.fromRGB(25, 25, 25),
	BgTransparency: 0.4,
	CanClickCenter: true,
});

Advanced Usage Patterns

Disabling UI During Tutorials

Disable other UI elements while a tutorial is active to guide user focus:

function GameUI() {
	const isTutorialActive = TutorialUiHightlight.useIsTutorialActive();

	return (
		<screengui>
			<textbutton
				Text="Play"
				Event={{
					MouseButton1Click: isTutorialActive ? undefined : startGame,
				}}
				BackgroundTransparency={isTutorialActive ? 0.7 : 0}
			/>

			<textbutton
				Text="Settings"
				Event={{
					MouseButton1Click: isTutorialActive ? undefined : openSettings,
				}}
				BackgroundTransparency={isTutorialActive ? 0.7 : 0}
			/>
		</screengui>
	);
}

Tutorial with Overlay Instructions

Create tutorials with contextual instructions and "Next" buttons for read-only steps:

function TutorialWithInstructions() {
	const currentStep = TutorialUiHightlight.useCurrentTutorialStep();
	const isTutorialActive = TutorialUiHightlight.useIsTutorialActive();

	// Configure read-only steps
	useEffect(() => {
		TutorialUiHightlight.SetStepConfig("read-instructions", {
			BgColor3: Color3.fromRGB(0, 0, 0),
			BgTransparency: 0.5,
			CanClickCenter: false, // Prevent clicking the highlighted area
		});
	}, []);

	const stepInstructions = {
		"read-instructions": "Welcome! This is your dashboard.",
		"click-play": "Click the Play button to start a game.",
		"click-settings": "Now try opening the Settings menu.",
	};

	return (
		<>
			{/* Your main UI */}
			<MainGameUI />

			{/* Tutorial overlay */}
			{isTutorialActive && currentStep && (
				<screengui ZIndexBehavior={Enum.ZIndexBehavior.Sibling}>
					{/* Instruction text */}
					<frame
						Position={UDim2.fromScale(0.5, 0.1)}
						Size={UDim2.fromOffset(400, 100)}
						AnchorPoint={new Vector2(0.5, 0)}
					>
						<textlabel
							Text={stepInstructions[currentStep] || ""}
							Size={UDim2.fromScale(1, 1)}
							TextScaled={true}
						/>
					</frame>

					{/* Next button for read-only steps */}
					{currentStep === "read-instructions" && (
						<textbutton
							Text="Next"
							Position={UDim2.fromScale(0.85, 0.85)}
							Size={UDim2.fromOffset(100, 40)}
							Event={{
								MouseButton1Click: () => TutorialUiHightlight.Resolve(currentStep),
							}}
						/>
					)}

					{/* Skip tutorial button */}
					<textbutton
						Text="Skip Tutorial"
						Position={UDim2.fromScale(0.02, 0.02)}
						Size={UDim2.fromOffset(120, 30)}
						Event={{
							MouseButton1Click: () => TutorialUiHightlight.StopTutorial(),
						}}
					/>
				</screengui>
			)}
		</>
	);
}

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.