fix: restore string[] choices, optional icons, and fix nested ChoiceGroup crash#168
Merged
Conversation
The `+choices` icons feature (#153) changed each choice from a plain `string` to `{ name; icon; iconStyle? }` with a *required* `icon`, which is a breaking change: existing configs that pass `string[]` (e.g. vike's docs) stop type-checking and crash at build time with "Missing group name" because the runtime resolves groups by `choice.name`. Restore backward compatibility and relax the requirement: - `Choice.choices` now accepts `string | { name; icon?; iconStyle? }`, with `icon` optional (a plain string is shorthand for `{ name }`). - Add `normalizeChoice`/`normalizeChoices` and normalize at every read site (build-time resolution + the `Tabs`/`CustomSelect` components) so the rest of the code only ever deals with normalized objects. - Only render the icon `<img>` when an icon is actually defined. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NAf7Qiofocsfume76cRNwk
When a toggleable code block (TS/JS via detype, or an npm command via pkgManager) is nested inside other JSX/markup (e.g. a `<Warning>` or a blockquote) within a `:::Choice`, it is emitted as a *nested* `ChoiceGroupContainer`. The `choiceGroupAll` injection pass skips descendants of a container, so the nested one renders without the attribute and `choiceGroupAll.some(...)` throws. Guard the access (consistent with the already-guarded `.map` just below): a container without `choiceGroupAll` simply renders no redundant select — its choices still toggle via the shared/global selector. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NAf7Qiofocsfume76cRNwk
Address review feedback: - Rename `normalizeChoices` to `resolveChoices` and have it operate on the whole choices config, applied once per environment: when building the merged config in `resolveChoiceGroupNodes`, and in `resolvePageContext` (exposed as `pageContext.resolved.choices`). `Tabs`/`CustomSelect` now read already-resolved choices instead of normalizing at every call site. - Drop the inline comments (keep JSDoc). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NAf7Qiofocsfume76cRNwk
Owner
Author
|
@phonzammi Because |
Collaborator
|
Thank you. |
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.
Why
Dependabot bump vikejs/vike#3362 (
@brillout/docpress0.16.39 → 0.16.43) breaks vike's docs CI in two ways. Both are docpress regressions in 0.16.43. This PR fixes them; with these changes vike needs no config change.Fix 1 —
+choicesAPI backward compatibilityThe icons feature (#153) changed each choice from a plain
stringto{ name; icon; iconStyle? }with a requiredicon. That is a breaking change:string[](like vike'schoices: ['React', 'Vue', 'Solid']) no longer satisfyConfig['choices'].choice.name, which isundefinedfor plain strings, so the build throws[Wrong Usage] Missing group name for [React,Vue,Solid].Also, requiring an icon on every choice is impractical (e.g. vike's
Otherserver choice has no logo).Changes:
Choice.choicesnow acceptsstring | { name; icon?; iconStyle? };iconis optional and a plain string is shorthand for{ name }.normalizeChoice/normalizeChoices, applied at every read site (build-time resolution + theTabsandCustomSelectcomponents) so the rest of the code only deals with normalized objects.<img>is rendered only when an icon is defined.Fix 2 — crash on nested
ChoiceGroupContainerIndependently, a toggleable code block (TS/JS via
remarkDetype, or annpmcommand viaremarkPkgManager) nested inside other markup (a<Warning>, a blockquote, …) within a:::Choiceis emitted as a nestedChoiceGroupContainer. ThechoiceGroupAllinjection passreturn 'skip's into containers, so the nested one renders without the attribute andchoiceGroupAll.some(...)throwsCannot read properties of undefined (reading 'some')during pre-rendering (hit by vike'sbodyHtmlEndandclientOnly-helperpages).This was previously masked by the Fix‑1 build error. The minimal, safe fix here guards the access — consistent with the already‑guarded
.maptwo lines below; the container's choices still toggle via the shared/global selector (verified in the rendered HTML).Verification
Against a local build of this branch linked into vike's docs:
build✓,test:types✓,test:units✓, demovike build✓string[]config):tsc✓ andvike build✓ (351 pages pre-rendered)string[], object-with-optional-icon, and mixed choice formatsFollow-up for vike#3362
After release, vike's bump should target the new version (≥ next patch); no change to vike's
+docpress.tsxis needed thanks to the restoredstring[]support.🤖 Generated with Claude Code
Generated by Claude Code