svelte-gym
v1.0.2
Published
Rapidly create and exercise your Svelte components.
Maintainers
Readme
Svelte Gym
Rapidly create, exercise, and share Svelte component states via URL-encoded permalinks.
Why Svelte Gym?
Developing and testing components should be seamless. Svelte Gym provides a playground environment to exercise your components and ensure they respond correctly to various inputs and constraints.
Key Features:
- URL-Driven State: Every control and property is reflected in the URL. Share a link, share a state.
- Visual Regression Ready: Deterministic URLs make it easy to use tools like BackstopJS to detect visual regressions.
- LLM Friendly: The URL structure provides a context-rich, text-based representation of your component's state, making it ideal for AI-assisted development and debugging.
Use Cases
- Responsive Testing: How does the component respond when the parent element resizes?
- Style Verification: Is the font size on the parent element respected?
- Edge Cases: Does text overflow expectedly? Is bad data (null, NaN, undefined) handled gracefully?
- Collaboration: Share a specific component state with a colleague or an LLM to reproduce a bug.
Getting Started
Installation
npm install -D svelte-gym
# or
pnpm install -D svelte-gym
# or
bun install -D svelte-gymBasic Usage
Create a +page.svelte route for your component (e.g., src/routes/gym/my-component/+page.svelte):
<script lang="ts">
import { TestHarness, restoreProps, GymCheckbox, GymTextbox } from "svelte-gym";
import MyComponent from '$lib/MyComponent.svelte';
// 1. Define your component properties
let props = $state({
label: "Hello World",
isActive: true,
count: 0
});
// 2. Restore properties from URL parameters automatically
// This allows the URL to drive the component state
restoreProps(props);
</script>
<!-- 3. Wrap your component in the TestHarness -->
<TestHarness>
{#snippet componentToTest()}
<MyComponent {...props} />
{/snippet}
<!-- 4. Add controls to manipulate props -->
{#snippet controls()}
<ul>
<li><GymCheckbox bind:props name="isActive" /></li>
<li><GymTextbox bind:props name="label" /></li>
</ul>
{/snippet}
</TestHarness>AI / LLM Workflow & Best Practices
Svelte Gym is designed to be "interpreter-friendly." To ensure the best results and visual parity when using LLMs for component development:
1. Minimal componentToTest Snippet
The componentToTest snippet should only contain the component being tested.
[!IMPORTANT] Avoid wrapping the component in extra
divorsectiontags. This ensures that the component's layout and styles are tested in isolation, matching how it will appear when deployed.
Correct:
{#snippet componentToTest()}
<MyComponent {...props} />
{/snippet}Incorrect:
{#snippet componentToTest()}
<div class="wrapper"> <!-- ❌ DON'T DO THIS -->
<MyComponent {...props} />
</div>2. Use Gym* Input Components
Always use the built-in Gym prefixed input components (e.g., GymSlider, GymTextbox, GymCheckbox) in the controls snippet.
[!IMPORTANT] Do not use standard HTML inputs or other custom components.
Gym*inputs are specifically designed to handle and test edge cases likenull,undefined,NaN, andInfinity, which are critical for robust component testing and are not supported by standard inputs.
3. URL-Driven State & Reproductions
- Describe the Issue: "My component breaks when the label is too long."
- Generate a Reproduction: The LLM can generate a Svelte Gym URL with a long label string encoded in the parameters.
- Example:
http://localhost:5173/gym/button?label=Super+Long+Label+That+Breaks+Layout
- Example:
- Fix and Verify: You can verify the fix visually, and the URL serves as a regression test case.
API Reference
TestHarness
The main wrapper for your component playground.
Props:
maxWidth(number, optional): Maximum width constraint for the test area.maxHeight(number, optional): Maximum height constraint for the test area.maxFontSize(number, optional): Maximum font size for the test area.
Snippets:
componentToTest: Place the component you want to test here.controls: PlaceGym*controls here to modifyprops.
restoreProps(props)
Synchronizes the URL search parameters with your local props object. This must be called in your component's <script> section.
Controls (Gym* Components)
All controls support bind:props and a name attribute corresponding to the property key in props.
GymCheckbox: Boolean toggle.GymTextbox: String input.GymSlider: Numeric slider (requiresmin,max).GymDropdown: Select from a list of options.GymRadioGroup: Radio button group.GymLog: Displays a log of events (passed as an array of strings).
JSON Path Support
Svelte Gym supports nested properties using dot notation. This is useful for complex state objects.
<script lang="ts">
let props = $state({
config: {
theme: {
mode: 'dark'
}
}
});
</script>In your controls:
<GymDropdown bind:props name="config.theme.mode" options={['light', 'dark']} />License
MIT
