Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release: Preminor alpha 7.3.0-alpha.0 #23794

Merged
merged 28 commits into from
Aug 11, 2023
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
615db42
Don't assign values to all slots (rollback to v7.0.27)
kasperpeulen Aug 3, 2023
35f1766
Merge branch 'next' into kasper/vue3-slots
kasperpeulen Aug 3, 2023
bb06edf
Merge branch 'next' into kasper/vue3-slots
kasperpeulen Aug 3, 2023
1582887
Merge branch 'next' into kasper/vue3-slots
kasperpeulen Aug 4, 2023
7d4f4a4
Merge branch 'next' into kasper/vue3-slots
kasperpeulen Aug 7, 2023
a1406c7
Update CHANGELOG.md for v7.2.2 [skip ci]
storybook-bot Aug 9, 2023
354d1ba
Merge branch 'next-release' into next
storybook-bot Aug 10, 2023
d89dee3
Update postinstall to look for addon script
Aug 10, 2023
d4ca02a
Deprecate key in addon render function as it is not available anymore
kasperpeulen Aug 10, 2023
9550c42
Fix TS checks
kasperpeulen Aug 10, 2023
0eaaa8c
Merge pull request #23792 from storybookjs/kasper/bug-23782
kasperpeulen Aug 10, 2023
910b671
Improve Icon component
cdedreuille Aug 10, 2023
d964d59
Added the new Toolbar component
cdedreuille Aug 10, 2023
b157376
Don't log when there is no postinstall script
Aug 10, 2023
c75a8fc
Adds more video coverage to the documentation
jonniebigodes Aug 10, 2023
601e902
Moves video up and callout
jonniebigodes Aug 10, 2023
af906e2
Merge pull request #23797 from storybookjs/chore_docs_adds_videos
jonniebigodes Aug 10, 2023
19d26cc
Merge pull request #23791 from storybookjs/shaun/new-add-cmd
shilman Aug 11, 2023
df451e7
Fix Safari bug with static keyword
kasperpeulen Aug 11, 2023
c936edc
Support Safari 15, Firefox 91 and Chrome 100
kasperpeulen Aug 11, 2023
8d8fc73
Merge pull request #23800 from storybookjs/kasper/fix-safari-static
kasperpeulen Aug 11, 2023
3ba0d68
Update CHANGELOG.md for v7.2.3 [skip ci]
storybook-bot Aug 11, 2023
ae80dc4
Merge pull request #23795 from storybookjs/charles-ui-updates
cdedreuille Aug 11, 2023
0dcbaed
Upgrade Addon Design
cdedreuille Aug 11, 2023
8413307
Merge branch 'next' into kasper/vue3-slots
kasperpeulen Aug 11, 2023
8e6cfb4
Merge pull request #23806 from storybookjs/charles-upgrade-addon-design
cdedreuille Aug 11, 2023
f158786
Merge pull request #23697 from storybookjs/kasper/vue3-slots
kasperpeulen Aug 11, 2023
d9ee3e5
Write changelog for 7.3.0-alpha.0
storybook-bot Aug 11, 2023
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 7.2.3

