@muzlukAgent Questions for React.
Mood Wheel is a beautifully designed mood and emotion picker for agent check-ins. Agent Questions turns those check-ins into real follow-ups: choices, custom answers, text, scales, time, and mood—then gives your app structured receipts to act on.
Try it as a
Live demo
Switch packages and use the real published interactions before installing them.
Loading live preview…
Installation
npm install @muzluk/mood-wheel @muzluk/agent-questionsInspiration
Mood Wheel is a mood picker by default, but really it is an expressive five-state input. Give it five ordered options and adapt the labels to the job your product is helping someone do.
Daily Check-in
A lightweight emotional check-in for journals, wellness tools, personal dashboards, or habit apps.
Awful → Low → Okay → Good → Great
Assistant Feedback
Let people rate an AI response with more nuance than thumbs up/down. The value can feed evaluation data, trigger a retry, or influence the next response.
Poor → Weak → Okay → Helpful → Excellent
Sprint Retro
A quick team pulse at the end of a sprint, release, project, or incident.
Rough → Hard → Okay → Smooth → Great
Lesson Check
Give students a low-friction way to communicate understanding without raising a hand or writing an explanation.
Lost → Unsure → Okay → Clear → Confident
Training Readiness
A pre-workout check-in that can adjust intensity or simply record how someone felt before training.
Exhausted → Low → Okay → Ready → Strong
Support Review
A more expressive customer-support rating than stars or a binary satisfaction question.
Awful → Poor → Okay → Good → Great
Setup Confidence
Use the wheel during onboarding to understand whether somebody is comfortable continuing.
Stuck → Unsure → Okay → Clear → Ready
Meal Reflection
A simple food-journal interaction focused on how a meal felt rather than calories or numerical scoring.
Bad → Off → Okay → Good → Great
Trip Check-in
Add a tiny reflection moment to a travel diary, itinerary, or trip-planning app.
Awful → Tiring → Okay → Lovely → Amazing
Team Pulse
A quick consensus check during meetings, planning sessions, workshops, or async collaboration.
Blocked → Concerned → Okay → Aligned → Excited
The same pattern works for confidence, urgency, difficulty, energy, agreement, satisfaction, severity, quality, readiness, preference, and progress.
Port it to React Native
Give this brief to your coding agent alongside the package source. It is intentionally specific about assets, gesture ownership, physics, timing, accessibility, audio, haptics, and validation so the native result keeps the source character instead of becoming a stock picker.
React Native port brief
You are a senior React Native interaction engineer. Port the published Muzluk
open-source package in this repository into a production-ready React Native
component with visual, behavioral, and tactile parity. The goal is not to make
a similar mobile control. The goal is to preserve the character of the source
interaction: the same assets, detents, timing, gesture ownership, velocity,
settling, sound, haptic rhythm, copy, spacing, and state transitions.
SOURCE OF TRUTH
1. Read the installed package README files, generated TypeScript declarations,
source repository, and every first-party asset before writing code. Do not
infer missing behavior from a generic slider or wheel library.
2. The source packages are @muzluk/mood-wheel and @muzluk/agent-questions.
The source repository is https://github.com/iyiolacak/mood-wheel.
3. Treat the shipped wheel and pointer images, tick cues, answer/reveal cues,
and their intrinsic dimensions as authoritative. Copy the actual files into
the native asset pipeline at their original pixel dimensions and scale them
only through the same layout rules. Do not redraw, rasterize, recolor,
crop, stretch, or replace them with emoji, SF Symbols, Material icons, or
third-party icon packs.
4. Preserve the MIT attribution and add the source package and its assets to
the app's third-party/first-party notices as appropriate.
PUBLIC NATIVE API
Create a small, typed API with these layers:
- MoodWheel<Value extends string>
- options: readonly five ordered { value, label, ariaLabel? } objects
- value/defaultValue, disabled, class/style equivalent, messages
- assets override with pointer, tick, and wheel only when a host genuinely
needs it
- intro: false | limited | always, introPlayLimit, introStorageKey
- sound, showControls, showHint, layoutVariant: default | ultraWide
- ambientVelocityY in pixels per second
- onAttemptInteract(): boolean for save/busy gating
- onChange and onDetent returning { index, option, source }
- source must be control, drag, keyboard-equivalent, or wheel/scroll
- AdvancedSlider
- aria/accessibility label, decrement/increment labels
- min, max, step, optional majorStep, value/defaultValue
- disabled, sound, unit, formatValue
- optional milestone hooks and onValueChange/onValueCommit/onDetent
- preserve every authored detent; do not silently coerce a one-minute range
into five-minute increments
- AgentQuestions
- receives the validated question set from the package schema/tool output
- owns drafts, vertical paging, answer/skip state, retry presentation, and
completion receipts
- exposes onAnswer, onSkip, onComplete, sound, assets, messages, locale, and
the transcribe(recording, { question, locale }) callback
- the host owns model calls, authorization, persistence, and post-completion
behavior; never hide network or storage policy inside the component
WHEEL GEOMETRY AND GESTURES
1. The supplied wheel has exactly five physical hit/trigger points. Enforce
exactly five options at the public boundary. Never serve four, six, or a
dynamically resized wheel to fit a different option count.
2. Build the wheel in a rounded, black viewport with the exact source width,
height, asset alignment, bottom anchor, and pointer resting position. The
wheel art and pointer must remain optically locked to the original.
3. A horizontal drag owns the wheel. A vertical gesture must be allowed to
bubble to AgentQuestions when the wheel is embedded in the question reel.
Do not make the entire screen compete for the same gesture.
4. During direct travel, map translation to the physical wheel angle. On
release, project a short window of release velocity, clamp it to the five
authored detents, then settle with one interruptible damped spring. A new
touch must interrupt the spring immediately and continue from the current
visual position, never from a stale selected value.
5. The pointer is a loose physical part. It should lag, lean, and shake from
horizontal wheel velocity, then recoil and settle with the wheel. When the
host passes ambientVelocityY, add that vertical host motion to the pointer's
inertial lean without changing the wheel's selected detent.
6. Preserve the first-use intro sweep and its cubic-bezier feel. Respect the
source introPlayLimit and storage key. Reduced motion must disable the sweep,
spring overshoot, and shake while keeping the control usable.
7. Keep edge labels, center label, controls, hint, hit targets, and focus state
in the same hierarchy and optical positions. Do not substitute a native
picker whose layout or momentum changes the experience.
QUESTION REEL MOTION
1. AgentQuestions is a vertically draggable reel. The current card, adjacent
card, progress indicator, and height window must move as one continuous
physical system. Do not teleport between questions or let the card settle at
several different heights.
2. Measure card heights before paging and keep a stable clipping window during
a transition. Answered cards remain visually answered; they do not collapse
into a boring receipt that causes layout shift.
3. Vertical release velocity chooses the next/previous question only when the
gesture crosses the authored threshold. Otherwise the current card springs
back. A drag can navigate a question after it is answered; an unanswered
required question still needs the source confirmation/skip rules.
4. Keep horizontal wheel ownership inside MoodWheel. Keep text fields, buttons,
microphone controls, and sliders from accidentally starting reel paging.
5. Reproduce the answer cue, answered sound, reveal motion, progress changes,
and retry/error states. Each transition must be interruptible and driven by
one source of truth for the active index.
ADVANCED TIMER RULER
1. Render a moving tick rail inside a full-width rounded black viewport with
black edge fades on both sides. The edge fades mask overflow; they are not
extra layout columns and must not intercept touches.
2. Short ranges expand each tick slot to fill the measured viewport. Long
ranges retain the compact native tick width and remain freely browsable by
dragging. For min=1, max=90, step=1, retain all 90 selectable minute
detents. majorStep changes labels only; it never removes ticks.
3. Keep the fixed selected detent, rolling numeric readout, tabular numerals,
source tick heights, selected color, sound variants, and release projection.
Do not add red threshold lines or a custom blue pointer/cursor. The selected
tick itself is enough feedback.
4. Edge dragging uses continuous rubber-band resistance. Release velocity is
projected for the source short window and settles to one normalized detent.
Arrow/button equivalents must use the same model as a gesture, not a second
hand-written value path.
5. The text entry path uses a black field with white semibold text. The submit
action is wider and centered. The optional microphone action records locally
and delegates transcription to the host callback; never hard-code a speech
provider.
PHYSICAL FEEDBACK
1. Use the project's existing Reanimated/gesture/audio/haptics stack when one
exists. Do not introduce a second animation runtime just for this port.
2. Tick sound is a small pooled set of the supplied cues. Reuse/preload them,
reset currentTime before playback, and fail silently if audio is unavailable.
The interaction must never wait for sound.
3. Pair detent crossings, milestone impacts, answer commits, and reel landings
with short haptic events that have a clear physical cause. Avoid a constant
vibration loop or arbitrary “success” decoration.
4. Gate audio/haptics behind host settings and platform capability checks. Clean
up players, streams, timers, and gesture worklets on unmount.
VISUAL PARITY
- Start from the source screenshots and asset files, not a generic design system.
- Keep the default system font used by the host app; do not add a display font.
- Preserve the compact mobile-first dimensions, dark surfaces, black wheel/ruler
viewports, rounded corners, muted labels, blue action, and semibold controls.
- Use no third-party icons. If an icon is needed, use the source-owned SVG/path
geometry or a platform-safe textless primitive that matches it optically.
- Keep button hit areas at least 40×40 points even when the visible icon is small.
- Avoid gradients, shadows, borders, and decorative cards unless the source
component already has that exact surface treatment. Do not invent a calmer or
more generic productivity UI.
ACCESSIBILITY AND EDGE CASES
- Expose correct accessibilityRole, accessibilityLabel, value/min/max, and
state for wheel, slider, buttons, text, microphone, and question progress.
- Provide VoiceOver/TalkBack actions for previous/next and selecting detents.
- Respect reduced motion, no-audio, denied-microphone, interrupted-recording,
empty transcription, disabled, saving, retry, and unmounted states.
- Keep controlled values authoritative without cancelling a live gesture or
release spring when the host echoes onChange.
- Normalize malformed ranges and never allow NaN, an out-of-range detent, or an
impossible question index to reach the UI.
- Preserve translated labels as presentation while stable values remain the
data contract.
IMPLEMENTATION PLAN
1. Inventory the web package source, declarations, tests, assets, dimensions,
CSS variables, sound files, and motion constants. Write a short parity map
before coding.
2. Build pure range/wheel physics helpers first and unit-test normalization,
detent generation, velocity projection, rubber-banding, and five-stop
enforcement.
3. Build MoodWheel, then AdvancedSlider, then AgentQuestions from those helpers.
Keep transient gesture values in shared values/refs so React renders do not
interrupt 60fps motion.
4. Add sound, haptic, accessibility, reduced-motion, microphone, and retry
behavior after the state contracts are stable.
5. Compare Android and iOS screenshots at the same viewport dimensions. Test
slow drags, fast flicks, interrupted springs, edge drags, rotation, long
labels, 1–90 time ranges, answered cards, skipped cards, and screen readers.
DELIVERABLES AND ACCEPTANCE
Return the changed files, the public TypeScript API, the asset attribution, and
the test commands. The port is complete only when:
- the five wheel stops and pointer motion match the source;
- a drag can be interrupted at any point without a jump;
- a 1–90 step-1 ruler still exposes every minute;
- short and long ruler geometry follows the viewport rules;
- question paging has no visible height/layout shift;
- answer/skip/retry receipts match the web contract;
- audio, haptics, reduced motion, accessibility, and microphone failure paths
are covered;
- iOS and Android screenshots are reviewed against the web reference; and
- unit, component, and gesture tests pass without weakening assertions.
If a native platform constraint prevents literal parity, document the constraint
and reproduce the same perceptual result with the smallest possible adapter.
Do not silently simplify the interaction or replace it with a stock control.
Usage
Pass exactly five options. Labels can be translated; the value is what your application receives.
import { MoodWheel } from "@muzluk/mood-wheel";
import "@muzluk/mood-wheel/styles.css";
const moods = [
{ value: "awful", label: "Awful" },
{ value: "rough", label: "Rough" },
{ value: "okay", label: "Okay" },
{ value: "good", label: "Good" },
{ value: "great", label: "Great" },
] as const;
export function CheckIn() {
return (
<MoodWheel
options={moods}
onChange={({ option }) => save(option.value)}
/>
);
}Connect an agent
Validate agent output before rendering it. Answer and completion callbacks return structured receipts that your application owns.
import {
AgentQuestions,
parseAgentQuestions,
} from "@muzluk/agent-questions";
import "@muzluk/agent-questions/styles.css";
const { questions } = parseAgentQuestions(agentOutput);
<AgentQuestions
questions={questions}
sound
onAnswer={(answer) => saveAnswer(answer)}
onComplete={(result) => continueAgent(result)}
/>API
Mood Wheel
- options
- Exactly five value and label pairs.
- value / defaultValue
- Choose controlled or uncontrolled state.
- onChange / onDetent
- Receive the option, index, and input source after a selection or detent.
- sound
- Enables the optional detent sound.
- messages / assets
- Replace accessible copy or the exact shipped pointer, wheel, and tick assets.
- intro
- Set
limitedoralways; tune its play limit and storage key. - presentation
- Use
disabled, controls, hint, layout, CSS class/style, custom icons, ambient velocity, and interaction gating.
Agent Questions
- questions
- A validated set of choice, text, scale, time, and five-stop mood questions.
- initial state
- Resume with
initialAnswersandinitialStep. - sound / assets
- Enable the bundled reveal and answer cues, or supply your own URLs.
- copy / theme
- Set title, status, locale, messages, aria label, and classic or ribbon theme.
- callbacks
- Handle answer, skip, complete, step-change, and dismissal receipts in your app.
- voice / options
- Provide
transcribefor local browser recordings andrenderOptionfor custom choice rendering. - agent schema
- Export
AGENT_QUESTIONS_TOOLto your model and parse its result before rendering.
Both packages are MIT licensed and built for React 18 and 19. Read the source and API documentation.