Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/angular/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
frameworkGlobalTypes,
frameworkSwitcher,
sharedParameters,
simplifyAngularDocsSource,
themeGlobalTypes,
themeInitialGlobals,
themeSwitcher,
Expand All @@ -18,6 +19,15 @@ export default {
parameters: {
...sharedParameters,
...a11yParameters,
docs: {
source: {
// Drop brackets around plain string args (e.g. `[variant]="variant"`
// -> `variant="outline"`) in the "Show code" snippet only — see
// simplifyAngularDocsSource for why the live story keeps binding them.
transform: (code: string, { args }: { args: Record<string, unknown> }) =>
simplifyAngularDocsSource(code, args),
},
},
// Must be a literal (Storybook reads it via static analysis, not
// execution). Keep in sync with packages/react/.storybook/preview.ts.
options: {
Expand Down
24 changes: 24 additions & 0 deletions packages/storybook-config/src/angular-docs-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Angular-only. `argsToTemplate()` (from `@storybook/angular`) always emits a
// property binding — `[variant]="variant"` — for every arg, because it has no
// way to know whether a value needs Angular expression evaluation or is just
// a static string. That's correct for the live canvas (bindings must be
// reactive so Controls can update it), but it makes the "Show code" snippet
// print brackets even for a plain enum like `variant` that carries no logic.
//
// This only rewrites the *displayed* source, via `docs.source.transform` —
// the story's real template still uses `argsToTemplate()` and stays reactive.
// It unwraps a passthrough binding `[key]="key"` into a plain attribute
// `key="value"`, and only for string-valued args (so `[disabled]="disabled"`
// and other non-string bindings, where the plain-attribute form would change
// meaning, are left untouched).
export function simplifyAngularDocsSource(
source: string,
args: Record<string, unknown> = {},
): string {
return Object.entries(args).reduce((code, [key, value]) => {
if (typeof value !== 'string') return code;
const pattern = new RegExp(`\\[${key}\\]="${key}"`, 'g');
const escaped = value.replace(/"/g, '&quot;');
return code.replace(pattern, () => `${key}="${escaped}"`);
}, source);
}
3 changes: 3 additions & 0 deletions packages/storybook-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export type {
// Browser-safe a11y config; the audit lives behind the `./test-runner` subpath.
export { WCAG_22_AA_TAGS, a11yParameters } from './a11y.js';

// Angular-only docs "Show code" cleanup; see the file for why.
export { simplifyAngularDocsSource } from './angular-docs-source.js';

// Shared preview parameters so every framework's Storybook renders stories the
// same way.
//
Expand Down
Loading