Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@rbxts/tutorial-ui-highlight) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
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-highlightPeer Dependencies
Make sure you have the required peer dependencies installed:
npm install @rbxts/charm @rbxts/react-charm @rbxts/react @rbxts/react-robloxQuick 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.