- Build: Support Chrome 100, Safari 15 and Firefox 91 - [#23800](https://github.com/storybookjs/storybook/pull/23800), thanks [@kasperpeulen](https://github.com/kasperpeulen)!

## 7.2.2

- CSF-Tools: Remove prettier from printConfig - [#23766](https://github.com/storybookjs/storybook/pull/23766), thanks [@kasperpeulen](https://github.com/kasperpeulen)!

## 7.2.1

- Addon docs: Add safe check in Webpack preset - [#23687](https://github.com/storybookjs/storybook/pull/23687), thanks [@yannbf](https://github.com/yannbf)!
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 7.3.0-alpha.0

- Addons: Deprecate key in addon render function as it is not available anymore - [#23792](https://github.com/storybookjs/storybook/pull/23792), thanks [@kasperpeulen](https://github.com/kasperpeulen)!
- Build: Support Chrome 100, Safari 15 and Firefox 91 - [#23800](https://github.com/storybookjs/storybook/pull/23800), thanks [@kasperpeulen](https://github.com/kasperpeulen)!
- CLI: Update postinstall to look for addon script - [#23791](https://github.com/storybookjs/storybook/pull/23791), thanks [@Integrayshaun](https://github.com/Integrayshaun)!
- UI: Update IconButton and add new Toolbar component - [#23795](https://github.com/storybookjs/storybook/pull/23795), thanks [@cdedreuille](https://github.com/cdedreuille)!
- UI: Upgrade Addon Design - [#23806](https://github.com/storybookjs/storybook/pull/23806), thanks [@cdedreuille](https://github.com/cdedreuille)!
- Vue3: Don't assign values to all slots (rollback to v7.0.27) - [#23697](https://github.com/storybookjs/storybook/pull/23697), thanks [@kasperpeulen](https://github.com/kasperpeulen)!

## 7.2.2-alpha.1

- CSF-Tools: Remove prettier from printConfig - [#23766](https://github.com/storybookjs/storybook/pull/23766), thanks [@kasperpeulen](https://github.com/kasperpeulen)!
Expand Down
2 changes: 1 addition & 1 deletion code/builders/builder-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const getConfig: ManagerBuilder['getConfig'] = async (options) => {
'.eot': 'dataurl',
'.ttf': 'dataurl',
},
target: ['chrome100'],
target: ['chrome100', 'safari15', 'firefox91'],
platform: 'browser',
bundle: true,
minify: true,
Expand Down
59 changes: 16 additions & 43 deletions code/lib/cli/src/add.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import path from 'path';
import fs from 'fs';
import { sync as spawnSync } from 'cross-spawn';

import { getStorybookInfo } from '@storybook/core-common';
import { readConfig, writeConfig } from '@storybook/csf-tools';

import { commandLog } from './helpers';
import {
JsPackageManagerFactory,
useNpmWarning,
Expand All @@ -15,43 +10,21 @@ import { getStorybookVersion } from './utils';

const logger = console;

const LEGACY_CONFIGS = ['addons', 'config', 'presets'];

const postinstallAddon = async (addonName: string, isOfficialAddon: boolean) => {
let skipMsg = null;
if (!isOfficialAddon) {
skipMsg = 'unofficial addon';
} else if (!fs.existsSync('.storybook')) {
skipMsg = 'no .storybook config';
} else {
skipMsg = 'no codmods found';
LEGACY_CONFIGS.forEach((config) => {
try {
const codemod = require.resolve(
// @ts-expect-error (it is broken)
`${getPackageName(addonName, isOfficialAddon)}/postinstall/${config}.js`
);
commandLog(`Running postinstall script for ${addonName}`)();
let configFile = path.join('.storybook', `${config}.ts`);
if (!fs.existsSync(configFile)) {
configFile = path.join('.storybook', `${config}.js`);
if (!fs.existsSync(configFile)) {
fs.writeFileSync(configFile, '', 'utf8');
}
}
spawnSync('npx', ['jscodeshift', '-t', codemod, configFile], {
stdio: 'inherit',
shell: true,
});
skipMsg = null;
} catch (err) {
// resolve failed, skip
}
});
}
const postinstallAddon = async (addonName: string) => {
try {
const modulePath = require.resolve(`${addonName}/postinstall`, { paths: [process.cwd()] });
// eslint-disable-next-line import/no-dynamic-require, global-require
const postinstall = require(modulePath);

if (skipMsg) {
commandLog(`Skipping postinstall for ${addonName}, ${skipMsg}`)();
try {
logger.log(`Running postinstall script for ${addonName}`);
await postinstall();
} catch (e) {
logger.error(`Error running postinstall script for ${addonName}`);
logger.error(e);
}
} catch (e) {
// no postinstall script
}
};

Expand Down Expand Up @@ -109,7 +82,7 @@ export async function add(
main.appendValueToArray(['addons'], addonName);
await writeConfig(main);

if (!options.skipPostinstall) {
await postinstallAddon(addon, isStorybookAddon);
if (!options.skipPostinstall && isStorybookAddon) {
await postinstallAddon(addonName);
}
}
4 changes: 1 addition & 3 deletions code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ const babelContent = JSON.stringify({
[
'@babel/preset-env',
{
targets: {
chrome: 100,
},
targets: { chrome: 100, safari: 15, firefox: 91 },
},
],
'@babel/preset-typescript',
Expand Down
4 changes: 3 additions & 1 deletion code/lib/cli/src/babel-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export const writeBabelConfigFile = async ({
}) => {
const fileLocation = location || path.join(process.cwd(), '.babelrc.json');

const presets: (string | [string, any])[] = [['@babel/preset-env', { targets: { chrome: 100 } }]];
const presets: (string | [string, any])[] = [
['@babel/preset-env', { targets: { chrome: 100, safari: 15, firefox: 91 } }],
];

if (typescript) {
presets.push('@babel/preset-typescript');
Expand Down
6 changes: 5 additions & 1 deletion code/lib/types/src/modules/addons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,11 @@ export type BaseStory<TArgs, StoryFnReturnType> =

export interface Addon_RenderOptions {
active: boolean;
key: string;
/**
* @deprecated You should not use key anymore as of Storybook 7.2 this render method is invoked as a React component.
* This property will be removed in 8.0.
* */
key?: unknown;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,5 +326,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "7.3.0-alpha.0"
}
22 changes: 8 additions & 14 deletions code/renderers/vue3/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { App } from 'vue';
import { createApp, h, reactive, isVNode, isReactive } from 'vue';
import type { ArgsStoryFn, RenderContext } from '@storybook/types';
import type { Args, StoryContext } from '@storybook/csf';

import type { StoryFnVueReturnType, StoryID, VueRenderer } from './types';

export const render: ArgsStoryFn<VueRenderer> = (props, context) => {
Expand All @@ -14,7 +13,7 @@ export const render: ArgsStoryFn<VueRenderer> = (props, context) => {
);
}

return () => h(Component, props, generateSlots(context));
return () => h(Component, props, getSlots(props, context));
};

// set of setup functions that will be called when story is created
Expand All @@ -36,7 +35,6 @@ const map = new Map<
{
vueApp: ReturnType<typeof createApp>;
reactiveArgs: Args;
reactiveSlots?: Args;
}
>();

Expand Down Expand Up @@ -93,20 +91,16 @@ export function renderToCanvas(

/**
* generate slots for default story without render function template
* @param context
*/

function generateSlots(context: StoryContext<VueRenderer, Args>) {
function getSlots(props: Args, context: StoryContext<VueRenderer, Args>) {
const { argTypes } = context;
const slots = Object.entries(argTypes)
.filter(([key, value]) => argTypes[key]?.table?.category === 'slots')
.map(([key, value]) => {
const slotValue = context.args[key];
return [key, typeof slotValue === 'function' ? slotValue : () => slotValue];
});

return reactive(Object.fromEntries(slots));
const slots = Object.entries(props)
.filter(([key]) => argTypes[key]?.table?.category === 'slots')
.map(([key, value]) => [key, typeof value === 'function' ? value : () => value]);

return Object.fromEntries(slots);
}

/**
* get the args from the root element props if it is a vnode otherwise from the context
* @param element is the root element of the story
Expand Down
1 change: 1 addition & 0 deletions code/ui/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
},
"dependencies": {
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-toolbar": "^1.0.4",
"@storybook/client-logger": "workspace:*",
"@storybook/csf": "^0.1.0",
"@storybook/global": "^5.0.0",
Expand Down
1 change: 1 addition & 0 deletions code/ui/components/src/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { Select } from './new/Select/Select';
export { Link } from './new/Link/Link';
export { Icon } from './new/Icon/Icon';
export { IconButton } from './new/IconButton/IconButton';
export { Toolbar } from './new/Toolbar/Toolbar';
32 changes: 7 additions & 25 deletions code/ui/components/src/legacy/tabs/tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,12 @@ type Panels = Record<string, Omit<ChildrenList[0], 'id'>>;
const panels: Panels = {
test1: {
title: 'Tab title #1',
render: ({ active, key }) =>
active ? (
<div id="test1" key={key}>
CONTENT 1
</div>
) : null,
render: ({ active }) => (active ? <div id="test1">CONTENT 1</div> : null),
},
test2: {
title: 'Tab title #2',
render: ({ active, key }) => (
render: ({ active }) => (
<div
key={key}
id="test2"
style={{
background: 'hotpink',
Expand All @@ -72,9 +66,9 @@ const panels: Panels = {
},
test3: {
title: 'Tab title #3',
render: ({ active, key }) =>
render: ({ active }) =>
active ? (
<div id="test3" key={key}>
<div id="test3">
{colours.map((colour, i) => (
<div
key={colour}
Expand All @@ -89,27 +83,15 @@ const panels: Panels = {
},
test4: {
title: 'Tab title #4',
render: ({ active, key }) =>
active ? (
<div key={key} id="test4">
CONTENT 4
</div>
) : null,
render: ({ active }) => (active ? <div id="test4">CONTENT 4</div> : null),
},
test5: {
title: 'Tab title #5',
render: ({ active, key }) =>
active ? (
<div key={key} id="test5">
CONTENT 5
</div>
) : null,
render: ({ active }) => (active ? <div id="test5">CONTENT 5</div> : null),
},
test6: {
title: 'Tab title #6',
render: ({ active, key }) => (
<TabWrapper key={key} active={active} render={() => <div>CONTENT 6</div>} />
),
render: ({ active }) => <TabWrapper active={active} render={() => <div>CONTENT 6</div>} />,
},
};

Expand Down
14 changes: 14 additions & 0 deletions code/ui/components/src/new/IconButton/IconButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ export const Disabled: Story = {
},
};

export const Animated: Story = {
args: {
...Base.args,
icon: 'FaceHappy',
},
render: () => (
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
<IconButton icon="FaceHappy" onClickAnimation="glow" />
<IconButton icon="FaceHappy" onClickAnimation="rotate360" />
<IconButton icon="FaceHappy" onClickAnimation="jiggle" />
</div>
),
};

export const WithHref: Story = {
render: () => (
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
Expand Down
46 changes: 38 additions & 8 deletions code/ui/components/src/new/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,61 @@
import React, { forwardRef } from 'react';
import type { SyntheticEvent } from 'react';
import React, { forwardRef, useEffect, useState } from 'react';
import { styled } from '@storybook/theming';
import { darken, lighten, rgba, transparentize } from 'polished';
import type { Icons } from '@storybook/icons';
import type { PropsOf } from '../utils/types';
import { Icon } from '../Icon/Icon';

interface ButtonProps<T extends React.ElementType = React.ElementType> {
interface IconButtonProps<T extends React.ElementType = React.ElementType> {
icon: Icons;
as?: T;
size?: 'small' | 'medium';
variant?: 'solid' | 'outline' | 'ghost';
onClick?: () => void;
onClick?: (event: SyntheticEvent) => void;
disabled?: boolean;
active?: boolean;
onClickAnimation?: 'none' | 'rotate360' | 'glow' | 'jiggle';
}

export const IconButton: {
<E extends React.ElementType = 'button'>(
props: ButtonProps<E> & Omit<PropsOf<E>, keyof ButtonProps>
props: IconButtonProps<E> & Omit<PropsOf<E>, keyof IconButtonProps>
): JSX.Element;
displayName?: string;
} = forwardRef(
({ as, icon = 'FaceHappy', ...props }: ButtonProps, ref: React.Ref<HTMLButtonElement>) => {
(
{ as, icon = 'FaceHappy', onClickAnimation = 'none', onClick, ...props }: IconButtonProps,
ref: React.Ref<HTMLButtonElement>
) => {
const LocalIcon = Icon[icon];
const [isAnimating, setIsAnimating] = useState(false);

const handleClick = (event: SyntheticEvent) => {
if (onClick) onClick(event);
if (onClickAnimation === 'none') return;
setIsAnimating(true);
};

useEffect(() => {
const timer = setTimeout(() => {
if (isAnimating) setIsAnimating(false);
}, 1000);
return () => clearTimeout(timer);
}, [isAnimating]);

return (
<StyledButton as={as} ref={ref} {...props}>
{icon && <LocalIcon />}
<StyledButton as={as} ref={ref} {...props} onClick={handleClick}>
<IconWrapper isAnimating={isAnimating} animation={onClickAnimation}>
<LocalIcon />
</IconWrapper>
</StyledButton>
);
}
);

IconButton.displayName = 'IconButton';

const StyledButton = styled.button<Omit<ButtonProps, 'icon'>>(
const StyledButton = styled.button<Omit<IconButtonProps, 'icon'>>(
({ theme, variant = 'solid', size = 'medium', disabled = false, active = false }) => ({
border: 0,
cursor: disabled ? 'not-allowed' : 'pointer',
Expand Down Expand Up @@ -109,3 +130,12 @@ const StyledButton = styled.button<Omit<ButtonProps, 'icon'>>(
},
})
);

const IconWrapper = styled.div<{
isAnimating: boolean;
animation: IconButtonProps['onClickAnimation'];
}>(({ theme, isAnimating, animation }) => ({
width: 14,
height: 14,
animation: isAnimating && animation !== 'none' && `${theme.animation[animation]} 1000ms ease-out`,
}));
Loading