Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1761296
Reapply "Vue: Make globals reactive in decorators"
Sidnioulz Mar 12, 2026
6bda49b
Merge branch 'next' into reapply-vue-globals-reactivity-fix
Sidnioulz Mar 13, 2026
b1725c6
Apply suggestions from code review
yannbf Mar 13, 2026
089e2b7
Merge branch 'next' into reapply-vue-globals-reactivity-fix
Sidnioulz Mar 16, 2026
b2f06b9
UI: Hide addon panel Drag on pages without a panel
Sidnioulz Mar 16, 2026
bbb8384
UI: Hide manifest tag for now
Sidnioulz Mar 16, 2026
01b1051
fix(a11y): replace native disabled with isDisabled and aria-disabled …
WioletaKolodziej Aug 23, 2025
cff53d2
Finalise Button aria-disabled changes
Sidnioulz Mar 16, 2026
e53219d
Addon-Docs: Add React as optimizeDeps entry
valentinpalkovic Mar 17, 2026
c3dcbf7
CLI: Avoid hanging of postinstall during init
valentinpalkovic Mar 17, 2026
92c9867
Adjust remaining tests using toBeDisabled
Sidnioulz Mar 17, 2026
5b317a9
Merge pull request #34175 from storybookjs/valentin/fix-hanging-a11y-…
valentinpalkovic Mar 17, 2026
87bb33f
Merge pull request #34176 from storybookjs/valentin/add-react-as-opti…
valentinpalkovic Mar 17, 2026
084f24b
Write changelog for 10.3.0-beta.1 [skip ci]
storybook-bot Mar 17, 2026
585d934
Fix mistake in E2E test locator
Sidnioulz Mar 17, 2026
dc72631
Merge pull request #34177 from storybookjs/version-non-patch-from-10.…
yannbf Mar 17, 2026
a571619
Bump version from "10.3.0-beta.0" to "10.3.0-beta.1" [skip ci]
storybook-bot Mar 17, 2026
c22afbb
UI: Use correct selector for addon panel focus check
Sidnioulz Mar 16, 2026
8e90c6e
Merge branch 'next' into sidnioulz/10-3-fix-focus-in-addon-panel-root
Sidnioulz Mar 17, 2026
9e58af5
Merge branch 'next' into sidnioulz/issue-31678-aria-disabled-finish
Sidnioulz Mar 17, 2026
0d30f65
AGENTS.md: document that `next` is the base branch
kasperpeulen Mar 17, 2026
f1d7dea
Merge pull request #34181 from storybookjs/worktree-update-agents-md
kasperpeulen Mar 17, 2026
609f377
Merge branch 'next' into sidnioulz/issue-31678-aria-disabled-finish
Sidnioulz Mar 17, 2026
662b52f
Merge pull request #34116 from storybookjs/reapply-vue-globals-reacti…
Sidnioulz Mar 17, 2026
90d86a1
Merge pull request #34162 from storybookjs/sidnioulz/10-3-resize-tool…
Sidnioulz Mar 17, 2026
63a8d4a
Merge pull request #34165 from storybookjs/sidnioulz/10-3-hide-manife…
Sidnioulz Mar 17, 2026
b8449a4
Merge pull request #34166 from storybookjs/sidnioulz/issue-31678-aria…
Sidnioulz Mar 17, 2026
985382c
Merge pull request #34164 from storybookjs/sidnioulz/10-3-fix-focus-i…
Sidnioulz Mar 17, 2026
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This file is the canonical instruction source for coding agents. Files like `CLA

Storybook is a large TypeScript monorepo. The git root is the repo root, the main code lives in `code/`, and build tooling lives in `scripts/`.

- **Base branch**: `next` (all PRs should target `next`, not `main`)
- **Node.js**: `22.21.1` (see `.nvmrc`)
- **Package Manager**: Yarn Berry
- **Task orchestration**: NX plus the custom `yarn task` runner
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 10.3.0-beta.1

- Addon-Docs: Add React as optimizeDeps entry - [#34176](https://github.com/storybookjs/storybook/pull/34176), thanks @valentinpalkovic!
- CLI: Avoid hanging of postinstall during init - [#34175](https://github.com/storybookjs/storybook/pull/34175), thanks @valentinpalkovic!

## 10.3.0-beta.0

- Test: Fix clearing mocks in Vitest [#34078](https://github.com/storybookjs/storybook/pull/34078)
Expand Down
2 changes: 1 addition & 1 deletion code/addons/a11y/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-a11y",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Addon A11y: Test UI component compliance with WCAG web accessibility standards",
"keywords": [
"a11y",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-docs",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Docs: Document UI components automatically with stories and MDX",
"keywords": [
"docs",
Expand Down
1 change: 1 addition & 0 deletions code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ const optimizeViteDeps = [
'@storybook/addon-docs > @storybook/react-dom-shim',
'react-dom/client',
'react/jsx-runtime',
'react',
];

export { webpackX as webpack, docsX as docs, optimizeViteDeps };
Expand Down
2 changes: 1 addition & 1 deletion code/addons/links/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-links",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Links: Link stories together to build demos and prototypes with your UI components",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/onboarding/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-onboarding",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Onboarding: Help new users learn how to write stories",
"keywords": [
"storybook",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ export const Default: Story = {};
export const Submitting: Story = {
play: async ({ args }) => {
const button = await screen.findByRole('button', { name: 'Submit' });
await expect(button).toBeDisabled();
await expect(button).toHaveAttribute('aria-disabled', 'true');

await userEvent.click(await screen.findByText('Design system'));
await expect(button).toBeDisabled();
await expect(button).toHaveAttribute('aria-disabled', 'true');

await userEvent.click(await screen.findByText('Functional testing'));
await userEvent.click(await screen.findByText('Accessibility testing'));
await userEvent.click(await screen.findByText('Visual testing'));
await expect(button).toBeDisabled();
await expect(button).toHaveAttribute('aria-disabled', 'true');

await userEvent.selectOptions(screen.getByRole('combobox'), ['We use it at work']);
await expect(button).not.toBeDisabled();
await expect(button).not.toHaveAttribute('aria-disabled', 'true');

await userEvent.click(button);

await waitFor(async () => {
await expect(button).toBeDisabled();
await expect(button).toHaveAttribute('aria-disabled', 'true');
await expect(args.onComplete).toHaveBeenCalledWith({
building: {
'application-ui': false,
Expand Down
2 changes: 1 addition & 1 deletion code/addons/pseudo-states/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "storybook-addon-pseudo-states",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Pseudo-states addon: Manipulate CSS pseudo states",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/themes/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-themes",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Themes addon: Switch between themes from the toolbar",
"keywords": [
"css",
Expand Down
2 changes: 1 addition & 1 deletion code/addons/vitest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/addon-vitest",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook Vitest addon: Blazing fast component testing using stories",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-vite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/builder-vite",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "A Storybook builder to dev and build with Vite",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-webpack5/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@storybook/builder-webpack5",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "A Storybook builder to dev and build with Webpack",
"keywords": [
"storybook",
Expand Down
2 changes: 1 addition & 1 deletion code/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "storybook",
"version": "10.3.0-beta.0",
"version": "10.3.0-beta.1",
"description": "Storybook: Develop, document, and test UI components in isolation",
"keywords": [
"storybook",
Expand Down
84 changes: 42 additions & 42 deletions code/core/src/common/versions.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
// auto generated file, do not edit
export default {
'@storybook/addon-a11y': '10.3.0-beta.0',
'@storybook/addon-docs': '10.3.0-beta.0',
'@storybook/addon-links': '10.3.0-beta.0',
'@storybook/addon-onboarding': '10.3.0-beta.0',
'storybook-addon-pseudo-states': '10.3.0-beta.0',
'@storybook/addon-themes': '10.3.0-beta.0',
'@storybook/addon-vitest': '10.3.0-beta.0',
'@storybook/builder-vite': '10.3.0-beta.0',
'@storybook/builder-webpack5': '10.3.0-beta.0',
storybook: '10.3.0-beta.0',
'@storybook/angular': '10.3.0-beta.0',
'@storybook/ember': '10.3.0-beta.0',
'@storybook/html-vite': '10.3.0-beta.0',
'@storybook/nextjs': '10.3.0-beta.0',
'@storybook/nextjs-vite': '10.3.0-beta.0',
'@storybook/preact-vite': '10.3.0-beta.0',
'@storybook/react-native-web-vite': '10.3.0-beta.0',
'@storybook/react-vite': '10.3.0-beta.0',
'@storybook/react-webpack5': '10.3.0-beta.0',
'@storybook/server-webpack5': '10.3.0-beta.0',
'@storybook/svelte-vite': '10.3.0-beta.0',
'@storybook/sveltekit': '10.3.0-beta.0',
'@storybook/vue3-vite': '10.3.0-beta.0',
'@storybook/web-components-vite': '10.3.0-beta.0',
sb: '10.3.0-beta.0',
'@storybook/cli': '10.3.0-beta.0',
'@storybook/codemod': '10.3.0-beta.0',
'@storybook/core-webpack': '10.3.0-beta.0',
'create-storybook': '10.3.0-beta.0',
'@storybook/csf-plugin': '10.3.0-beta.0',
'eslint-plugin-storybook': '10.3.0-beta.0',
'@storybook/react-dom-shim': '10.3.0-beta.0',
'@storybook/preset-create-react-app': '10.3.0-beta.0',
'@storybook/preset-react-webpack': '10.3.0-beta.0',
'@storybook/preset-server-webpack': '10.3.0-beta.0',
'@storybook/html': '10.3.0-beta.0',
'@storybook/preact': '10.3.0-beta.0',
'@storybook/react': '10.3.0-beta.0',
'@storybook/server': '10.3.0-beta.0',
'@storybook/svelte': '10.3.0-beta.0',
'@storybook/vue3': '10.3.0-beta.0',
'@storybook/web-components': '10.3.0-beta.0',
'@storybook/addon-a11y': '10.3.0-beta.1',
'@storybook/addon-docs': '10.3.0-beta.1',
'@storybook/addon-links': '10.3.0-beta.1',
'@storybook/addon-onboarding': '10.3.0-beta.1',
'storybook-addon-pseudo-states': '10.3.0-beta.1',
'@storybook/addon-themes': '10.3.0-beta.1',
'@storybook/addon-vitest': '10.3.0-beta.1',
'@storybook/builder-vite': '10.3.0-beta.1',
'@storybook/builder-webpack5': '10.3.0-beta.1',
storybook: '10.3.0-beta.1',
'@storybook/angular': '10.3.0-beta.1',
'@storybook/ember': '10.3.0-beta.1',
'@storybook/html-vite': '10.3.0-beta.1',
'@storybook/nextjs': '10.3.0-beta.1',
'@storybook/nextjs-vite': '10.3.0-beta.1',
'@storybook/preact-vite': '10.3.0-beta.1',
'@storybook/react-native-web-vite': '10.3.0-beta.1',
'@storybook/react-vite': '10.3.0-beta.1',
'@storybook/react-webpack5': '10.3.0-beta.1',
'@storybook/server-webpack5': '10.3.0-beta.1',
'@storybook/svelte-vite': '10.3.0-beta.1',
'@storybook/sveltekit': '10.3.0-beta.1',
'@storybook/vue3-vite': '10.3.0-beta.1',
'@storybook/web-components-vite': '10.3.0-beta.1',
sb: '10.3.0-beta.1',
'@storybook/cli': '10.3.0-beta.1',
'@storybook/codemod': '10.3.0-beta.1',
'@storybook/core-webpack': '10.3.0-beta.1',
'create-storybook': '10.3.0-beta.1',
'@storybook/csf-plugin': '10.3.0-beta.1',
'eslint-plugin-storybook': '10.3.0-beta.1',
'@storybook/react-dom-shim': '10.3.0-beta.1',
'@storybook/preset-create-react-app': '10.3.0-beta.1',
'@storybook/preset-react-webpack': '10.3.0-beta.1',
'@storybook/preset-server-webpack': '10.3.0-beta.1',
'@storybook/html': '10.3.0-beta.1',
'@storybook/preact': '10.3.0-beta.1',
'@storybook/react': '10.3.0-beta.1',
'@storybook/server': '10.3.0-beta.1',
'@storybook/svelte': '10.3.0-beta.1',
'@storybook/vue3': '10.3.0-beta.1',
'@storybook/web-components': '10.3.0-beta.1',
};
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ TestFunctionTypes.test(
},
async ({ canvas }) => {
const button = canvas.getByText('Arg from story');
await expect(button).toBeEnabled();
await expect(button).not.toHaveAttribute('aria-disabled', 'true');
}
);

Expand All @@ -106,7 +106,7 @@ export const ExtendedStorySinglePlayExample = TestFunctionTypes.extend({
},
play: async ({ canvas }) => {
const button = canvas.getByText('Arg from extended story');
await expect(button).toBeEnabled();
await expect(button).not.toHaveAttribute('aria-disabled', 'true');
},
});

Expand All @@ -120,7 +120,7 @@ ExtendedStorySingleTestExample.test(
'this is a very long test name to explain that this story test should guarantee that the args have been extended correctly',
async ({ canvas }) => {
const button = canvas.getByText('Arg from extended story');
await expect(button).toBeEnabled();
await expect(button).not.toHaveAttribute('aria-disabled', 'true');
}
);

Expand Down
28 changes: 27 additions & 1 deletion code/core/src/components/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { FaceHappyIcon } from '@storybook/icons';

import { fn } from 'storybook/test';
import { expect, fn } from 'storybook/test';
import { styled } from 'storybook/theming';

import preview from '../../../../../.storybook/preview';
Expand Down Expand Up @@ -291,6 +291,32 @@ export const Disabled = meta.story({
ariaLabel: false,
disabled: true,
children: 'Disabled Button',
onClick: fn(),
},
render: (args) => (
<Row>
<Button variant="solid" {...args}>
Disabled Button
</Button>
</Row>
),
play: async ({ args, canvas, step }) => {
const button = canvas.getByRole('button', { name: 'Disabled Button' });

await step('Disabled button should be aria-disabled', async () => {
expect(button).toHaveAttribute('aria-disabled', 'true');
});

await step('Disabled button should not be clickable', async () => {
button.click();
expect(args.onClick).not.toHaveBeenCalled();
});

await step('Disabled button should be focusable for accessibility', async () => {
const button = canvas.getByRole('button', { name: 'Disabled Button' });
button.focus();
expect(button).toHaveFocus();
});
},
});

Expand Down
13 changes: 7 additions & 6 deletions code/core/src/components/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,13 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
variant={variant}
size={size}
padding={padding}
disabled={disabled || readOnly}
$disabled={disabled || readOnly}
aria-disabled={disabled || readOnly ? 'true' : undefined}
readOnly={readOnly}
active={active}
animating={isAnimating}
animation={animation}
onClick={handleClick}
onClick={disabled || readOnly ? undefined : handleClick}
aria-label={!readOnly && ariaLabel !== false ? ariaLabel : undefined}
aria-keyshortcuts={readOnly ? undefined : shortcutAttribute}
{...(readOnly ? {} : ariaDescriptionAttrs)}
Expand All @@ -165,7 +166,7 @@ const StyledButton = styled('button', {
padding?: 'small' | 'medium' | 'none';
variant?: 'outline' | 'solid' | 'ghost';
active?: boolean;
disabled?: boolean;
$disabled?: boolean;
readOnly?: boolean;
animating?: boolean;
animation?: 'none' | 'rotate360' | 'glow' | 'jiggle';
Expand All @@ -174,15 +175,15 @@ const StyledButton = styled('button', {
theme,
variant,
size,
disabled,
$disabled,
readOnly,
active,
animating,
animation = 'none',
padding,
}) => ({
border: 0,
cursor: readOnly ? 'inherit' : disabled ? 'not-allowed' : 'pointer',
cursor: readOnly ? 'inherit' : $disabled ? 'not-allowed' : 'pointer',
display: 'inline-flex',
gap: '6px',
alignItems: 'center',
Expand Down Expand Up @@ -216,7 +217,7 @@ const StyledButton = styled('button', {
verticalAlign: 'top',
whiteSpace: 'nowrap',
userSelect: 'none',
opacity: disabled && !readOnly ? 0.5 : 1,
opacity: $disabled && !readOnly ? 0.5 : 1,
margin: 0,
fontSize: `${theme.typography.size.s1}px`,
fontWeight: theme.typography.weight.bold,
Expand Down
13 changes: 7 additions & 6 deletions code/core/src/manager-api/modules/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import { focusableUIElements } from './layout';

const { navigator, document } = global;

function wasFocusInElement(element: HTMLElement | null) {
return document.activeElement && element?.contains(document.activeElement);
}

export const isMacLike = () =>
navigator && navigator.platform ? !!navigator.platform.match(/(Mac|iPhone|iPod|iPad)/i) : false;
export const controlOrMetaKey = () => (isMacLike() ? 'meta' : 'control');
Expand Down Expand Up @@ -359,13 +363,11 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) => {

case 'togglePanel': {
const wasPanelShown = fullAPI.getIsPanelShown();
const panelElement = document.getElementById(focusableUIElements.storyPanelRoot);
const wasFocusInPanel =
panelElement && document.activeElement && panelElement.contains(document.activeElement);
const panelElement = document.getElementById(focusableUIElements.addonPanel);

fullAPI.togglePanel();

if (wasPanelShown && wasFocusInPanel) {
if (wasPanelShown && wasFocusInElement(panelElement)) {
// poll: true always returns a Promise.
(
fullAPI.focusOnUIElement(focusableUIElements.showAddonPanel, {
Expand All @@ -384,11 +386,10 @@ export const init: ModuleFn = ({ store, fullAPI, provider }) => {
case 'toggleNav': {
const wasNavShown = fullAPI.getIsNavShown();
const sidebarElement = document.getElementById(focusableUIElements.sidebarRegion);
const wasFocusInSidebar = sidebarElement?.contains(document?.activeElement);

fullAPI.toggleNav();

if (wasNavShown && wasFocusInSidebar) {
if (wasNavShown && wasFocusInElement(sidebarElement)) {
// poll: true always returns a Promise.
(
fullAPI.focusOnUIElement(focusableUIElements.showSidebar, {
Expand Down
2 changes: 1 addition & 1 deletion code/core/src/manager-api/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version = '10.3.0-beta.0';
export const version = '10.3.0-beta.1';
Loading
Loading