Agent skill
variant-selection
Variant and attribute selection on product detail pages. Use when modifying variant selectors, debugging "Add to Cart" button state, understanding option availability, or adding discount badges to options.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/variant-selection
SKILL.md
Variant Selection System
Source: Saleor Docs - Attributes - How product/variant attributes work
When to Use
Use this skill when:
- Modifying variant/attribute selection on product pages
- Understanding why a variant isn't selectable
- Adding discount indicators to variant options
- Debugging "Add to Cart" button state
Instructions
Core Concept: Variants, Not Products
You add VARIANTS to cart, not products. Each variant is a specific attribute combination:
| Product | Attributes | Variant ID |
|---|---|---|
| T-Shirt | Black + Medium | abc123 |
| T-Shirt | Black + Large | def456 |
| T-Shirt | White + Medium | ghi789 |
The checkoutLinesAdd mutation requires a specific variantId. Without selecting ALL attributes, there's no variant to add.
Two Types of Variant Attributes
Saleor distinguishes between two types of variant attributes:
| Type | variantSelection |
Purpose | UI | Passed to Cart? |
|---|---|---|---|---|
| Selection | VARIANT_SELECTION |
Identify which variant (color, size) | Interactive picker | No - just the variantId |
| Non-Selection | NOT_VARIANT_SELECTION |
Describe the variant (material, brand) | Display-only badges | No - already on variant |
Key insight: Neither type is "passed" to checkout. You only pass the variantId. All attributes are already stored on the variant in Saleor.
# GraphQL queries use the variantSelection filter:
selectionAttributes: attributes(variantSelection: VARIANT_SELECTION) { ... }
nonSelectionAttributes: attributes(variantSelection: NOT_VARIANT_SELECTION) { ... }
Non-selection attributes are display-only - shown as informational badges, not interactive selectors.
File Structure
src/ui/components/pdp/variant-selection/
├── index.ts # Public exports
├── types.ts # TypeScript interfaces
├── utils.ts # Data transformation & logic
├── variant-selector.tsx # Single attribute selector
├── variant-selection-section.tsx # Main container
├── optional-attributes.tsx # Non-selection attribute badges
└── renderers/
├── color-swatch-option.tsx # Color swatch (circular)
└── button-option.tsx # Button for size/text (unified)
Key Functions in utils.ts
| Function | Purpose |
|---|---|
groupVariantsByAttributes() |
Extract unique attribute values from variants |
findMatchingVariant() |
Find variant matching ALL selected attributes |
getOptionsForAttribute() |
Get options with availability/compatibility info |
getAdjustedSelections() |
Clear conflicting selections when needed |
getUnavailableAttributeInfo() |
Detect dead-end selections |
For detailed function signatures and usage, see UTILS_REFERENCE.md.
Option States
| State | Meaning | Visual | Clickable? |
|---|---|---|---|
| Available | In stock | Normal | ✓ |
| Incompatible | No variant with this + current selections | Dimmed | ✓ (clears others) |
| Out of stock | Variant exists but quantity = 0 | Strikethrough | ✗ |
URL Parameter Pattern
Selections are stored in URL params:
?color=black&size=m&variant=abc123
↑ ↑ ↑
Color sel Size sel Matching variant (set automatically)
The variant param is only set when ALL attributes are selected.
Discount Badges
Options can show discount percentages:
// In utils.ts
interface VariantOption {
id: string;
name: string;
available: boolean;
hasDiscount?: boolean; // Any variant with this option is discounted
discountPercent?: number; // Max discount percentage
// ...
}
The renderers display a small badge when discountPercent is set.
Examples
Smart Selection Adjustment
When user selects an incompatible option:
State: ?color=red (Red only exists in Size S)
User clicks: Size L
Result: ?size=l (Red is cleared, not blocked)
Users are never "stuck" - they can always explore all options.
Dead End Detection
const deadEnd = getUnavailableAttributeInfo(variants, groups, selections);
// Returns: { slug: "size", name: "Size", blockedBy: "Red" }
// UI shows: "No size available in Red"
Custom Renderers
<VariantSelectionSection
variants={variants}
renderers={{
color: MyCustomColorPicker,
size: MySizeChart,
}}
/>
State Machine
The selection system has 5 states with automatic conflict resolution. For the full state diagram and transition rules, see STATE_MACHINE.md.
Quick reference:
| State | Add to Cart | Description |
|---|---|---|
| Empty | ❌ | No selections |
| Partial | ❌ | Some attributes selected |
| Complete | ✅ | All selected, variant found |
| Conflict | — | Auto-clears to Partial |
| DeadEnd | ❌ | Selection blocks other groups |
Key behavior: When user selects an incompatible option, other selections are cleared automatically (not blocked). Users can always explore all options.
Anti-patterns
❌ Don't enable "Add to Cart" without full selection - Needs variant ID
❌ Don't block incompatible options - Let users click, clear others
❌ Don't assume single attribute - Products can have multiple
❌ Don't use 0 in boolean checks for prices - Use typeof === "number"
❌ Don't make non-selection attributes interactive - They're display-only (badges, not toggles)
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?