{"id":"biotoxin495/guiinteractioneffects","name":"guiinteractioneffects","scope":"biotoxin495","platform":"roblox","description":"A Roblox UI module for declarative hover/press tween effects on UI Elements.","version":"1.0.1","latest":"1.0.1","versions":["1.0.0","1.0.1"],"license":"MIT","licenseRating":"safe","licenseCaveats":[],"licenseVerified":true,"dependencies":{},"integrity":"0c04908978d63dbed0eb12bab4c7d23c4787122a70baa2e584043aa9ce0f8f65","likes":0,"downloads":0,"install":"forest install biotoxin495/guiinteractioneffects","url":"https://forest.dev/p/roblox/biotoxin495/guiinteractioneffects","files":"https://api.forest.dev/ai/package/roblox/biotoxin495/guiinteractioneffects/files","readme":"# GuiInteractionEffects — Declarative hover/press tween effects for Roblox GuiButtons\n\n**GuiInteractionEffects** is a small Roblox UI module for wiring up hover and press tween effects on `GuiButton`s declaratively, instead of hand-writing `MouseEnter`/`MouseLeave`/`MouseButton1Down`/`MouseButton1Up` connections and `TweenService:Create` calls for every button in your game.\n\nYou describe what each object should look like in each interaction state. GuiInteractionEffects captures the original property values automatically, resolves the correct tween for the current state, and restores everything cleanly when you disable or clear a button.\n\n## Quick example\n\n```lua\nlocal GuiInteractionEffects = require(ReplicatedStorage.Modules.GuiInteractionEffects)\n\nGuiInteractionEffects:Setup(button, {\n\tOnMouseEnter = {\n\t\tself = { BackgroundTransparency = 0.5 },\n\t},\n\tOnClickStart = {\n\t\tself = { Rotation = 5 },\n\t},\n})\n```\n\nHovering the button tweens `BackgroundTransparency` to `0.5`. Pressing it also tweens `Rotation` to `5`, while `BackgroundTransparency` stays at its hover value. Releasing or leaving smoothly restores the original values GuiInteractionEffects captured when `Setup` was called.\n\n## 🚀 Features\n\n### Declarative, inline configuration\n\nEffects are described as plain tables keyed by state and target, not imperative event handlers.\n\n```lua\nGuiInteractionEffects:Setup(button, {\n\tOnMouseEnter = {\n\t\tself = { BackgroundTransparency = 0.5 },\n\t},\n\tOnMouseLeave = {\n\t\tself = { BackgroundTransparency = 1 },\n\t},\n\tOnClickStart = {\n\t\tself = { Rotation = 5 },\n\t},\n})\n```\n\n### Automatic original-property capture\n\nGuiInteractionEffects gathers the union of every property referenced across `OnMouseEnter`, `OnMouseLeave`, and `OnClickStart` for every target, and records each one's original value before anything is tweened. You never have to manually snapshot or restore a value yourself.\n\n### Correct partial-state fallback\n\nA state only has to configure the properties it cares about. Properties it omits resolve through a documented fallback chain instead of getting stuck at a stale value:\n\n```text\nPressed -> OnClickStart, falls back to OnMouseEnter, falls back to the original value\nHover   -> OnMouseEnter, falls back to the original value\nIdle    -> OnMouseLeave, falls back to the original value\n```\n\nIn the quick example above, this is exactly why `BackgroundTransparency` correctly stays at its hover value while pressed, even though `OnClickStart` never mentions it.\n\n### Safe under rapid interaction\n\nBefore starting a new tween on an object, GuiInteractionEffects cancels and destroys any tween already running on it. Repeatedly entering/leaving a button, pressing mid-hover-tween, or releasing mid-press-tween won't leave stale tweens fighting over the same properties.\n\n### Multiple target styles\n\n```lua\nGuiInteractionEffects:Setup(button, {\n\tOnMouseEnter = {\n\t\tself = { BackgroundTransparency = 0.5 },       -- the button itself\n\t\tIcon = { ImageColor3 = Color3.new(1, 1, 1) },  -- descendant lookup by Name\n\t\t[someInstance] = { Rotation = 5 },             -- direct instance reference (preferred)\n\t},\n})\n```\n\nDirect instance references are the most precise and are recommended when a name might not be unique. String lookups warn during development if the target is missing or the name is ambiguous.\n\n### `SetEnabled` and the `MouseEffectsActive` attribute\n\n```lua\nGuiInteractionEffects:SetEnabled(button, false)\n```\n\nDisabling a button immediately restores its original appearance and ignores further interaction events until it's re-enabled. Setting the `MouseEffectsActive` boolean attribute to `false` on the button does the same thing, and both share one internal implementation, so they can't drift out of sync.\n\n### `Apply` for one-off tweens\n\n```lua\nGuiInteractionEffects:Apply(guiObject, {\n\tself = { BackgroundTransparency = 0.5 },\n}, TweenInfo.new(0.2))\n```\n\n`Apply` immediately tweens a collection of target properties without setting up any interaction listeners or persistent state, useful for scripted, non-interaction-driven transitions.\n\n### Typed\n\n`ButtonEffectsTable`, `SetupOptions`, `EffectTargets`, `EffectProps`, and `EffectCallback` are exported types, so effect configs and options tables get Luau type checking at the call site.\n\n## 📖 Basic usage\n\nPlace the `GuiInteractionEffects` module somewhere accessible to a client script, then set up each button once:\n\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\n\nlocal GuiInteractionEffects = require(ReplicatedStorage.Modules.GuiInteractionEffects)\n\nlocal button = script.Parent.CloseButton\n\nGuiInteractionEffects:Setup(button, {\n\tOnMouseEnter = {\n\t\tself = { BackgroundTransparency = 0.85, Rotation = 9 },\n\t\tIcon = { ImageColor3 = Color3.fromRGB(255, 41, 41) },\n\t},\n\tOnMouseLeave = {\n\t\tself = { BackgroundTransparency = 1, Rotation = 0 },\n\t\tIcon = { ImageColor3 = Color3.fromRGB(255, 0, 0) },\n\t},\n\tOnClickStart = {\n\t\tself = { BackgroundTransparency = 0.92 },\n\t},\n}, {\n\tTweenInfo = TweenInfo.new(0.15),\n})\n```\n\nClean up when the button is no longer needed:\n\n```lua\nGuiInteractionEffects:Clear(button)\n```\n\nCleanup also happens automatically if the button instance is destroyed, so `Clear` is only needed if you want to detach effects from a button that's staying alive.\n\n### Example: disabling a button while an action is in progress\n\n```lua\nGuiInteractionEffects:SetEnabled(purchaseButton, false)\n\nlocal success = doPurchase()\n\nGuiInteractionEffects:SetEnabled(purchaseButton, true)\n```\n\n### Example: driving state through an attribute instead\n\n```lua\npurchaseButton:SetAttribute(\"MouseEffectsActive\", false)\n-- ... later ...\npurchaseButton:SetAttribute(\"MouseEffectsActive\", true)\n```\n\n### Example: hover callbacks\n\n```lua\nGuiInteractionEffects:Setup(button, {\n\tOnMouseEnter = {\n\t\tself = { BackgroundColor3 = button.BackgroundColor3:Lerp(Color3.new(), 0.2) },\n\t},\n}, {\n\tOnMouseEnter = function()\n\t\tSoundService.Hover:Play()\n\tend,\n})\n```\n\n## ⚙️ API\n\n### `GuiInteractionEffects:Setup(button, effects, options?)`\n\nSets up interaction effects for a `GuiButton`. Calling `Setup` again on a button that's already configured clears the previous configuration first.\n\n```lua\nGuiInteractionEffects:Setup(button, effectsTable, options)\n```\n\n### `GuiInteractionEffects:Clear(button)`\n\nDisconnects all events, cancels active tweens, restores the button's original appearance, and forgets it. Safe to call more than once; calling it on a button that was never set up (or was already cleared) is a harmless no-op.\n\n```lua\nGuiInteractionEffects:Clear(button)\n```\n\n### `GuiInteractionEffects:SetEnabled(button, enabled)`\n\nEnables or disables interaction effects for a previously-set-up button. Disabling immediately (without tweening) restores the original appearance and blocks further interaction events. Re-enabling does not automatically apply hover effects; a new interaction event is required.\n\n```lua\nGuiInteractionEffects:SetEnabled(button, false)\nGuiInteractionEffects:SetEnabled(button, true)\n```\n\n### `GuiInteractionEffects:Apply(guiObject, effects, tweenInfo?)`\n\nImmediately tweens a collection of target properties on `guiObject`. Does not set up any persistent interaction listeners or state tracking.\n\n```lua\nGuiInteractionEffects:Apply(guiObject, {\n\tself = { BackgroundTransparency = 0.5 },\n}, TweenInfo.new(0.2))\n```\n\n## Effects table reference\n\n```lua\n{\n\tOnMouseEnter = {\n\t\t[target] = { [property] = value, ... },\n\t\t...\n\t},\n\tOnMouseLeave = { ... },\n\tOnClickStart = { ... },\n}\n```\n\nAll three states are optional. `target` can be `\"self\"`, a direct `Instance` reference, or a string name resolved via recursive descendant lookup.\n\n## Options reference\n\n```lua\n{\n\tTweenInfo = TweenInfo.new(0.15), -- used for all tweened transitions\n\n\tOnMouseEnter = function() end, -- fired after hover effects are applied\n\tOnMouseLeave = function() end, -- fired after leave/idle effects are applied\n}\n```\n\nBoth callbacks are optional, and `TweenInfo` defaults to `TweenInfo.new(0.15)` when omitted.\n\n## 📝 Notes\n\n* GuiInteractionEffects is intended for client-side UI.\n* v1 supports desktop mouse interaction only (`MouseEnter`, `MouseLeave`, `MouseButton1Down`, `MouseButton1Up`). Touch, gamepad selection, and keyboard/gamepad activation are not wired up in this release.\n* String target lookups warn during development if a name can't be found or matches more than one descendant; prefer direct instance references when precision matters.\n* An error configuring one target does not prevent other valid targets from being set up.\n* Cleanup listens to the button's `Destroying` event, not a `Parent == nil` check, so temporarily reparenting a button won't be mistaken for destruction.\n\n## 🛠️ Installation\n\n### Wally\n\nAdd GuiInteractionEffects to your `wally.toml` dependencies:\n\n```toml\n[dependencies]\nGuiInteractionEffects = \"biotoxin495/guiinteractioneffects@1.0.0\"\n```\n\nRun:\n\n```text\nwally install\n```\n\nThen require the package from the location configured by your project. Like for example:\n\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\n\nlocal GuiInteractionEffects = require(\n\tReplicatedStorage.Packages.GuiInteractionEffects\n)\n```\n\n### Manual installation\n\nYou can install the standalone ModuleScript manually by copying `src/init.luau` from the repository.\n\nRecommended structure:\n\n```text\nReplicatedStorage\n└── Modules\n    └── GuiInteractionEffects\n```\n\nThen require it with:\n\n```lua\nlocal GuiInteractionEffects = require(\n\tReplicatedStorage.Modules.GuiInteractionEffects\n)\n```\n\nmade with ❤️ by biotoxin495\n","readmeTruncated":false}