feat(config): add defaultPreviewSettings to seed initial preview-pane state#842
feat(config): add defaultPreviewSettings to seed initial preview-pane state#842arikw wants to merge 2 commits into
Conversation
… state
Histoire's preview-settings store is seeded with hardcoded defaults
(notably `responsiveWidth: 720`) the first time it runs. There is
currently no way to change those seeds from `histoire.config.js`, so
every story loads with the responsive picker constrained to 720px
even when the user wants previews to render at their natural width.
This commit exposes a new top-level config field
`defaultPreviewSettings: Partial<PreviewSettings>` that merges into the
useStorage initial value. Each field is optional; omitted fields fall
back to the built-in default. The user-written file `histoire.config.js`
becomes:
export default defineConfig({
defaultPreviewSettings: {
responsiveWidth: null, // null → "Auto"
},
})
Only seeds the store on first visit. Once the user changes a setting
via the toolbar, their choice is persisted and wins on later loads.
Type changes:
- `PreviewSettings` moves from `packages/histoire-app/src/app/types.ts`
to `packages/histoire-shared/src/types/config.ts` so the node-side
config schema can reference it. The app-side type file re-exports.
- `responsiveWidth` and `responsiveHeight` widen from `number` to
`number | null` so the picker UI's existing `?? 'Auto'` fallback
has a typed home (the runtime already passed null for height; the
number-only type was a latent mismatch).
Docs: new entry under `docs/reference/config.md` after
`defaultStoryProps`.
|
|
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
There was a problem hiding this comment.
Code Review
This pull request introduces the defaultPreviewSettings configuration option, allowing users to seed the initial state of the preview pane, such as responsive dimensions and background settings. The PreviewSettings interface was updated to support null values for width and height, representing an 'Auto' sizing mode. Feedback suggests extending this change to the ResponsivePreset interface to maintain type consistency across the configuration and align with existing documentation.
✅ Deploy Preview for histoire-examples-svelte3 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for histoire-examples-vue3 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for histoire-controls ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for histoire-site ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
The built-in `responsivePresets` already ship presets with `height: null` (Laptop Small, Laptop Large, Desktop, 4K — see packages/histoire/src/node/config.ts) and the documentation reflects that shape, but the `ResponsivePreset` type declared the fields as `width: number; height?: number` — a latent mismatch that crashed TypeScript users who tried to mirror the default presets in their own `responsivePresets` override. Widen both fields to `number | null`. No runtime change in core; the ToolbarResponsiveSize.vue UI is already null-safe (`v-if="preset.width"`, `v-if="preset.height"`). Updates the docs alongside. Note: the screenshot plugin (packages/histoire-plugin-screenshot) reads `preset.width` and `preset.height` directly and passes them to capture-website. That code path already breaks on the built-in null-height presets; not regressing it here. Addresses gemini-code-assist's review comment on PR histoire-dev#842.
Summary
Adds a new top-level config field
defaultPreviewSettings: Partial<PreviewSettings>so users can seed the persistedpreview-settings store from
histoire.config.js. The primary motivation: change the responsive size picker's initial width away from its hardcoded 720px default so stories can render at their natural width on a first visit.Each field of
defaultPreviewSettingsis optional; omitted fields fall back to the built-in default. Only seeds the store onfirst visit — once the user changes a setting via the toolbar, their choice persists and wins on later loads.
Why
The responsive size picker currently always boots at 720px because
useStorageis seeded with{ responsiveWidth: 720, ... }inpackages/histoire-app/src/app/stores/preview-settings.ts. There is no way to change that seed fromdefineConfig. For projects where the typical primitive is best previewed at its natural width (forms, dialogs, list items) the 720px starting point reads like a bug — every story loads constrained until the user clicks the picker.The two pre-existing workarounds both have meaningful downsides:
defaultStoryProps.responsiveDisabled: true— removes the picker entirely, losing the ability to QA at mobile widths.responsivePresetswith a "Full" preset — fails becauseResponsivePreset.widthis typednumber(nonullallowed).This PR exposes the seed directly. The picker UI already handles
null(responsiveWidth.value ?? 'Auto'atStoryResponsivePreview.vue:121) so the implementation surface is small.What changed
packages/histoire-shared/src/types/config.tsPreviewSettingsinterface (moved frompackages/histoire-app/src/app/types.ts).defaultPreviewSettings?: Partial<PreviewSettings>toHistoireConfig.responsiveWidthandresponsiveHeightfromnumbertonumber | null. The runtime already passednullfor height; thenumber-only type was a latent mismatch. Picker UI's?? 'Auto'fallback only made sense if these were nullable.packages/histoire-app/src/app/types.tsPreviewSettingsre-exported from@histoire/shared.packages/histoire-app/src/app/stores/preview-settings.tsuseStorageseed merges built-in defaults withhistoireConfig.defaultPreviewSettings.docs/reference/config.mddefaultStoryPropsdocumenting the field.Test plan
defaultPreviewSettingsis omitted (built-in default preserved).defaultPreviewSettings.responsiveWidth: nullmakes the picker boot at "Auto" on a fresh local-storage state._histoire-sandbox-settings-v3in localStorage).Related
Closes #843