Skip to content
Merged
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 10.2.8

- Telemetry: Add Expo metaframework - [#33783](https://github.com/storybookjs/storybook/pull/33783), thanks @copilot-swe-agent!
- Telemetry: Add init exit event - [#33773](https://github.com/storybookjs/storybook/pull/33773), thanks @valentinpalkovic!
- Telemetry: Add share events - [#33766](https://github.com/storybookjs/storybook/pull/33766), thanks @ndelangen!
- Test: Update event creation logic in user-event package - [#33787](https://github.com/storybookjs/storybook/pull/33787), thanks @valentinpalkovic!

## 10.2.7

- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!
Expand Down
5 changes: 2 additions & 3 deletions code/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,9 @@ module.exports = {
'import-x/no-named-as-default-member': 'warn',
'react/destructuring-assignment': 'warn',

// This warns about importing interfaces and types in a normal import, it's arguably better to import with the `type` prefix separate from the runtime imports,
// I leave this as a warning right now because we haven't really decided yet, and the codebase is riddled with errors if I set to 'error'.
// Our codebase is mostly TypeScript, and typescript will warn when imports are not found.
// It IS set to 'error' for JS files.
'import-x/named': 'warn',
'import-x/named': 'off',
},
},
{
Expand Down
7 changes: 7 additions & 0 deletions code/core/src/core-events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ enum events {
OPEN_IN_EDITOR_RESPONSE = 'openInEditorResponse',
// Emitted when the manager UI sets up a focus trap
MANAGER_INERT_ATTRIBUTE_CHANGED = 'managerInertAttributeChanged',

SHARE_STORY_LINK = 'shareStoryLink',
SHARE_ISOLATE_MODE = 'shareIsolateMode',
SHARE_POPOVER_OPENED = 'sharePopoverOpened',
}

// Enables: `import Events from ...`
Expand Down Expand Up @@ -167,6 +171,9 @@ export const {
OPEN_IN_EDITOR_REQUEST,
OPEN_IN_EDITOR_RESPONSE,
MANAGER_INERT_ATTRIBUTE_CHANGED,
SHARE_STORY_LINK,
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
} = events;

export * from './data/create-new-story';
Expand Down
4 changes: 2 additions & 2 deletions code/core/src/core-server/presets/common-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { initCreateNewStoryChannel } from '../server-channel/create-new-story-ch
import { initFileSearchChannel } from '../server-channel/file-search-channel';
import { initGhostStoriesChannel } from '../server-channel/ghost-stories-channel';
import { initOpenInEditorChannel } from '../server-channel/open-in-editor-channel';
import { initPreviewInitializedChannel } from '../server-channel/preview-initialized-channel';
import { initTelemetryChannel } from '../server-channel/telemetry-channel';
import { initializeChecklist } from '../utils/checklist';
import { defaultFavicon, defaultStaticDirs } from '../utils/constants';
import { initializeSaveStory } from '../utils/save-story/save-story';
Expand Down Expand Up @@ -264,7 +264,7 @@ export const experimental_serverChannel = async (
initCreateNewStoryChannel(channel, options, coreOptions);
initGhostStoriesChannel(channel, options, coreOptions);
initOpenInEditorChannel(channel, options, coreOptions);
initPreviewInitializedChannel(channel, options, coreOptions);
initTelemetryChannel(channel, options);

return channel;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

import { makePayload } from './preview-initialized-channel';
import { makePayload } from './telemetry-channel';

describe('makePayload', () => {
beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import type { Channel } from 'storybook/internal/channels';
import { PREVIEW_INITIALIZED } from 'storybook/internal/core-events';
import {
PREVIEW_INITIALIZED,
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
SHARE_STORY_LINK,
} from 'storybook/internal/core-events';
import { type InitPayload, telemetry } from 'storybook/internal/telemetry';
import { type CacheEntry, getLastEvents } from 'storybook/internal/telemetry';
import { getSessionId } from 'storybook/internal/telemetry';
import type { CoreConfig, Options } from 'storybook/internal/types';
import type { Options } from 'storybook/internal/types';

export const makePayload = (
userAgent: string,
Expand All @@ -24,13 +29,9 @@ export const makePayload = (
return payload;
};

export function initPreviewInitializedChannel(
channel: Channel,
options: Options,
_coreConfig: CoreConfig
) {
channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => {
if (!options.disableTelemetry) {
export function initTelemetryChannel(channel: Channel, options: Options) {
if (!options.disableTelemetry) {
channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => {
try {
const sessionId = await getSessionId();
const lastEvents = await getLastEvents();
Expand All @@ -40,9 +41,16 @@ export function initPreviewInitializedChannel(
const payload = makePayload(userAgent, lastInit, sessionId);
telemetry('preview-first-load', payload);
}
} catch (e) {
// do nothing
}
}
});
} catch {}
});
channel.on(SHARE_POPOVER_OPENED, async () => {
telemetry('share', { action: 'popover-opened' });
});
channel.on(SHARE_STORY_LINK, async () => {
telemetry('share', { action: 'story-link-copied' });
});
channel.on(SHARE_ISOLATE_MODE, async () => {
telemetry('share', { action: 'isolate-mode-opened' });
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { global } from '@storybook/global';
import type { StoryObj } from '@storybook/react-vite';

import { ManagerContext } from 'storybook/manager-api';
import { expect, screen, waitFor } from 'storybook/test';
import { expect, fn, screen, waitFor } from 'storybook/test';

import { shareTool } from './share';

Expand All @@ -15,6 +15,7 @@ const managerContext = {
refId: undefined,
},
api: {
emit: fn().mockName('api::emit'),
getShortcutKeys: () => ({
copyStoryLink: ['alt', 'shift', 'l'],
openInIsolation: ['alt', 'shift', 'i'],
Expand Down
15 changes: 14 additions & 1 deletion code/core/src/manager/components/preview/tools/share.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React, { useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';

import { Button, PopoverProvider, TooltipLinkList } from 'storybook/internal/components';
import {
SHARE_ISOLATE_MODE,
SHARE_POPOVER_OPENED,
SHARE_STORY_LINK,
} from 'storybook/internal/core-events';
import type { Addon_BaseType } from 'storybook/internal/types';

import { global } from '@storybook/global';
Expand Down Expand Up @@ -71,6 +76,10 @@ const ShareMenu = React.memo(function ShareMenu({
const copyStoryLink = shortcutKeys?.copyStoryLink;
const openInIsolation = shortcutKeys?.openInIsolation;

useEffect(() => {
api.emit(SHARE_POPOVER_OPENED);
}, [api]);

const links = useMemo(() => {
const copyTitle = copied ? 'Copied!' : 'Copy story link';
const originHrefs = api.getStoryHrefs(storyId, { base: 'origin', refId });
Expand All @@ -84,6 +93,7 @@ const ShareMenu = React.memo(function ShareMenu({
icon: <LinkIcon />,
right: enableShortcuts ? <Shortcut keys={copyStoryLink} /> : null,
onClick: () => {
api.emit(SHARE_STORY_LINK, originHrefs.managerHref);
copy(originHrefs.managerHref);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
Expand All @@ -94,6 +104,9 @@ const ShareMenu = React.memo(function ShareMenu({
title: 'Open in isolation mode',
icon: <ShareAltIcon />,
right: enableShortcuts ? <Shortcut keys={openInIsolation} /> : null,
onClick: () => {
api.emit(SHARE_ISOLATE_MODE, originHrefs.previewHref);
},
href: originHrefs.previewHref,
target: '_blank',
rel: 'noopener noreferrer',
Expand Down
3 changes: 3 additions & 0 deletions code/core/src/manager/globals/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ export default {
'SET_WHATS_NEW_CACHE',
'SHARED_STATE_CHANGED',
'SHARED_STATE_SET',
'SHARE_ISOLATE_MODE',
'SHARE_POPOVER_OPENED',
'SHARE_STORY_LINK',
'STORIES_COLLAPSE_ALL',
'STORIES_EXPAND_ALL',
'STORY_ARGS_UPDATED',
Expand Down
1 change: 1 addition & 0 deletions code/core/src/telemetry/storybook-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const metaFrameworks = {
'@tanstack/react-router': 'tanstack-react',
'@react-router/dev': 'react-router',
'@remix-run/dev': 'remix',
expo: 'expo',
} as Record<string, string>;

export const sanitizeAddonName = (name: string) => {
Expand Down
2 changes: 2 additions & 0 deletions code/core/src/telemetry/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type EventType =
| 'scaffolded-empty'
| 'browser'
| 'canceled'
| 'exit'
| 'error'
| 'error-metadata'
| 'version-update'
Expand All @@ -42,6 +43,7 @@ export type EventType =
| 'migrate'
| 'preview-first-load'
| 'doctor'
| 'share'
| 'ghost-stories';
export interface Dependency {
version: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ProjectType } from 'storybook/internal/cli';
import type { JsPackageManager } from 'storybook/internal/common';
import { logger, prompt } from 'storybook/internal/node-logger';
import { telemetry } from 'storybook/internal/telemetry';
import type { SupportedLanguage } from 'storybook/internal/types';

import picocolors from 'picocolors';
Expand Down Expand Up @@ -91,6 +92,13 @@ We assume that Storybook is already instantiated for your project. Do you still
if (force || options.yes) {
options.force = true;
} else {
if (!options.disableTelemetry) {
await telemetry(
'exit',
{ eventType: 'init', reason: 'existing-installation' },
{ stripMetadata: true, immediate: true }
);
}
process.exit(0);
}
}
Expand Down
7 changes: 7 additions & 0 deletions code/lib/create-storybook/src/scaffold-new-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ export const scaffoldNewProject = async (
}

if (projectStrategy === 'other') {
if (!disableTelemetry) {
await telemetry(
'exit',
{ eventType: 'init', reason: 'scaffold-other' },
{ stripMetadata: true, immediate: true }
);
}
logger.warn(
'To install Storybook on another framework, first generate a project with that framework and then rerun this command.'
);
Expand Down
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,5 +220,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "10.2.8"
}
2 changes: 1 addition & 1 deletion docs/versions/latest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"10.2.7","info":{"plain":"- CSF: Fix cross-file story imports in csf-factories codemod - [#33723](https://github.com/storybookjs/storybook/pull/33723), thanks @yatishgoel!\n- Core: Fix rendering of View Transitions in Firefox - [#33651](https://github.com/storybookjs/storybook/pull/33651), thanks @ghengeveld!\n- Globals: Repair dynamicTitle: false for user-defined tools - [#33284](https://github.com/storybookjs/storybook/pull/33284), thanks @ia319!\n- Logger: Honor --loglevel for npmlog output - [#33776](https://github.com/storybookjs/storybook/pull/33776), thanks @LouisLau-art!"}}
{"version":"10.2.8","info":{"plain":"- Telemetry: Add Expo metaframework - [#33783](https://github.com/storybookjs/storybook/pull/33783), thanks @copilot-swe-agent!\n- Telemetry: Add init exit event - [#33773](https://github.com/storybookjs/storybook/pull/33773), thanks @valentinpalkovic!\n- Telemetry: Add share events - [#33766](https://github.com/storybookjs/storybook/pull/33766), thanks @ndelangen!\n- Test: Update event creation logic in user-event package - [#33787](https://github.com/storybookjs/storybook/pull/33787), thanks @valentinpalkovic!"}}
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8951,10 +8951,10 @@ __metadata:

"@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch":
version: 14.6.1
resolution: "@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch::version=14.6.1&hash=228211"
resolution: "@testing-library/user-event@patch:@testing-library/user-event@npm%3A14.6.1#~/.yarn/patches/@testing-library-user-event-npm-14.6.1-5da7e1d4e2.patch::version=14.6.1&hash=4faa83"
peerDependencies:
"@testing-library/dom": ">=7.21.4"
checksum: 10c0/837761d0a6f87268e0e4c69c1afaf14ddadea51aab44e82d22a12e1ae7c970f9af900b7d7379ed672132b76694c32f8cbd786020300261e805b499898b8f20f4
checksum: 10c0/b3d9c3351e7a3bb9169bd5262aaad7911647cf38d4f24d217561481a028fe3a5d0fbd9e6320017a264c4ef2bd52947079e3c665bd6a768ff85780da1012e3672
languageName: node
linkType: hard

Expand Down