feat(#1): controls mapper (remap, skins, presets, live test)#196
Merged
Conversation
Add framework-agnostic controls data helpers (getMapping/setMapping, assignBinding/removeBinding, createDefaultMapping, preset serialize/parse, localStorage persistence, CONTROL_SKINS), a Pinia store holding reactive state, and a standalone /tools/ControlsMapper view built from a reusable ControlsMapper component tree (bindings, style, presets, tester). Add a skin prop to TouchControl for previewable on-screen control styles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…alog - Relocate the view to src/views/Tests (route /tests/ControlsMapper) - Bindings use tabs per control device (keyboard/gamepad/faux-pad) - Add resetToDefaults store action and a Reset to defaults button - Make the view its own scroll container (global body scroll is locked) - Move preset import/export into a reusable Dialog component Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dated links) Collapse presets into a single Add menu: save current config, import a config file, download the current config, and a list of saved configs shown as clickable dated links that apply on click. Remove the now-unused Dialog. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two top-level tabs: Bindings (presets Add menu + reset + device bindings) and Test (style + live tester). Bindings rows wrap for narrow screens and fonts step up for readability on phones. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
radix Select forbids an empty-string SelectItem value; map the unset faux-pad direction to a 'none' sentinel instead. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap each Tabs in an auto-height container so the shared height:100% resolves to auto and TabsContent no longer creates inner scroll boxes (faux-pad). Add a RotateCcw icon to the Reset button. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The panel's display:flex overrode the [hidden] attribute so the inactive tab stayed visible and pushed content down; gate display behind :not([hidden]). Set the view text color to --color-foreground so labels are not invisible white on the light background. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a normalized position prop to TouchControl and a useGamepadStick composable that polls the left stick each frame, so moving a gamepad joystick moves the faux-pad preview in the Test tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Track the last input device in the store (via recordAction) and switch the Bindings device sub-tab to match, so pressing a key, gamepad button, or using the faux-pad focuses the matching tab. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add mouse drag support to the faux-pad controller (mousedown on the knob, mousemove/up on window) so it works on desktop, extracted into a helper to stay within the function-length limit. Stop useGamepadStick from re-emitting an identical position each frame, which had been resetting the knob to center and fighting drags. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
✅ Deploy Preview for cnotv-generative-art ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Rebuild the mapper UI with the LobbyUI kit (LobbyUIRow, LobbyUIOptionToggle, LobbyUIButton, LobbyUIConfigField) on a themed backdrop, and add a shared useMenuFocus composable providing roving keyboard/gamepad focus over [data-lui-row] rows (up/down rows, left/right controls, activate, select/number editing) with a gamepad focus hint. Presets become buttons instead of a dropdown; the device sub-tab and top tabs are toggles. Let LobbyUIOptionToggle wrap so 3-option toggles fit narrow screens. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ayout - Load the Darumadrop One font in the view (matches other LobbyUI screens) - LobbyUIButton: add size prop (sm/md/lg), remove borders and box-shadows - LobbyUIOptionToggle: add size + per-option icons + hide-label-on-mobile; highlight the active option with a fill instead of a border - Device toggle uses keyboard/gamepad/joystick icons (labels hidden on mobile) - Listen (ghost) and Clear are small icon buttons (ear / x) - Import + Download sit together as their own list; saved configs load by clicking their dated label - Save (large) and Reset moved to the very bottom; skin toggle is small Shared LobbyUIButton/LobbyUIOptionToggle changes are global and flatten buttons across all lobbies. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Move Save/Reset up next to the title so they're reachable without scrolling - Increase spacing between title, tabs, and options - Add a Presets tab and move the preset import/download/saved-config list there - Swap the Listen ear icon for a signal icon Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Listen uses a pencil icon, Clear uses an undo icon - Drop-shadow on binding, preset, and toggle icons to match the LobbyUI text - Nudge icons down to sit on the font's optical center - Trigger fills the row so the action icons sit at the end - More spacing under the header and the device tabs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Restore a focus border on LobbyUIButton/LobbyUIOptionToggle (transparent at rest, focus color when focused) so joypad/keyboard focus is visible - Replace the faux-pad direction dropdown with prev/next arrow steppers that disable at the first/last option Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The playful font sat high in the default 1.5 line box, making text look off-center inside the focus border; tighten line-height to 1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add LobbyUIIconButton (round icon button) and use it for listen/clear, preset delete, and the config-field arrows - Rebuild LobbyUIConfigField as prev/next arrow steppers around a read-only value (no dropdown click, no underline); disable arrows at first/last / min/max - Optically center button and toggle text via asymmetric vertical padding (keeps height, unlike line-height) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…arrows - Lay out the binding rows as one grid (display: contents rows) so label, trigger, listen and clear align in the same columns across rows - Revert LobbyUIConfigField to a focusable select/number with non-focusable decorative arrows, restoring the click-to-edit / click-to-confirm flow; drop the underline Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Gamepad capture now ignores buttons already held when Listen is activated and only binds a freshly-pressed button, so activating with the confirm button no longer instantly binds it - Remove the device auto-switch on last input: it snapped back to the gamepad tab on every d-pad nav press, making it impossible to select/stay on another device tab with the pad Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the binding value itself the focusable control: click/tap/activate it to listen, then press an input to set it. Replace the pencil/undo icons with a single X that resets the binding. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…aux-pad jump - Hide the gamepad hint when focus leaves the panel (e.g. joypad cancel), via a focusout listener - Pause menu navigation while a binding is being captured so the input only updates the keybinding - Config field value can be changed with up/down as well as left/right - Faux-pad tab lists all actions (including Jump) with a direction select, so Jump is no longer missing Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capture gamepad buttons on release so the confirm/activate button can be bound without re-triggering navigation, and capture stick axis deflections (axisN-left/right/up/down) so stick directions are bindable too. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ab focus - Non-directional faux-pad actions (jump) bind to a same-named on-screen button (None/Button) instead of a direction; movement actions keep directions - Stop refocusing to the first row when switching top tabs, so focus stays on the tab toggle instead of jumping to Save Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… defer edits - Binding capture interrupts if the other device is used (keyboard while capturing gamepad, or vice-versa) - Skip live test recording while a binding is being captured - Config-field edits (select/number) only apply on confirm; cycling previews and cancel reverts, so faux-pad directions no longer reset other bindings until confirmed Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…elds Move the gamepad focus-hint chip into a reusable LobbyUIFocusHint component and give lui-field__control a visible focus border so focused inputs are clear. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1
Summary
A standalone Controls Mapper at
/tests/ControlsMapperwhere you can remap controls, style the on-screen widget, save/load configs, and test everything live. All data logic lives in the framework-agnostic@webgamekit/controlspackage; Pinia holds reactive state; Vue components are UI only.Design
Goal — one place to:
localStorage, plus JSON file import/download.Architecture
packages/controls(pure functions +localStorage):getMapping/setMapping,assignBinding/removeBinding,createDefaultMapping,serializePreset/parsePreset,savePresets/loadPresets,CONTROL_SKINS.src/stores/controlsMapper.ts(Pinia) holds reactive state and delegates to those functions.src/components/ControlsMapper/*render UI only; the view is a thin wrapper (auto-routed).Layout — two top-level tabs for mobile: Bindings (Add menu + Reset + device sub-tabs that auto-follow the last input) and Test (skin picker + live preview + tester). Each tab fits a single phone viewport.
Key Changes
@webgamekit/controlsgetMapping()/setMapping()on thecreateControlsinstance (the issue listed these as done; onlyremapControlsOptions()actually existed).assignBinding,removeBinding(per-action conflict resolution),createDefaultMapping.serializePreset,parsePreset,savePresets,loadPresets,PRESETS_STORAGE_KEY.CONTROL_SKINS,getDefaultSkinId.App
src/stores/controlsMapper.ts— reactive mapping / skin / presets / live actions / last device.src/components/ControlsMapper/— orchestrator + Bindings, Style, Presets (Add dropdown: save/import/download + dated links), Tester, plususeBindingCaptureanduseGamepadStick.src/views/Tests/ControlsMapper/ControlsMapper.vue— thin routed view.TouchControl.vue—skinprop (default look unchanged),inlinepreview mode, externalposition(gamepad-driven) prop.Behaviour
Test Plan
pnpm test:unit— 1315 tests pass (new:getMapping/setMapping, mapping helpers, presets round-trip + storage, skins, faux-pad mouse, store round-trips incl.lastDevice).pnpm type-check,pnpm lint, stylelint — all clean./tests/ControlsMapper, rebind a key/gamepad button, swap skins, save/import/download a config, drag the pad, watch actions fire live, confirm tabs auto-switch by input.🤖 Generated with Claude Code