feat(ep-commerce): per-variation input rendering via EPVariationCase (#336)#337
Merged
Merged
Conversation
752b695 to
b77ff98
Compare
…336) Allow each variation on a product to render with its own input pattern (e.g. Language as a native <select>, Format as native radios) while keeping the existing single-drop-in ergonomic for the uniform N-variation case. Implements the "Discriminated Slot Children" pattern (modelled after HTML's <picture>/<source>): - New EPVariationCase: slot host with an optional `forVariation` prop. A keyed case renders only when iterating its named variation; an un-keyed case acts as the fallback for any variation no keyed sibling has claimed. - New EPVariationOptionSelect: atomic native <select> renderer for one variation. - New EPVariationOptionRadioGroup: atomic native radio-group renderer for one variation. - VariationPickerContext exposes `claimedVariations` + `registerClaim`. Each keyed EPVariationCase self-registers on mount (Primer-style context registration); the fallback consults the registry to decide whether to render. No React.Children scanning, so wrapping by Plasmic's runtime divs doesn't break filtering. - Picker default `children` slot now contains one un-keyed EPVariationCase wrapping the existing Field + EPVariationOptionList default, so zero-config N-variation usage is unchanged. Also fixes a picker hydration bug uncovered while wiring this: the init effect now falls back to `variants[0]` when no defaultVariantId resolves and populates `selectedValues` so trigger highlights match the auto-selected variant exposed via the URL writer. Ordering is preserved from EP — the picker iterates `product.options[]` in EP order; `forVariation` only chooses which slot subtree renders during each iteration.
b77ff98 to
7bcc9ce
Compare
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.
Summary
Closes #336.
Adds a per-variation "input pattern" capability to
EPVariationPickerso each variation on a product can render with its own input style — primarily so a storefront's PDP can render Language as a native<select>and Format as native radios, while other variations continue to render as the existing card/chip pattern.The shape is the Discriminated Slot Children pattern, modelled after HTML's
<picture>/<source>. Consumers compose:What's new
EPVariationCase— slot host with optionalforVariationprop. Keyed cases render only when iterating their named variation; un-keyed cases act as the fallback for any variation no keyed sibling has claimed.EPVariationOptionSelect— atomic native<select>renderer for one variation.EPVariationOptionRadioGroup— atomic native radio-group renderer for one variation.VariationPickerContextnow exposesclaimedVariations: ReadonlySet<string>andregisterClaim(variationName) => unregister. KeyedEPVariationCaseinstances self-register on mount; the fallback consults the registry to decide whether to render. NoReact.Childrenscanning, so Plasmic's runtime div wrapping doesn't break the filter.childrenslot now contains a single un-keyedEPVariationCasewrapping the existingField + EPVariationOptionList. Zero-config N-variation usage is unchanged.Picker hydration fix
While wiring this I noticed the picker's init
useEffectwasn't populatingselectedValueswhen nodefaultVariantIdresolved, leaving option triggers un-highlighted on first load even though a variant was effectively in use. Fixed in the same effect: falls back tovariants[0]and populatesselectedValuesaccordingly. Bundled here because the newEPVariationCaseregistration would re-trigger the bug in any consumer that adopts the new pattern.Naming
The component is named
EPVariationCase(switch/case analogy: "this is the case for variation X"), matching the existingVariationnamespace in this package. Earlier drafts of this PR usedEPVariationAxis— that's been renamed to align with the rest of the surface (EPVariationField,EPVariationOptionList, etc.) and to keep "variation" as the single domain term consumers see.Ordering
Preserved from EP. The picker still iterates
product.options[]in EP order;forVariationonly decides which subtree renders during each iteration. Reorder in the EP catalog to change display order.Backwards compatibility
Existing projects using
<EPVariationOptionList>directly under the picker continue to work — the new defaultchildrencontent is semantically identical to the prior default content.EPVariationOptionList'sselectionMode="dropdown"branch is not removed; new use is steered toEPVariationOptionSelect.Alternatives considered
Rejected during design grilling:
selectionModeByVariation: Record<variationName, mode>config prop. Awkward Plasmic Studio authoring (no first-class UI forRecord<string, enum>), config split between picker prop and child components, silent failure on typo.VariantSelectorshape). Unauthorable in Plasmic Studio.Test plan
yarn buildinplasmicpkgs/commerce-providers/elastic-path— verify no TS errors.EPVariationPickeron a Plasmic page with a 2-variation product (e.g. ISO 5495:2005 with Language × Format). Default children renders chip pattern for both variations.<EPVariationCase forVariation="Language"><EPVariationOptionSelect/></EPVariationCase>and<EPVariationCase forVariation="Format"><EPVariationOptionRadioGroup/></EPVariationCase>inside the picker. Confirm Language renders as<select>, Format as native radios.useFormContextfield names (variation_<axisId>,ProductVariant).?variant=URL round-trip works through the new renderers.EPVariationCaseinstances authored) renders the picker with the default fallback chip pattern across N variations.