;
-
-export const Base = {
- args: { children: 'Button' },
-};
-
-export const Variants: Story = {
- args: {
- ...Base.args,
- },
- render: () => (
-
-
-
-
-
- ),
-};
-
-export const Active: Story = {
- args: {
- ...Base.args,
- },
- render: (args) => (
-
-
-
-
-
- ),
-};
-
-export const WithIcon: Story = {
- args: {
- ...Base.args,
- icon: 'FaceHappy',
- },
- render: ({ icon, children }) => (
-
-
-
-
-
- ),
-};
-
-export const Sizes: Story = {
- args: {
- ...Base.args,
- },
- render: () => (
-
-
-
-
- ),
-};
-
-export const Disabled: Story = {
- args: {
- ...Base.args,
- disabled: true,
- children: 'Disabled Button',
- },
-};
-
-export const WithHref: Story = {
- args: {
- ...Base.args,
- },
- render: () => (
-
-
-
-
- ),
-};
diff --git a/code/ui/components/src/new/Button/Button.tsx b/code/ui/components/src/new/Button/Button.tsx
deleted file mode 100644
index f36ea73379d4..000000000000
--- a/code/ui/components/src/new/Button/Button.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import React, { forwardRef } 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 {
- children: string;
- as?: T;
- size?: 'small' | 'medium';
- variant?: 'solid' | 'outline' | 'ghost';
- onClick?: () => void;
- disabled?: boolean;
- active?: boolean;
- icon?: Icons;
-}
-
-export const Button: {
- (
- props: ButtonProps & Omit, keyof ButtonProps>
- ): JSX.Element;
- displayName?: string;
-} = forwardRef(
- ({ as, children, icon, ...props }: ButtonProps, ref: React.Ref) => {
- const LocalIcon = Icon[icon];
-
- return (
-
- {icon && }
- {children}
-
- );
- }
-);
-
-Button.displayName = 'Button';
-
-const StyledButton = styled.button>(
- ({ theme, variant = 'solid', size = 'medium', disabled = false, active = false }) => ({
- border: 0,
- cursor: disabled ? 'not-allowed' : 'pointer',
- display: 'inline-flex',
- gap: '6px',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- padding: `${(() => {
- if (size === 'small') return '0 10px';
- if (size === 'medium') return '0 12px';
- return 0;
- })()}`,
- height: size === 'small' ? '28px' : '32px',
- position: 'relative',
- textAlign: 'center',
- textDecoration: 'none',
- transitionProperty: 'background, box-shadow',
- transitionDuration: '150ms',
- transitionTimingFunction: 'ease-out',
- verticalAlign: 'top',
- whiteSpace: 'nowrap',
- userSelect: 'none',
- opacity: disabled ? 0.5 : 1,
- margin: 0,
- fontSize: `${theme.typography.size.s1}px`,
- fontWeight: theme.typography.weight.bold,
- lineHeight: '1',
- background: `${(() => {
- if (variant === 'solid') return theme.color.secondary;
- if (variant === 'outline') return theme.button.background;
- if (variant === 'ghost' && active) return theme.background.hoverable;
- return 'transparent';
- })()}`,
- color: `${(() => {
- if (variant === 'solid') return theme.color.lightest;
- if (variant === 'outline') return theme.input.color;
- if (variant === 'ghost' && active) return theme.color.secondary;
- if (variant === 'ghost') return theme.color.mediumdark;
- return theme.input.color;
- })()}`,
- boxShadow: variant === 'outline' ? `${theme.button.border} 0 0 0 1px inset` : 'none',
- borderRadius: theme.input.borderRadius,
-
- '&:hover': {
- color: variant === 'ghost' ? theme.color.secondary : null,
- background: `${(() => {
- let bgColor = theme.color.secondary;
- if (variant === 'solid') bgColor = theme.color.secondary;
- if (variant === 'outline') bgColor = theme.button.background;
-
- if (variant === 'ghost') return transparentize(0.86, theme.color.secondary);
- return theme.base === 'light' ? darken(0.02, bgColor) : lighten(0.03, bgColor);
- })()}`,
- },
-
- '&:active': {
- color: variant === 'ghost' ? theme.color.secondary : null,
- background: `${(() => {
- let bgColor = theme.color.secondary;
- if (variant === 'solid') bgColor = theme.color.secondary;
- if (variant === 'outline') bgColor = theme.button.background;
-
- if (variant === 'ghost') return theme.background.hoverable;
- return theme.base === 'light' ? darken(0.02, bgColor) : lighten(0.03, bgColor);
- })()}`,
- },
-
- '&:focus': {
- boxShadow: `${rgba(theme.color.secondary, 1)} 0 0 0 1px inset`,
- outline: 'none',
- },
- })
-);
diff --git a/code/ui/components/src/new/Icon/Icon.mdx b/code/ui/components/src/new/Icon/Icon.mdx
deleted file mode 100644
index 2b2488a21e46..000000000000
--- a/code/ui/components/src/new/Icon/Icon.mdx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { IconGallery, IconItem } from '@storybook/blocks';
-import { Icon } from './Icon';
-
-
-
-# Icon
-
-An Icon is a piece of visual element, but we must ensure its accessibility while using it. It can have 2 purposes:
-
-- **Decorative only** β for example, it illustrates a label next to it. We must ensure that it is ignored by screen readers, by setting `aria-hidden` attribute (ex: ``)
-- **Non-decorative** β it means that it delivers information. For example, an icon as only child in a button. The meaning can be obvious visually, but it must have a proper text alternative via `aria-label` for screen readers. (ex: ``)
-
-
-
-{Icon.iconList.map((group) => (
-
-
-
-
{group.name}
-
-
- {group.icons.map((item) => {
- const MyIcon = Icon[item]
- return (
-
-
-
- )})}
-
-
-
-))}
\ No newline at end of file
diff --git a/code/ui/components/src/new/Icon/Icon.tsx b/code/ui/components/src/new/Icon/Icon.tsx
deleted file mode 100644
index 14219a539c9e..000000000000
--- a/code/ui/components/src/new/Icon/Icon.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export * as Icon from '@storybook/icons';
diff --git a/code/ui/components/src/new/IconButton/IconButton.stories.tsx b/code/ui/components/src/new/IconButton/IconButton.stories.tsx
deleted file mode 100644
index 4e239b9fb1b3..000000000000
--- a/code/ui/components/src/new/IconButton/IconButton.stories.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import React from 'react';
-import { IconButton } from './IconButton';
-
-const meta: Meta = {
- title: 'IconButton',
- component: IconButton,
- tags: ['autodocs'],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base = {
- args: { icon: 'FaceHappy' },
-};
-
-export const Types: Story = {
- render: () => (
-
-
-
-
-
- ),
-};
-
-export const Active: Story = {
- render: () => (
-
-
-
-
-
- ),
-};
-
-export const Sizes: Story = {
- render: () => (
-
-
-
-
- ),
-};
-
-export const Disabled: Story = {
- args: {
- ...Base.args,
- icon: 'FaceHappy',
- disabled: true,
- },
-};
-
-export const Animated: Story = {
- args: {
- ...Base.args,
- icon: 'FaceHappy',
- },
- render: () => (
-
-
-
-
-
- ),
-};
-
-export const WithHref: Story = {
- render: () => (
-
- console.log('Hello')} />
-
-
- ),
-};
diff --git a/code/ui/components/src/new/IconButton/IconButton.tsx b/code/ui/components/src/new/IconButton/IconButton.tsx
deleted file mode 100644
index 18385bf3609d..000000000000
--- a/code/ui/components/src/new/IconButton/IconButton.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-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 IconButtonProps {
- icon: Icons;
- as?: T;
- size?: 'small' | 'medium';
- variant?: 'solid' | 'outline' | 'ghost';
- onClick?: (event: SyntheticEvent) => void;
- disabled?: boolean;
- active?: boolean;
- onClickAnimation?: 'none' | 'rotate360' | 'glow' | 'jiggle';
-}
-
-export const IconButton: {
- (
- props: IconButtonProps & Omit, keyof IconButtonProps>
- ): JSX.Element;
- displayName?: string;
-} = forwardRef(
- (
- { as, icon = 'FaceHappy', onClickAnimation = 'none', onClick, ...props }: IconButtonProps,
- ref: React.Ref
- ) => {
- 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 (
-
-
-
-
-
- );
- }
-);
-
-IconButton.displayName = 'IconButton';
-
-const StyledButton = styled.button>(
- ({ theme, variant = 'solid', size = 'medium', disabled = false, active = false }) => ({
- border: 0,
- cursor: disabled ? 'not-allowed' : 'pointer',
- display: 'inline-flex',
- gap: '6px',
- alignItems: 'center',
- justifyContent: 'center',
- overflow: 'hidden',
- width: `${(() => {
- if (size === 'small') return '28px';
- if (size === 'medium') return '32px';
- return 'auto';
- })()}`,
- height: size === 'small' ? '28px' : '32px',
- position: 'relative',
- textAlign: 'center',
- textDecoration: 'none',
- transitionProperty: 'background, box-shadow',
- transitionDuration: '150ms',
- transitionTimingFunction: 'ease-out',
- verticalAlign: 'top',
- whiteSpace: 'nowrap',
- userSelect: 'none',
- opacity: disabled ? 0.5 : 1,
- margin: 0,
- fontSize: `${theme.typography.size.s1}px`,
- fontWeight: theme.typography.weight.bold,
- lineHeight: '1',
- background: `${(() => {
- if (variant === 'solid') return theme.color.secondary;
- if (variant === 'outline') return theme.button.background;
- if (variant === 'ghost' && active) return theme.background.hoverable;
- return 'transparent';
- })()}`,
- color: `${(() => {
- if (variant === 'solid') return theme.color.lightest;
- if (variant === 'outline') return theme.input.color;
- if (variant === 'ghost' && active) return theme.color.secondary;
- if (variant === 'ghost') return theme.color.mediumdark;
- return theme.input.color;
- })()}`,
- boxShadow: variant === 'outline' ? `${theme.button.border} 0 0 0 1px inset` : 'none',
- borderRadius: theme.input.borderRadius,
-
- '&:hover': {
- color: variant === 'ghost' ? theme.color.secondary : null,
- background: `${(() => {
- let bgColor = theme.color.secondary;
- if (variant === 'solid') bgColor = theme.color.secondary;
- if (variant === 'outline') bgColor = theme.button.background;
-
- if (variant === 'ghost') return transparentize(0.86, theme.color.secondary);
- return theme.base === 'light' ? darken(0.02, bgColor) : lighten(0.03, bgColor);
- })()}`,
- },
-
- '&:active': {
- color: variant === 'ghost' ? theme.color.secondary : null,
- background: `${(() => {
- let bgColor = theme.color.secondary;
- if (variant === 'solid') bgColor = theme.color.secondary;
- if (variant === 'outline') bgColor = theme.button.background;
-
- if (variant === 'ghost') return theme.background.hoverable;
- return theme.base === 'light' ? darken(0.02, bgColor) : lighten(0.03, bgColor);
- })()}`,
- },
-
- '&:focus': {
- boxShadow: `${rgba(theme.color.secondary, 1)} 0 0 0 1px inset`,
- outline: 'none',
- },
- })
-);
-
-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`,
-}));
diff --git a/code/ui/components/src/new/Input/Input.stories.tsx b/code/ui/components/src/new/Input/Input.stories.tsx
deleted file mode 100644
index 8130f39aa72d..000000000000
--- a/code/ui/components/src/new/Input/Input.stories.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import { Input } from './Input';
-
-const meta: Meta = {
- title: 'Input',
- component: Input,
- tags: ['autodocs'],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base: Story = {
- args: {
- placeholder: 'Hello World',
- },
-};
-
-export const Filled: Story = {
- args: {
- ...Base.args,
- value: 'Hello World',
- },
-};
-
-export const Disabled: Story = {
- args: {
- ...Base.args,
- disabled: true,
- },
-};
diff --git a/code/ui/components/src/new/Input/Input.tsx b/code/ui/components/src/new/Input/Input.tsx
deleted file mode 100644
index da10006c960e..000000000000
--- a/code/ui/components/src/new/Input/Input.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React, { forwardRef } from 'react';
-import { styled } from '@storybook/theming';
-
-interface InputProps {
- disabled?: boolean;
- placeholder?: string;
- value?: string;
-}
-
-export const Input = forwardRef(({ ...props }, ref) => {
- return ;
-});
-
-Input.displayName = 'Input';
-
-const StyledInput = styled.input(({ theme }) => ({
- // resets
- appearance: 'none',
- border: '0 none',
- display: 'block',
- margin: ' 0',
- position: 'relative',
-
- // styles
- width: '100%',
- height: '32px',
- transition: 'box-shadow 200ms ease-out, opacity 200ms ease-out',
- color: theme.input.color,
- background: theme.input.background,
- boxShadow: `${theme.input.border} 0 0 0 1px inset`,
- borderRadius: theme.input.borderRadius,
- fontSize: theme.typography.size.s2 - 1,
- padding: '6px 10px',
- boxSizing: 'border-box',
- lineHeight: '20px',
-
- '&:focus': {
- boxShadow: `${theme.color.secondary} 0 0 0 1px inset`,
- outline: 'none',
- },
-
- '&[disabled]': {
- cursor: 'not-allowed',
- opacity: 0.5,
- },
-
- '&:-webkit-autofill': {
- WebkitBoxShadow: `0 0 0 3em ${theme.color.lightest} inset`,
- },
-
- '&::placeholder': {
- color: theme.textMutedColor,
- opacity: 1,
- },
-}));
diff --git a/code/ui/components/src/new/Link/Link.stories.tsx b/code/ui/components/src/new/Link/Link.stories.tsx
deleted file mode 100644
index 0fee3e095b8a..000000000000
--- a/code/ui/components/src/new/Link/Link.stories.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import React from 'react';
-import { Link } from './Link';
-
-const meta: Meta = {
- title: 'Link',
- component: Link,
- tags: ['autodocs'],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base = {
- args: { children: 'Link' },
-};
-
-export const Variants: Story = {
- render: () => (
-
-
- Primary
-
-
- Secondary
-
-
- ),
-};
-
-export const Underline: Story = {
- render: () => (
-
-
- Primary
-
-
- Secondary
-
-
- Secondary
-
-
- Secondary
-
-
- ),
-};
-
-export const Weight: Story = {
- render: () => (
-
-
- Primary
-
-
- Secondary
-
-
- Secondary
-
-
- Secondary
-
-
- ),
-};
-
-export const WithIcon: Story = {
- render: () => (
-
-
- Primary
-
-
- Secondary
-
-
- ),
-};
-
-export const WithArrow: Story = {
- render: () => (
-
-
-
- Primary
-
-
- Secondary
-
-
-
-
- Primary
-
-
- Secondary
-
-
-
- ),
-};
diff --git a/code/ui/components/src/new/Link/Link.tsx b/code/ui/components/src/new/Link/Link.tsx
deleted file mode 100644
index 3422ac6a7f31..000000000000
--- a/code/ui/components/src/new/Link/Link.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import type { MouseEvent } from 'react';
-import React, { forwardRef } from 'react';
-import { styled } from '@storybook/theming';
-import type { Icons } from '@storybook/icons';
-import { Icon } from '../Icon/Icon';
-import type { PropsOf } from '../utils/types';
-
-export interface LinkProps {
- as?: T;
- children: string;
- variant?: 'primary' | 'secondary';
- weight?: 'regular' | 'bold';
- underline?: 'hover' | 'always';
- icon?: Icons;
- onClick?: (e: MouseEvent) => void;
- withArrow?: boolean;
-}
-
-export const Link: {
- (
- props: LinkProps & Omit, keyof LinkProps>
- ): JSX.Element;
- displayName?: string;
-} = forwardRef(
- ({ children, icon, withArrow, ...props }: LinkProps, ref: React.Ref) => {
- const LocalIcon = Icon[icon];
- return (
-
-
- {icon && }
- {children}
-
- {withArrow && }
-
- );
- }
-);
-
-Link.displayName = 'Link';
-
-const StyledLink = styled.a>(
- ({ theme, variant = 'primary', underline = 'hover', weight = 'regular' }) => ({
- display: 'inline-flex',
- gap: 4,
- alignItems: 'center',
- transition: 'all 150ms ease-out',
- textDecoration: 'none',
- lineHeight: 1,
- color: `${(() => {
- if (variant === 'primary') return theme.color.secondary;
- if (variant === 'secondary') return theme.color.defaultText;
- return theme.color.secondary;
- })()}`,
- fontWeight: `${(() => {
- if (weight === 'regular') return theme.typography.weight.regular;
- if (weight === 'bold') return theme.typography.weight.bold;
- return theme.typography.weight.bold;
- })()}`,
- textDecorationLine: `${underline === 'always' ? 'underline' : 'none'}`,
- textDecorationStyle: 'solid',
- textDecorationThickness: '1px',
- textUnderlineOffset: '2px',
-
- '&:hover, &:focus': {
- cursor: 'pointer',
- textDecorationLine: 'underline',
- },
- })
-);
-
-const StyledLeft = styled.span(({ theme }) => ({
- display: 'inline-flex',
- gap: 6,
- alignItems: 'center',
- fontSize: theme.typography.size.s2 - 1,
-}));
diff --git a/code/ui/components/src/new/Select/Select.stories.tsx b/code/ui/components/src/new/Select/Select.stories.tsx
deleted file mode 100644
index 452fe113fba4..000000000000
--- a/code/ui/components/src/new/Select/Select.stories.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import React from 'react';
-
-import { Select } from './Select';
-
-const meta: Meta = {
- title: 'Select',
- component: Select.Root,
- tags: ['autodocs'],
- parameters: {
- layout: 'centered',
- },
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base: Story = {
- args: {},
- render: (_, { args }) => (
-
-
-
-
-
-
- Avocado
- Banana
- Bilberry
- Blackberry
- Blackcurrant
- Black sapote
- Blueberry
- Boysenberry
- Breadfruit
- Cacao
- Cactus pear
- Canistel
- Catmon
- Cempedak
- Cherimoya
- Cherry
- Chico fruit
- Cloudberry
- Coco de mer
- Coconut
- Crab apple
- Cranberry
- Currant
- Damson
- Date
- Dragonfruit
- Durian
- Elderberry
- Feijoa
- Fig
- Finger Lime
- Gac Fruit
- Goji berry
- Gooseberry
- Grape
- Raisin
- Grapefruit
- Grewia asiatica
- Guava
- Guyabano
- Hala Fruit
- Honeyberry
- Huckleberry
- Jabuticaba
- Jackfruit
- Jambul
- Japanese plum
- Jostaberry
- Jujube
- Juniper berry
- Kaffir Lime
- Kiwano
- Kiwifruit
- Kumquat
- Lanzones
- Lemon
- Lime
- Loganberry
- Longan
- Loquat
-
-
-
- ),
-};
diff --git a/code/ui/components/src/new/Select/Select.tsx b/code/ui/components/src/new/Select/Select.tsx
deleted file mode 100644
index 0ae606877434..000000000000
--- a/code/ui/components/src/new/Select/Select.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import * as React from 'react';
-import * as SelectPrimitive from '@radix-ui/react-select';
-import { styled } from '@storybook/theming';
-import { ExpandAlt } from './icons/ExpandAlt';
-import { Arrowup } from './icons/Arrowup';
-import { Arrowdown } from './icons/Arrowdown';
-import { Check } from './icons/Check';
-
-const SelectTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
- {children}
-
-
-
-
-));
-SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
-
-const SelectContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
-
-
-
- {children}
-
-
-
-
-
-));
-SelectContent.displayName = SelectPrimitive.Content.displayName;
-
-const SelectLabel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => );
-SelectLabel.displayName = SelectPrimitive.Label.displayName;
-
-const SelectItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
-
-
- {children}
-
-));
-SelectItem.displayName = SelectPrimitive.Item.displayName;
-
-const SelectSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => );
-SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
-
-export const Select = {
- Root: SelectPrimitive.Root,
- Group: SelectPrimitive.Group,
- Value: SelectPrimitive.Value,
- Trigger: SelectTrigger,
- Content: SelectContent,
- Label: SelectLabel,
- Item: SelectItem,
- Separator: SelectSeparator,
-};
-
-const StyledTrigger = styled(SelectPrimitive.Trigger)(({ theme }) => ({
- all: 'unset',
- display: 'flex',
- width: '100%',
- height: '32px',
- alignItems: 'center',
- justifyContent: 'space-between',
- transition: 'box-shadow 200ms ease-out, opacity 200ms ease-out',
- color: theme.input.color,
- background: theme.input.background,
- boxShadow: `${theme.input.border} 0 0 0 1px inset`,
- borderRadius: theme.input.borderRadius,
- fontSize: theme.typography.size.s2 - 1,
- padding: '6px 10px',
- boxSizing: 'border-box',
- lineHeight: '20px',
-
- '&:focus': {
- boxShadow: `${theme.color.secondary} 0 0 0 1px inset`,
- outline: 'none',
- },
-
- '&[disabled]': {
- cursor: 'not-allowed',
- opacity: 0.5,
- },
-
- '&[data-placeholder]': {
- color: theme.textMutedColor,
- },
-
- '&:-webkit-autofill': {
- WebkitBoxShadow: `0 0 0 3em ${theme.color.lightest} inset`,
- },
-}));
-
-const StyledContent = styled(SelectPrimitive.Content)(({ theme }) => ({
- boxSizing: 'border-box',
- overflow: 'hidden',
- backgroundColor: theme.input.background,
- borderRadius: '6px',
- border: theme.base === 'dark' ? `1px solid ${theme.input.border}` : '1px solid transparent',
- width: '100%',
- boxShadow:
- '0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)',
-}));
-
-const StyledViewport = styled(SelectPrimitive.Viewport)(() => ({
- boxSizing: 'border-box',
- width: '100%',
- padding: '5px',
-}));
-
-const StyledScrollUpButton = styled(SelectPrimitive.ScrollUpButton)(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- height: '25px',
- backgroundColor: theme.input.background,
- color: theme.input.color,
- cursor: 'default',
-}));
-
-const StyledScrollDownButton = styled(SelectPrimitive.ScrollDownButton)(({ theme }) => ({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- height: '25px',
- backgroundColor: theme.input.background,
- color: theme.input.color,
- cursor: 'default',
-}));
-
-const StyledItem = styled(SelectPrimitive.Item)(({ theme }) => ({
- fontSize: '13px',
- lineHeight: 1,
- color: theme.input.color,
- borderRadius: '3px',
- display: 'flex',
- alignItems: 'center',
- height: '25px',
- padding: '0 35px 0 25px',
- position: 'relative',
- userSelect: 'none',
-
- '&[data-disabled]': {
- color: 'red',
- pointerEvents: 'none',
- },
-
- '&[data-highlighted]': {
- outline: 'none',
- backgroundColor: theme.barSelectedColor,
- color: theme.barBg,
- },
-}));
-
-const StyledItemIndicator = styled(SelectPrimitive.ItemIndicator)(() => ({
- position: 'absolute',
- left: 0,
- width: '25px',
- display: 'inline-flex',
- alignItems: 'center',
- justifyContent: 'center',
-}));
diff --git a/code/ui/components/src/new/Select/SelectItem.tsx b/code/ui/components/src/new/Select/SelectItem.tsx
deleted file mode 100644
index f60f084cd3ae..000000000000
--- a/code/ui/components/src/new/Select/SelectItem.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as RadixSelect from '@radix-ui/react-select';
-import React, { forwardRef } from 'react';
-import { styled } from '@storybook/theming';
-import { Icon } from '@storybook/components/experimental';
-
-interface SelectItemProps {
- children: React.ReactNode;
- value: string;
-}
-
-export const SelectItem = forwardRef(
- ({ children, ...props }, forwardedRef) => {
- return (
-
- {children}
-
-
-
-
- );
- }
-);
-
-SelectItem.displayName = 'SelectItem';
-
-const StyledItem = styled(RadixSelect.Item)(() => ({
- fontSize: '13px',
- lineHeight: 1,
- color: 'blue',
- borderRadius: '3px',
- display: 'flex',
- alignItems: 'center',
- height: '25px',
- padding: '0 35px 0 25px',
- position: 'relative',
- userSelect: 'none',
-
- '&[data-disabled]': {
- color: 'red',
- pointerEvents: 'none',
- },
-
- '&[data-highlighted]': {
- outline: 'none',
- backgroundColor: 'green',
- color: 'white',
- },
-}));
-
-const StyledItemIndicator = styled(RadixSelect.ItemIndicator)(() => ({
- position: 'absolute',
- left: 0,
- width: '25px',
- display: 'inline-flex',
- alignItems: 'center',
- justifyContent: 'center',
-}));
diff --git a/code/ui/components/src/new/Select/icons/Arrowdown.tsx b/code/ui/components/src/new/Select/icons/Arrowdown.tsx
deleted file mode 100644
index d8437ca5d122..000000000000
--- a/code/ui/components/src/new/Select/icons/Arrowdown.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-import type { IconProps } from './types';
-import { IconWrapper } from './IconWrapper';
-
-export const Arrowdown = (allProps: IconProps) => {
- const { svgProps: props, ...restProps } = allProps;
- return (
-
-
-
- }
- {...restProps}
- />
- );
-};
-
-export default Arrowdown;
diff --git a/code/ui/components/src/new/Select/icons/Arrowup.tsx b/code/ui/components/src/new/Select/icons/Arrowup.tsx
deleted file mode 100644
index 24f722e410a6..000000000000
--- a/code/ui/components/src/new/Select/icons/Arrowup.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-import type { IconProps } from './types';
-import { IconWrapper } from './IconWrapper';
-
-export const Arrowup = (allProps: IconProps) => {
- const { svgProps: props, ...restProps } = allProps;
- return (
-
-
-
- }
- {...restProps}
- />
- );
-};
-
-export default Arrowup;
diff --git a/code/ui/components/src/new/Select/icons/Check.tsx b/code/ui/components/src/new/Select/icons/Check.tsx
deleted file mode 100644
index 4d5beb1531a3..000000000000
--- a/code/ui/components/src/new/Select/icons/Check.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-import type { IconProps } from './types';
-import { IconWrapper } from './IconWrapper';
-
-export const Check = (allProps: IconProps) => {
- const { svgProps: props, ...restProps } = allProps;
- return (
-
-
-
- }
- {...restProps}
- />
- );
-};
-
-export default Check;
diff --git a/code/ui/components/src/new/Select/icons/ExpandAlt.tsx b/code/ui/components/src/new/Select/icons/ExpandAlt.tsx
deleted file mode 100644
index 7f0626adcbea..000000000000
--- a/code/ui/components/src/new/Select/icons/ExpandAlt.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-import type { IconProps } from './types';
-import { IconWrapper } from './IconWrapper';
-
-export const ExpandAlt = (allProps: IconProps) => {
- const { svgProps: props, ...restProps } = allProps;
- return (
-
-
-
- }
- {...restProps}
- />
- );
-};
-
-export default ExpandAlt;
diff --git a/code/ui/components/src/new/Select/icons/IconWrapper.tsx b/code/ui/components/src/new/Select/icons/IconWrapper.tsx
deleted file mode 100644
index a4c60d6709f8..000000000000
--- a/code/ui/components/src/new/Select/icons/IconWrapper.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-import type { IconProps } from './types';
-
-export const IconWrapper: React.FC<{ icon: React.ReactNode } & IconProps> = ({
- icon,
- color: colorProp,
- size: sizeProp,
- ...restProps
-}) => {
- const color = colorProp || 'currentColor';
- const size = sizeProp || '14px';
-
- return (
-
- {icon}
-
- );
-};
diff --git a/code/ui/components/src/new/Select/icons/types.ts b/code/ui/components/src/new/Select/icons/types.ts
deleted file mode 100644
index 142493c5ee59..000000000000
--- a/code/ui/components/src/new/Select/icons/types.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import type React from 'react';
-
-export type IconProps = {
- /** Set icon fill color from design system */
- color?: string;
- /** Set width and height of icon in pixels */
- size?: number;
- /** Props to pass directly to svg element */
- svgProps?: React.SVGProps;
-} & Omit, 'color' | 'size'>;
diff --git a/code/ui/components/src/new/Textarea/Textarea.stories.tsx b/code/ui/components/src/new/Textarea/Textarea.stories.tsx
deleted file mode 100644
index b23516d8f2bd..000000000000
--- a/code/ui/components/src/new/Textarea/Textarea.stories.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import { Textarea } from './Textarea';
-
-const meta: Meta = {
- title: 'Textarea',
- component: Textarea,
- tags: ['autodocs'],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base: Story = {
- args: {
- placeholder: 'Hello World',
- },
-};
-
-export const Filled: Story = {
- args: {
- ...Base.args,
- value:
- 'Self ocean ultimate reason faith virtues evil eternal-return moral strong superiority. Society will christian god holiest evil virtues ultimate salvation aversion victorious strong eternal-return. Ascetic pious hope selfish battle pinnacle revaluation passion ocean passion chaos reason intentions. Hope hatred pious superiority ascetic chaos ultimate mountains ideal. Superiority good abstract hatred holiest passion ultimate evil inexpedient joy. Salvation war salvation ideal decieve good law ascetic hatred transvaluation horror good. Zarathustra aversion pious truth burying evil inexpedient spirit virtues virtues hope salvation transvaluation. Enlightenment chaos ascetic salvation god holiest play marvelous oneself ocean. Enlightenment faithful dead truth insofar fearful madness love.Inexpedient war hatred superiority disgust justice superiority. Chaos justice contradict christian decieve god. Revaluation suicide hope enlightenment decrepit truth hatred insofar gains sexuality merciful ocean revaluation depths. Revaluation ocean superiority endless of evil horror. Ultimate salvation joy good good endless will horror aversion superiority depths. Evil hatred ideal pious joy reason.',
- },
-};
-
-export const Disabled: Story = {
- args: {
- ...Base.args,
- disabled: true,
- },
-};
diff --git a/code/ui/components/src/new/Textarea/Textarea.tsx b/code/ui/components/src/new/Textarea/Textarea.tsx
deleted file mode 100644
index 15a156bf8b1f..000000000000
--- a/code/ui/components/src/new/Textarea/Textarea.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import React, { forwardRef } from 'react';
-import { styled } from '@storybook/theming';
-import TextareaAutoResize from 'react-textarea-autosize';
-
-interface TextareaProps {
- disabled?: boolean;
- placeholder?: string;
- value?: string;
-}
-
-export const Textarea = forwardRef(({ ...props }, ref) => {
- return ;
-});
-
-Textarea.displayName = 'Textarea';
-
-const StyledTextarea = styled(TextareaAutoResize)(({ theme }) => ({
- // resets
- appearance: 'none',
- border: '0 none',
- margin: ' 0',
- position: 'relative',
-
- // styles
- display: 'flex',
- alignItems: 'center',
- width: '100%',
- height: '32px',
- transition: 'box-shadow 200ms ease-out, opacity 200ms ease-out',
- color: theme.input.color,
- background: theme.input.background,
- boxShadow: `${theme.input.border} 0 0 0 1px inset`,
- borderRadius: theme.input.borderRadius,
- fontSize: theme.typography.size.s2 - 1,
- padding: '6px 10px',
- boxSizing: 'border-box',
- minHeight: 32,
- lineHeight: '20px',
-
- '&:focus': {
- boxShadow: `${theme.color.secondary} 0 0 0 1px inset`,
- outline: 'none',
- },
-
- '&[disabled]': {
- cursor: 'not-allowed',
- opacity: 0.5,
- },
-
- '&:-webkit-autofill': {
- WebkitBoxShadow: `0 0 0 3em ${theme.color.lightest} inset`,
- },
-
- '&::placeholder': {
- color: theme.textMutedColor,
- opacity: 1,
- },
-}));
diff --git a/code/ui/components/src/new/Toolbar/Toolbar.stories.tsx b/code/ui/components/src/new/Toolbar/Toolbar.stories.tsx
deleted file mode 100644
index d50a8f2bab23..000000000000
--- a/code/ui/components/src/new/Toolbar/Toolbar.stories.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import React from 'react';
-
-import { Toolbar } from './Toolbar';
-import { IconButton } from '../IconButton/IconButton';
-import { Button } from '../Button/Button';
-
-const meta: Meta = {
- title: 'Toolbar',
- component: Toolbar.Root,
- tags: ['autodocs'],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Base: Story = {
- args: {
- hasPadding: true,
- borderTop: false,
- borderBottom: true,
- },
- render: (_, { args }) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ),
-};
-
-export const NoMargin: Story = {
- args: {
- ...Base.args,
- hasPadding: false,
- },
- render: Base.render,
-};
-
-export const BorderTop: Story = {
- args: {
- ...Base.args,
- borderTop: true,
- borderBottom: false,
- },
- render: Base.render,
-};
-
-export const BorderBottom: Story = {
- args: {
- ...Base.args,
- borderTop: false,
- borderBottom: true,
- },
- render: Base.render,
-};
-
-export const BorderTopBottom: Story = {
- args: {
- ...Base.args,
- borderTop: true,
- borderBottom: true,
- },
- render: Base.render,
-};
diff --git a/code/ui/components/src/new/Toolbar/Toolbar.tsx b/code/ui/components/src/new/Toolbar/Toolbar.tsx
deleted file mode 100644
index 827011ba06fa..000000000000
--- a/code/ui/components/src/new/Toolbar/Toolbar.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import type { ComponentPropsWithoutRef, ElementRef } from 'react';
-import React, { forwardRef } from 'react';
-import * as ToolbarPrimitive from '@radix-ui/react-toolbar';
-import { styled } from '@storybook/theming';
-
-interface RootProps extends ComponentPropsWithoutRef {
- hasPadding?: boolean;
- borderBottom?: boolean;
- borderTop?: boolean;
-}
-
-const ToolbarRoot = forwardRef, RootProps>(
- ({ className, children, ...props }, ref) => (
-
- {children}
-
- )
-);
-ToolbarRoot.displayName = ToolbarPrimitive.Root.displayName;
-
-const ToolbarSeparator = React.forwardRef<
- ElementRef,
- ComponentPropsWithoutRef
->(({ className, ...props }, ref) => );
-ToolbarSeparator.displayName = ToolbarPrimitive.Separator.displayName;
-
-const ToolbarToggleGroup = React.forwardRef<
- ElementRef,
- ToolbarPrimitive.ToolbarToggleGroupSingleProps | ToolbarPrimitive.ToolbarToggleGroupMultipleProps
->(({ className, ...props }, ref) => );
-ToolbarToggleGroup.displayName = ToolbarPrimitive.ToggleGroup.displayName;
-
-const ToolbarToggleItem = React.forwardRef<
- ElementRef,
- ComponentPropsWithoutRef
->(({ className, ...props }, ref) => );
-ToolbarToggleItem.displayName = ToolbarPrimitive.ToggleItem.displayName;
-
-const StyledRoot = styled(ToolbarPrimitive.Root)(
- ({ theme, hasPadding = true, borderBottom = true, borderTop = false }) => ({
- display: 'flex',
- padding: hasPadding ? '0 10px' : 0,
- justifyContent: 'space-between',
- height: 40,
- borderBottom: borderBottom ? `1px solid ${theme.appBorderColor}` : 'none',
- borderTop: borderTop ? `1px solid ${theme.appBorderColor}` : 'none',
- boxSizing: 'border-box',
- backgroundColor: theme.barBg,
- })
-);
-
-const StyledSeparator = styled(ToolbarPrimitive.Separator)(({ theme }) => ({
- width: 1,
- height: 20,
- backgroundColor: theme.appBorderColor,
-}));
-
-const StyledToggleGroup = styled(ToolbarPrimitive.ToggleGroup)({
- display: 'flex',
- gap: 5,
- alignItems: 'center',
-});
-
-const Left = styled.div({
- display: 'flex',
- gap: 5,
- alignItems: 'center',
-});
-
-const Right = styled.div({
- display: 'flex',
- gap: 5,
- alignItems: 'center',
-});
-
-export const Toolbar = {
- Root: ToolbarRoot,
- Left,
- Right,
- ToogleGroup: ToolbarToggleGroup,
- ToggleItem: ToolbarToggleItem,
- Separator: ToolbarSeparator,
-};
diff --git a/code/ui/components/src/new/utils/types.ts b/code/ui/components/src/new/utils/types.ts
deleted file mode 100644
index f5713d0b3479..000000000000
--- a/code/ui/components/src/new/utils/types.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import type React from 'react';
-
-export type PropsOf> =
- JSX.LibraryManagedAttributes>;
diff --git a/code/ui/manager/package.json b/code/ui/manager/package.json
index ee84f2036237..96191e437764 100644
--- a/code/ui/manager/package.json
+++ b/code/ui/manager/package.json
@@ -43,7 +43,8 @@
"static/**/*",
"README.md",
"*.js",
- "*.d.ts"
+ "*.d.ts",
+ "!src/**/*"
],
"scripts": {
"check": "../../../scripts/prepare/check.ts",
diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx
index ddee4eb97170..b2c90a6a0403 100644
--- a/code/ui/manager/src/components/notifications/NotificationItem.tsx
+++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx
@@ -4,7 +4,6 @@ import { type State } from '@storybook/manager-api';
import { Link } from '@storybook/router';
import { styled, useTheme } from '@storybook/theming';
import { Icons, IconButton, type IconsProps } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
import { transparentize } from 'polished';
const Notification = styled.div(({ theme }) => ({
@@ -116,7 +115,7 @@ const DismissNotificationItem: FC<{
onDismiss();
}}
>
-
+
);
diff --git a/code/ui/manager/src/components/panel/panel.stories.tsx b/code/ui/manager/src/components/panel/panel.stories.tsx
index 6fe0f00f833e..f3f523f29c65 100644
--- a/code/ui/manager/src/components/panel/panel.stories.tsx
+++ b/code/ui/manager/src/components/panel/panel.stories.tsx
@@ -1,7 +1,6 @@
import React, { useCallback, useRef, useState } from 'react';
import { action } from '@storybook/addon-actions';
-import { Badge, Spaced } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Badge, Icons, Spaced } from '@storybook/components';
import { Addon_TypesEnum } from '@storybook/types';
import Panel from './panel';
import { panels, shortcuts } from '../layout/app.mockdata';
@@ -57,7 +56,7 @@ export const JSXTitles = () => {
),
diff --git a/code/ui/manager/src/components/panel/panel.tsx b/code/ui/manager/src/components/panel/panel.tsx
index 2717af21525f..6abcce50f0e9 100644
--- a/code/ui/manager/src/components/panel/panel.tsx
+++ b/code/ui/manager/src/components/panel/panel.tsx
@@ -1,6 +1,5 @@
import React, { Component, Fragment } from 'react';
-import { Tabs, IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Tabs, Icons, IconButton } from '@storybook/components';
import type { State } from '@storybook/manager-api';
import { shortcutToHumanString } from '@storybook/manager-api';
import type { Addon_BaseType } from '@storybook/types';
@@ -67,14 +66,14 @@ const AddonPanel = React.memo<{
shortcuts.panelPosition
)}]`}
>
- {panelPosition === 'bottom' ? : }
+
-
+
) : undefined
diff --git a/code/ui/manager/src/components/preview/toolbar.tsx b/code/ui/manager/src/components/preview/toolbar.tsx
index 3a171b657db4..b82e5cb2eb38 100644
--- a/code/ui/manager/src/components/preview/toolbar.tsx
+++ b/code/ui/manager/src/components/preview/toolbar.tsx
@@ -3,8 +3,7 @@ import React, { Fragment, useMemo } from 'react';
import { styled } from '@storybook/theming';
-import { FlexBar, IconButton, Separator, TabButton, TabBar } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { FlexBar, IconButton, Icons, Separator, TabButton, TabBar } from '@storybook/components';
import {
shortcutToHumanString,
Consumer,
@@ -72,7 +71,7 @@ export const fullScreenTool: Addon_BaseType = {
onClick={toggle as any}
title={`${value ? 'Exit full screen' : 'Go full screen'} [${shortcut}]`}
>
- {value ? : }
+
)
}
diff --git a/code/ui/manager/src/components/preview/tools/addons.tsx b/code/ui/manager/src/components/preview/tools/addons.tsx
index 898e24dd06d6..53fe821ae4af 100644
--- a/code/ui/manager/src/components/preview/tools/addons.tsx
+++ b/code/ui/manager/src/components/preview/tools/addons.tsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { IconButton, Icons } from '@storybook/components';
import { Consumer, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import type { Addon_BaseType } from '@storybook/types';
@@ -24,7 +23,7 @@ export const addonsTool: Addon_BaseType = {
!isVisible && (
<>
- {panelPosition === 'bottom' ? : }
+
>
)
diff --git a/code/ui/manager/src/components/preview/tools/copy.tsx b/code/ui/manager/src/components/preview/tools/copy.tsx
index 3e18a1d6d603..0b0084aae857 100644
--- a/code/ui/manager/src/components/preview/tools/copy.tsx
+++ b/code/ui/manager/src/components/preview/tools/copy.tsx
@@ -1,8 +1,7 @@
import { global } from '@storybook/global';
import React from 'react';
import copy from 'copy-to-clipboard';
-import { getStoryHref, IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { getStoryHref, IconButton, Icons } from '@storybook/components';
import { Consumer, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import type { Addon_BaseType } from '@storybook/types';
@@ -38,7 +37,7 @@ export const copyTool: Addon_BaseType = {
onClick={() => copy(getStoryHref(baseUrl, storyId, queryParams))}
title="Copy canvas link"
>
-
+
) : null
}
diff --git a/code/ui/manager/src/components/preview/tools/eject.tsx b/code/ui/manager/src/components/preview/tools/eject.tsx
index dd7f3bb3f695..65688038b859 100644
--- a/code/ui/manager/src/components/preview/tools/eject.tsx
+++ b/code/ui/manager/src/components/preview/tools/eject.tsx
@@ -1,7 +1,6 @@
import { global } from '@storybook/global';
import React from 'react';
-import { getStoryHref, IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { getStoryHref, IconButton, Icons } from '@storybook/components';
import { Consumer, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import type { Addon_BaseType } from '@storybook/types';
@@ -35,7 +34,7 @@ export const ejectTool: Addon_BaseType = {
target="_blank"
title="Open canvas in new tab"
>
-
+
) : null
}
diff --git a/code/ui/manager/src/components/preview/tools/menu.tsx b/code/ui/manager/src/components/preview/tools/menu.tsx
index 459c4e72a475..8512e9e16abc 100644
--- a/code/ui/manager/src/components/preview/tools/menu.tsx
+++ b/code/ui/manager/src/components/preview/tools/menu.tsx
@@ -1,6 +1,5 @@
import React from 'react';
-import { IconButton, Separator } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { IconButton, Icons, Separator } from '@storybook/components';
import { Consumer, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import type { Addon_BaseType } from '@storybook/types';
@@ -23,7 +22,7 @@ export const menuTool: Addon_BaseType = {
!isVisible && (
<>
-
+
>
diff --git a/code/ui/manager/src/components/preview/tools/remount.tsx b/code/ui/manager/src/components/preview/tools/remount.tsx
index 435b059e8c70..6bf4c1f7553e 100644
--- a/code/ui/manager/src/components/preview/tools/remount.tsx
+++ b/code/ui/manager/src/components/preview/tools/remount.tsx
@@ -1,7 +1,6 @@
import type { ComponentProps } from 'react';
import React, { useState } from 'react';
-import { IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { IconButton, Icons } from '@storybook/components';
import { Consumer, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import { styled } from '@storybook/theming';
@@ -57,7 +56,7 @@ export const remountTool: Addon_BaseType = {
animating={isAnimating}
disabled={!storyId}
>
-
+
);
}}
diff --git a/code/ui/manager/src/components/preview/tools/zoom.tsx b/code/ui/manager/src/components/preview/tools/zoom.tsx
index be98293fd264..84e0f72bafae 100644
--- a/code/ui/manager/src/components/preview/tools/zoom.tsx
+++ b/code/ui/manager/src/components/preview/tools/zoom.tsx
@@ -1,8 +1,7 @@
import type { SyntheticEvent, MouseEventHandler } from 'react';
import React, { Component, useCallback } from 'react';
-import { IconButton, Separator } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Icons, IconButton, Separator } from '@storybook/components';
import type { Addon_BaseType } from '@storybook/types';
import { types } from '@storybook/manager-api';
@@ -39,13 +38,13 @@ const Zoom = React.memo<{
return (
<>
-
+
-
+
-
+
>
);
diff --git a/code/ui/manager/src/components/sidebar/Menu.tsx b/code/ui/manager/src/components/sidebar/Menu.tsx
index e9749a60186b..3f66fc013a4d 100644
--- a/code/ui/manager/src/components/sidebar/Menu.tsx
+++ b/code/ui/manager/src/components/sidebar/Menu.tsx
@@ -4,8 +4,7 @@ import React, { useMemo, useState } from 'react';
import { styled } from '@storybook/theming';
import { transparentize } from 'polished';
import type { Button, TooltipLinkListLink } from '@storybook/components';
-import { WithTooltip, TooltipLinkList, IconButton, Icons } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { WithTooltip, TooltipLinkList, Icons, IconButton } from '@storybook/components';
export type MenuList = ComponentProps['links'];
@@ -17,7 +16,7 @@ const sharedStyles = {
display: 'block',
};
-const StyledIcon = styled(Icons)(sharedStyles, ({ theme }) => ({
+const Icon = styled(Icons)(sharedStyles, ({ theme }) => ({
color: theme.color.secondary,
}));
@@ -78,7 +77,7 @@ export interface ListItemIconProps {
*/
export const MenuItemIcon = ({ icon, imgSrc }: ListItemIconProps) => {
if (icon) {
- return ;
+ return ;
}
if (imgSrc) {
return ;
@@ -124,7 +123,7 @@ export const SidebarMenu: FC<{
highlighted={isHighlighted}
active={isTooltipVisible}
>
-
+
);
@@ -148,7 +147,7 @@ export const ToolbarMenu: FC<{
tooltip={({ onHide }) => }
>
-
+
);
diff --git a/code/ui/manager/src/components/sidebar/RefBlocks.tsx b/code/ui/manager/src/components/sidebar/RefBlocks.tsx
index e232ef24bcd3..ddea8ed11aa6 100644
--- a/code/ui/manager/src/components/sidebar/RefBlocks.tsx
+++ b/code/ui/manager/src/components/sidebar/RefBlocks.tsx
@@ -2,8 +2,7 @@ import { global } from '@storybook/global';
import type { FC } from 'react';
import React, { useState, useCallback, Fragment } from 'react';
-import { WithTooltip, Spaced, Button, Link, ErrorFormatter } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Icons, WithTooltip, Spaced, Button, Link, ErrorFormatter } from '@storybook/components';
import { logger } from '@storybook/client-logger';
import { styled } from '@storybook/theming';
@@ -79,7 +78,7 @@ export const AuthBlock: FC<{ loginUrl: string; id: string }> = ({ loginUrl, id }
@@ -89,7 +88,7 @@ export const AuthBlock: FC<{ loginUrl: string; id: string }> = ({ loginUrl, id }
Sign in to browse this Storybook.
@@ -115,7 +114,7 @@ export const ErrorBlock: FC<{ error: Error }> = ({ error }) => (
>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
- View error
+ View error
{' '}
diff --git a/code/ui/manager/src/components/sidebar/RefIndicator.tsx b/code/ui/manager/src/components/sidebar/RefIndicator.tsx
index 5c8b8f92c217..a46ba2c89642 100644
--- a/code/ui/manager/src/components/sidebar/RefIndicator.tsx
+++ b/code/ui/manager/src/components/sidebar/RefIndicator.tsx
@@ -3,8 +3,7 @@ import type { FC } from 'react';
import React, { useMemo, useCallback, forwardRef } from 'react';
import type { TooltipLinkListLink } from '@storybook/components';
-import { WithTooltip, Spaced, TooltipLinkList, Icons } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Icons, WithTooltip, Spaced, TooltipLinkList } from '@storybook/components';
import { styled } from '@storybook/theming';
import { transparentize } from 'polished';
import { useStorybookApi } from '@storybook/manager-api';
@@ -160,7 +159,7 @@ const CurrentVersion: FC = ({ url, versions }) => {
return (
{currentVersionId}
-
+
);
};
@@ -205,7 +204,7 @@ export const RefIndicator = React.memo(
}
>
-
+
diff --git a/code/ui/manager/src/components/sidebar/Tree.tsx b/code/ui/manager/src/components/sidebar/Tree.tsx
index a2a17c847827..8d5ac50484ea 100644
--- a/code/ui/manager/src/components/sidebar/Tree.tsx
+++ b/code/ui/manager/src/components/sidebar/Tree.tsx
@@ -9,7 +9,6 @@ import type {
} from '@storybook/manager-api';
import { styled } from '@storybook/theming';
import { Button, Icons, TooltipLinkList, WithTooltip } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
import { transparentize } from 'polished';
import type { MutableRefObject } from 'react';
import React, { useCallback, useMemo, useRef } from 'react';
@@ -302,7 +301,7 @@ const Node = React.memo(function Node({
setFullyExpanded();
}}
>
- {isFullyExpanded ? : }
+
)}
diff --git a/code/ui/manager/src/containers/menu.tsx b/code/ui/manager/src/containers/menu.tsx
index 8230b16aae0a..a387cb24d5f3 100644
--- a/code/ui/manager/src/containers/menu.tsx
+++ b/code/ui/manager/src/containers/menu.tsx
@@ -1,8 +1,7 @@
import type { FC } from 'react';
import React, { useCallback, useMemo } from 'react';
-import { Badge } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Badge, Icons } from '@storybook/components';
import type { API, State } from '@storybook/manager-api';
import { shortcutToHumanString } from '@storybook/manager-api';
import { styled, useTheme } from '@storybook/theming';
@@ -104,7 +103,7 @@ export const useMenu = (
onClick: () => api.toggleNav(),
active: showNav,
right: enableShortcuts ? : null,
- left: showNav ? : null,
+ left: showNav ? : null,
}),
[api, enableShortcuts, shortcutKeys, showNav]
);
@@ -116,7 +115,7 @@ export const useMenu = (
onClick: () => api.toggleToolbar(),
active: showToolbar,
right: enableShortcuts ? : null,
- left: showToolbar ? : null,
+ left: showToolbar ? : null,
}),
[api, enableShortcuts, shortcutKeys, showToolbar]
);
@@ -128,7 +127,7 @@ export const useMenu = (
onClick: () => api.togglePanel(),
active: showPanel,
right: enableShortcuts ? : null,
- left: showPanel ? : null,
+ left: showPanel ? : null,
}),
[api, enableShortcuts, shortcutKeys, showPanel]
);
@@ -150,7 +149,7 @@ export const useMenu = (
onClick: () => api.toggleFullscreen(),
active: isFullscreen,
right: enableShortcuts ? : null,
- left: isFullscreen ? : null,
+ left: isFullscreen ? : null,
}),
[api, enableShortcuts, shortcutKeys, isFullscreen]
);
diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts
index 793165aaf103..ef2523f0e06a 100644
--- a/code/ui/manager/src/globals/exports.ts
+++ b/code/ui/manager/src/globals/exports.ts
@@ -114,15 +114,6 @@ export default {
'resetComponents',
'withReset',
],
- '@storybook/components/experimental': [
- 'Button',
- 'Icon',
- 'IconButton',
- 'Input',
- 'Link',
- 'Select',
- 'Toolbar',
- ],
'@storybook/channels': [
'Channel',
'PostMessageTransport',
@@ -172,6 +163,7 @@ export default {
'STORY_SPECIFIED',
'STORY_THREW_EXCEPTION',
'STORY_UNCHANGED',
+ 'TELEMETRY_ERROR',
'TOGGLE_WHATS_NEW_NOTIFICATIONS',
'UPDATE_GLOBALS',
'UPDATE_QUERY_PARAMS',
diff --git a/code/ui/manager/src/globals/runtime.ts b/code/ui/manager/src/globals/runtime.ts
index 391acebf3e91..5850699f171d 100644
--- a/code/ui/manager/src/globals/runtime.ts
+++ b/code/ui/manager/src/globals/runtime.ts
@@ -2,7 +2,6 @@ import * as REACT from 'react';
import * as REACTDOM from 'react-dom';
import * as STORYBOOKCOMPONENTS from '@storybook/components';
-import * as STORYBOOKCOMPONENTSEXPERIMENTAL from '@storybook/components/experimental';
import * as STORYBOOKCHANNELS from '@storybook/channels';
import * as STORYBOOKEVENTS from '@storybook/core-events';
import * as STORYBOOKROUTER from '@storybook/router';
@@ -17,7 +16,6 @@ export const values: Required> = {
react: REACT as any,
'react-dom': REACTDOM,
'@storybook/components': STORYBOOKCOMPONENTS,
- '@storybook/components/experimental': STORYBOOKCOMPONENTSEXPERIMENTAL,
'@storybook/channels': STORYBOOKCHANNELS,
'@storybook/core-events': STORYBOOKEVENTS,
'@storybook/router': STORYBOOKROUTER,
diff --git a/code/ui/manager/src/globals/types.ts b/code/ui/manager/src/globals/types.ts
index a499ea31bfaf..2861e45f632a 100644
--- a/code/ui/manager/src/globals/types.ts
+++ b/code/ui/manager/src/globals/types.ts
@@ -5,7 +5,6 @@ export enum Keys {
'react' = '__REACT__',
'react-dom' = '__REACTDOM__',
'@storybook/components' = '__STORYBOOKCOMPONENTS__',
- '@storybook/components/experimental' = '__STORYBOOKCOMPONENTSEXPERIMENTAL__',
'@storybook/channels' = '__STORYBOOKCHANNELS__',
'@storybook/core-events' = '__STORYBOOKCOREEVENTS__',
'@storybook/router' = '__STORYBOOKROUTER__',
diff --git a/code/ui/manager/src/index.tsx b/code/ui/manager/src/index.tsx
index 8bf921c005da..2836846be5b1 100644
--- a/code/ui/manager/src/index.tsx
+++ b/code/ui/manager/src/index.tsx
@@ -7,6 +7,7 @@ import { Location, LocationProvider, useNavigate } from '@storybook/router';
import { Provider as ManagerProvider, types } from '@storybook/manager-api';
import type { Combo } from '@storybook/manager-api';
import { ThemeProvider, ensure as ensureTheme } from '@storybook/theming';
+import { ProviderDoesNotExtendBaseProviderError } from '@storybook/core-events/manager-errors';
import { HelmetProvider } from 'react-helmet-async';
@@ -83,7 +84,7 @@ const Main: FC<{ provider: Provider }> = ({ provider }) => {
export function renderStorybookUI(domNode: HTMLElement, provider: Provider) {
if (!(provider instanceof Provider)) {
- throw new Error('provider is not extended from the base Provider');
+ throw new ProviderDoesNotExtendBaseProviderError();
}
ReactDOM.render(, domNode);
diff --git a/code/ui/manager/src/runtime.ts b/code/ui/manager/src/runtime.ts
index bb1691be334c..dd29b9a45223 100644
--- a/code/ui/manager/src/runtime.ts
+++ b/code/ui/manager/src/runtime.ts
@@ -1,3 +1,5 @@
+/* eslint-disable local-rules/no-uncategorized-errors */
+
import { global } from '@storybook/global';
import type { Channel } from '@storybook/channels';
@@ -5,7 +7,8 @@ import type { AddonStore } from '@storybook/manager-api';
import { addons } from '@storybook/manager-api';
import type { Addon_Types, Addon_Config } from '@storybook/types';
import { createBrowserChannel } from '@storybook/channels';
-import { CHANNEL_CREATED } from '@storybook/core-events';
+import { CHANNEL_CREATED, TELEMETRY_ERROR } from '@storybook/core-events';
+import { UncaughtManagerError } from '@storybook/core-events/manager-errors';
import Provider from './provider';
import { renderStorybookUI } from './index';
@@ -35,6 +38,7 @@ class ReactProvider extends Provider {
this.addons = addons;
this.channel = channel;
+ global.__STORYBOOK_ADDONS_CHANNEL__ = channel;
if (FEATURES?.storyStoreV7 && CONFIG_TYPE === 'DEVELOPMENT') {
this.serverChannel = this.channel;
@@ -55,12 +59,51 @@ class ReactProvider extends Provider {
}
}
-const { document } = global;
-
-const rootEl = document.getElementById('root');
-renderStorybookUI(rootEl, new ReactProvider());
-
// Apply all the globals
Object.keys(Keys).forEach((key: keyof typeof Keys) => {
global[Keys[key]] = values[key];
});
+
+function preprocessError(
+ originalError: Error & {
+ fromStorybook?: boolean;
+ category?: string;
+ target?: any;
+ currentTarget?: any;
+ srcElement?: any;
+ }
+) {
+ let error = originalError;
+
+ if (!originalError.fromStorybook) {
+ error = new UncaughtManagerError(originalError);
+ }
+
+ // DOM manipulation errors and other similar errors are not serializable as they contain
+ // circular references to the window object. If that's the case, we make a simplified copy
+ if (error.target === window || error.currentTarget === window || error.srcElement === window) {
+ error = new Error(originalError.message);
+ error.name = originalError.name || error.name;
+ error.category = originalError.category;
+ }
+
+ return error;
+}
+
+global.sendTelemetryError = (error) => {
+ const channel = global.__STORYBOOK_ADDONS_CHANNEL__;
+ channel.emit(TELEMETRY_ERROR, preprocessError(error));
+};
+
+// handle all uncaught errors at the root of the application and log to telemetry
+global.addEventListener('error', (args) => {
+ const error = args.error || args;
+ global.sendTelemetryError(error);
+});
+global.addEventListener('unhandledrejection', ({ reason }) => {
+ global.sendTelemetryError(reason);
+});
+
+const { document } = global;
+const rootEl = document.getElementById('root');
+renderStorybookUI(rootEl, new ReactProvider());
diff --git a/code/ui/manager/src/settings/index.tsx b/code/ui/manager/src/settings/index.tsx
index 2d2f91d985c5..24b0b12a8229 100644
--- a/code/ui/manager/src/settings/index.tsx
+++ b/code/ui/manager/src/settings/index.tsx
@@ -1,6 +1,5 @@
import { useStorybookApi, useStorybookState, types } from '@storybook/manager-api';
-import { IconButton, FlexBar, TabBar, TabButton, ScrollArea } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { IconButton, Icons, FlexBar, TabBar, TabButton, ScrollArea } from '@storybook/components';
import { Location, Route } from '@storybook/router';
import { styled } from '@storybook/theming';
import { global } from '@storybook/global';
@@ -95,7 +94,7 @@ const Pages: FC<{
}}
title="Close settings page"
>
-
+
diff --git a/code/ui/manager/src/settings/whats_new.tsx b/code/ui/manager/src/settings/whats_new.tsx
index f66217f6f925..b9e11aea2a7b 100644
--- a/code/ui/manager/src/settings/whats_new.tsx
+++ b/code/ui/manager/src/settings/whats_new.tsx
@@ -1,8 +1,7 @@
import type { ComponentProps, FC } from 'react';
import React, { Fragment, useEffect, useState } from 'react';
import { styled, useTheme } from '@storybook/theming';
-import { Button, IconButton, Loader, Icons } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Button, IconButton, Icons, Loader } from '@storybook/components';
import { useStorybookApi, useStorybookState } from '@storybook/manager-api';
import { global } from '@storybook/global';
@@ -78,7 +77,7 @@ export const WhatsNewFooter = ({
return (
-
+
Share this with your team.
{copyText}
@@ -87,12 +86,12 @@ export const WhatsNewFooter = ({
{isNotificationsEnabled ? (
<>
-
+
Hide notifications
>
) : (
<>
-
+
Show notifications
>
)}
diff --git a/code/ui/manager/src/typings.d.ts b/code/ui/manager/src/typings.d.ts
index f46c49b91852..2ff3df07e63e 100644
--- a/code/ui/manager/src/typings.d.ts
+++ b/code/ui/manager/src/typings.d.ts
@@ -25,3 +25,5 @@ declare var __STORYBOOKTHEMING__: any;
declare var __STORYBOOKAPI__: any;
declare var __STORYBOOKADDONS__: any;
declare var __STORYBOOKCLIENTLOGGER__: any;
+declare var __STORYBOOK_ADDONS_CHANNEL__: any;
+declare var sendTelemetryError: (error: any) => void;
diff --git a/code/yarn.lock b/code/yarn.lock
index 88afaae488c0..799a4a106cbe 100644
--- a/code/yarn.lock
+++ b/code/yarn.lock
@@ -453,7 +453,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.19.6, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.0, @babel/core@npm:^7.22.1, @babel/core@npm:^7.22.9, @babel/core@npm:^7.3.4, @babel/core@npm:^7.7.5":
+"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.19.6, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.1, @babel/core@npm:^7.22.9, @babel/core@npm:^7.3.4, @babel/core@npm:^7.7.5":
version: 7.22.9
resolution: "@babel/core@npm:7.22.9"
dependencies:
@@ -5704,7 +5704,7 @@ __metadata:
polished: ^4.2.2
prop-types: ^15.7.2
react-inspector: ^6.0.0
- telejson: ^7.0.3
+ telejson: ^7.2.0
ts-dedent: ^2.0.0
typescript: ~4.9.3
uuid: ^9.0.0
@@ -6277,7 +6277,7 @@ __metadata:
jest-specific-snapshot: ^8.0.0
read-pkg-up: ^7.0.1
semver: ^7.3.7
- telejson: ^7.0.3
+ telejson: ^7.2.0
tmp: ^0.2.1
ts-dedent: ^2.0.0
tsconfig-paths-webpack-plugin: ^4.0.1
@@ -6383,7 +6383,7 @@ __metadata:
memoizerific: ^1.11.3
polished: ^4.2.2
react-colorful: ^5.1.2
- telejson: ^7.0.3
+ telejson: ^7.2.0
tocbot: ^4.20.1
ts-dedent: ^2.0.0
util-deprecate: ^1.0.2
@@ -6466,15 +6466,23 @@ __metadata:
version: 0.0.0-use.local
resolution: "@storybook/builder-webpack5@workspace:builders/builder-webpack5"
dependencies:
- "@babel/core": ^7.22.0
+ "@babel/core": ^7.22.9
+ "@storybook/addons": "workspace:*"
"@storybook/channels": "workspace:*"
+ "@storybook/client-api": "workspace:*"
"@storybook/client-logger": "workspace:*"
+ "@storybook/components": "workspace:*"
"@storybook/core-common": "workspace:*"
"@storybook/core-events": "workspace:*"
"@storybook/core-webpack": "workspace:*"
+ "@storybook/global": ^5.0.0
+ "@storybook/manager-api": "workspace:*"
"@storybook/node-logger": "workspace:*"
"@storybook/preview": "workspace:*"
"@storybook/preview-api": "workspace:*"
+ "@storybook/router": "workspace:*"
+ "@storybook/store": "workspace:*"
+ "@storybook/theming": "workspace:*"
"@swc/core": ^1.3.49
"@types/node": ^16.0.0
"@types/pretty-hrtime": ^1.0.0
@@ -6509,6 +6517,9 @@ __metadata:
webpack-dev-middleware: ^6.1.1
webpack-hot-middleware: ^2.25.1
webpack-virtual-modules: ^0.5.0
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
typescript:
optional: true
@@ -6543,7 +6554,7 @@ __metadata:
"@storybook/core-events": "workspace:*"
"@storybook/global": ^5.0.0
qs: ^6.10.0
- telejson: ^7.0.3
+ telejson: ^7.2.0
tiny-invariant: ^1.3.1
typescript: ~4.9.3
languageName: unknown
@@ -6743,6 +6754,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@storybook/core-events@workspace:lib/core-events"
dependencies:
+ ts-dedent: ^2.0.0
typescript: ~4.9.3
languageName: unknown
linkType: soft
@@ -6797,7 +6809,7 @@ __metadata:
semver: ^7.3.7
serve-favicon: ^2.5.0
slash: ^5.0.0
- telejson: ^7.0.3
+ telejson: ^7.2.0
tiny-invariant: ^1.3.1
ts-dedent: ^2.0.0
typescript: ~4.9.3
@@ -7077,7 +7089,7 @@ __metadata:
qs: ^6.10.0
semver: ^7.3.7
store2: ^2.14.2
- telejson: ^7.0.3
+ telejson: ^7.2.0
ts-dedent: ^2.0.0
typescript: ~4.9.3
peerDependencies:
@@ -7503,6 +7515,7 @@ __metadata:
"@storybook/channels": "workspace:*"
"@storybook/client-logger": "workspace:*"
"@storybook/core-events": "workspace:*"
+ "@storybook/global": ^5.0.0
"@storybook/preview-api": "workspace:*"
typescript: ~4.9.3
languageName: unknown
@@ -7760,6 +7773,7 @@ __metadata:
eslint: ^8.28.0
eslint-import-resolver-typescript: ^3.5.2
eslint-plugin-import: ^2.26.0
+ eslint-plugin-local-rules: "portal:../scripts/eslint-plugin-local-rules"
eslint-plugin-react: ^7.31.10
eslint-plugin-storybook: ^0.6.6
fs-extra: ^11.1.0
@@ -15740,6 +15754,12 @@ __metadata:
languageName: node
linkType: hard
+"eslint-plugin-local-rules@portal:../scripts/eslint-plugin-local-rules::locator=%40storybook%2Froot%40workspace%3A.":
+ version: 0.0.0-use.local
+ resolution: "eslint-plugin-local-rules@portal:../scripts/eslint-plugin-local-rules::locator=%40storybook%2Froot%40workspace%3A."
+ languageName: node
+ linkType: soft
+
"eslint-plugin-prettier@npm:^3.4.0":
version: 3.4.1
resolution: "eslint-plugin-prettier@npm:3.4.1"
@@ -29429,12 +29449,12 @@ __metadata:
languageName: node
linkType: hard
-"telejson@npm:^7.0.3":
- version: 7.1.0
- resolution: "telejson@npm:7.1.0"
+"telejson@npm:^7.2.0":
+ version: 7.2.0
+ resolution: "telejson@npm:7.2.0"
dependencies:
memoizerific: ^1.11.3
- checksum: dc9a185d0e00d947c0eaa229bfb993aab61a3ba79282ae409768fc8ae66d236e89a64ebe291f9ea6ed5e05396e0be52a7542ea32b6c1321b20440f28c7828edc
+ checksum: d26e6cc93e54bfdcdb207b49905508c5db45862e811a2e2193a735409e47b14530e1c19351618a3e03ad2fd4ffc3759364fcd72851aba2df0300fab574b6151c
languageName: node
linkType: hard
diff --git a/docs/addons/writing-addons.md b/docs/addons/writing-addons.md
index a7b361f76f0a..db951af33832 100644
--- a/docs/addons/writing-addons.md
+++ b/docs/addons/writing-addons.md
@@ -109,8 +109,7 @@ Going through the code blocks in sequence:
```ts
import { useGlobals, useStorybookApi } from '@storybook/manager-api';
-import { IconButton } from '@storybook/components';
-import { Icon } from '@storybook/components/experimental';
+import { Icons, IconButton } from '@storybook/components';
```
The [`useGlobals`](./addons-api.md#useglobals) and [`useStorybookApi`](./addons-api.md#usestorybookapi) hooks from the `manager-api` package are used to access the Storybook's APIs, allowing users to interact with the addon, such as enabling or disabling it. The `Icons` and `IconButtons` components from the [`@storybook/components`](https://www.npmjs.com/package/@storybook/components) package render the icons and buttons in the toolbar.
@@ -145,7 +144,7 @@ export const Tool = memo(function MyAddonSelector() {
title="Apply outlines to the preview"
onClick={toggleMyTool}
>
-
+
);
});
diff --git a/docs/essentials/controls.md b/docs/essentials/controls.md
index 5266c0760f02..cc0f937ec97b 100644
--- a/docs/essentials/controls.md
+++ b/docs/essentials/controls.md
@@ -123,26 +123,26 @@ If you haven't used the CLI to setup the configuration, or if you want to define
## Fully custom args
-Until now, we only used auto-generated controls based on the component we're writing stories for. If we are writing [complex stories](../writing-stories/stories-for-multiple-components.md), we may want to add controls for args that arenβt part of the component.
+Until now, we only used auto-generated controls based on the component we're writing stories for. If we are writing [complex stories](../writing-stories/stories-for-multiple-components.md), we may want to add controls for args that arenβt part of the component. For example, here's how you could use a `footer` arg to populate a child component:
diff --git a/docs/essentials/highlight.md b/docs/essentials/highlight.md
index 926f1a9589e4..c1f8222a9885 100644
--- a/docs/essentials/highlight.md
+++ b/docs/essentials/highlight.md
@@ -2,36 +2,51 @@
title: 'Highlight'
---
-Storybook's [Highlight](https://storybook.js.org/addons/@storybook/addon-highlight/) addon allows you to highlight specific DOM nodes within your story. You can use it to call attention to particular parts of the story.
+Storybook's [Highlight](https://storybook.js.org/addons/@storybook/addon-highlight/) addon is a helpful tool for visually debugging your components, allowing you to highlight specific DOM nodes within your story when used as a standalone addon or enhancing other addons such as the [Accessibility addon](https://storybook.js.org/addons/@storybook/addon-a11y/) to inform you of accessibility issues within your components.
-![](highlight.png)
+![Story with highlighted elements](./highlight.png)
-This addon can be used to enhance other addons. For example, [Accessibility](https://storybook.js.org/addons/@storybook/addon-a11y/) addon uses it to highlight DOM nodes that are failing accessibility checks.
+## Highlighting DOM Elements
-## Apply or clear highlights
-
-Highlight DOM nodes by emitting the `HIGHLIGHT` event from within a story or an addon. The event payload must contain a list of selectors you want to highlight.
+To highlight DOM elements with the addon, you'll need to emit the `HIGHLIGHT` event from within a story or an addon. The event payload must contain an `elements` property assigned to an array of selectors matching the elements you want to highlight. For example:
-Highlights are automatically cleared when the story changes. You can also manually clear them by emitting the `RESET_HIGHLIGHT` event.
+
+
+π‘ We recommend choosing the most specific selector possible to avoid highlighting elements other addons use. This is because the addon tries to match selectors against the entire DOM tree.
+
+
+
+### Reset highlighted elements
+
+Out of the box, Storybook automatically removes highlighted elements when transitioning between stories. However, if you need to clear them manually, you can emit the `RESET_HIGHLIGHT` event from within a story or an addon. For example:
@@ -39,11 +54,19 @@ Highlights are automatically cleared when the story changes. You can also manual
## Customize style
+By default, the addon applies a standard style to the highlighted elements you've enabled for the story. However, you can enable your custom style by extending the payload object and providing a `color` and/or `style` properties. For example:
+
diff --git a/docs/essentials/highlight.png b/docs/essentials/highlight.png
index 616e42e388b5..2d1aef2f56ea 100644
Binary files a/docs/essentials/highlight.png and b/docs/essentials/highlight.png differ
diff --git a/docs/snippets/angular/addon-highlight-reset.ts.mdx b/docs/snippets/angular/addon-highlight-reset.ts.mdx
new file mode 100644
index 000000000000..04fe5864f9fe
--- /dev/null
+++ b/docs/snippets/angular/addon-highlight-reset.ts.mdx
@@ -0,0 +1,30 @@
+```ts
+// MyComponent.stories.ts
+
+import type { Meta, StoryObj } from '@storybook/angular';
+import { componentWrapperDecorator } from '@storybook/angular';
+import { useChannel } from '@storybook/preview-api';
+import { HIGHLIGHT, RESET_HIGHLIGHT } from '@storybook/addon-highlight';
+
+import { MyComponent } from './MyComponent.component';
+
+const meta: Meta = {
+ component: MyComponent,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const ResetHighlight: Story = {
+ decorators: [
+ componentWrapperDecorator((story) => {
+ const emit = useChannel({});
+ emit(RESET_HIGHLIGHT); //π Remove previously highlighted elements
+ emit(HIGHLIGHT, {
+ elements: ['header', 'section', 'footer'],
+ });
+ return story;
+ }),
+ ],
+};
+```
diff --git a/docs/snippets/angular/component-story-highlight-addon.ts.mdx b/docs/snippets/angular/component-story-highlight-addon.ts.mdx
index 1786f86192e0..b64a6c96bac7 100644
--- a/docs/snippets/angular/component-story-highlight-addon.ts.mdx
+++ b/docs/snippets/angular/component-story-highlight-addon.ts.mdx
@@ -1,34 +1,29 @@
```ts
-// Card.stories.ts
+// MyComponent.stories.ts
-import { componentWrapperDecorator } from '@storybook/angular';
import type { Meta, StoryObj } from '@storybook/angular';
+import { componentWrapperDecorator } from '@storybook/angular';
import { useChannel } from '@storybook/preview-api';
-import { HIGHLIGHT, RESET_HIGHLIGHT } from '@storybook/addon-highlight';
-import { Card } from './card.component';
+import { HIGHLIGHT } from '@storybook/addon-highlight';
-const meta: Meta = {
- /* π The title prop is optional.
- * See https://storybook.js.org/docs/angular/configure/overview#configure-story-loading
- * to learn how to generate automatic titles
- */
- title: 'Card',
- component: Card,
+import { MyComponent } from './MyComponent.component';
+
+const meta: Meta = {
+ component: MyComponent,
};
export default meta;
-type Story = StoryObj;
+type Story = StoryObj;
-export const Default: Story = (args) => ({
- template: '',
+export const Highlighted: Story = {
decorators: [
componentWrapperDecorator((story) => {
const emit = useChannel({});
emit(HIGHLIGHT, {
- elements: ['.title', '.subtitle'],
+ elements: ['h2', 'a', '.storybook-button'],
});
return story;
}),
],
-});
+};
```
diff --git a/docs/snippets/angular/highlight-addon-custom-style.ts.mdx b/docs/snippets/angular/highlight-addon-custom-style.ts.mdx
new file mode 100644
index 000000000000..193a4387e614
--- /dev/null
+++ b/docs/snippets/angular/highlight-addon-custom-style.ts.mdx
@@ -0,0 +1,31 @@
+```ts
+// MyComponent.stories.ts
+
+import type { Meta, StoryObj } from '@storybook/angular';
+import { componentWrapperDecorator } from '@storybook/angular';
+import { useChannel } from '@storybook/preview-api';
+import { HIGHLIGHT } from '@storybook/addon-highlight';
+
+import { MyComponent } from './MyComponent.component';
+
+const meta: Meta = {
+ component: MyComponent,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const StyledHighlight: Story = {
+ decorators: [
+ componentWrapperDecorator((story) => {
+ const emit = useChannel({});
+ emit(HIGHLIGHT, {
+ elements: ['h2', 'a', '.storybook-button'],
+ color: 'blue',
+ style: 'double', // 'dotted' | 'dashed' | 'solid' | 'double'
+ });
+ return story;
+ }),
+ ],
+};
+```
diff --git a/docs/snippets/angular/page-story-slots.ts.mdx b/docs/snippets/angular/page-story-slots.ts.mdx
index 2b79a6caa3e3..63ac7f3309cc 100644
--- a/docs/snippets/angular/page-story-slots.ts.mdx
+++ b/docs/snippets/angular/page-story-slots.ts.mdx
@@ -5,26 +5,23 @@ import type { Meta, StoryObj } from '@storybook/angular';
import { Page } from './page.component';
-const meta: Meta = {
- component: Page,
-};
-
-export default meta;
-type Story = StoryObj;
+type PagePropsAndCustomArgs = Page & { footer?: string };
-/*
- *π Render functions are a framework specific feature to allow you control on how the component renders.
- * See https://storybook.js.org/docs/angular/api/csf
- * to learn how to use render functions.
- */
-export const CustomFooter: Story = {
- render: (args) => ({
+const meta: Meta = {
+ component: Page,
+ render: ({ footer, ...args }) => ({
props: args,
template: `
- ${args.footer}
+ ${footer}
`,
}),
+};
+export default meta;
+
+type Story = StoryObj;
+
+export const CustomFooter: Story = {
args: {
footer: 'Built with Storybook',
},
diff --git a/docs/snippets/angular/table-story-fully-customize-controls.ts.mdx b/docs/snippets/angular/table-story-fully-customize-controls.ts.mdx
deleted file mode 100644
index 387ca9506c93..000000000000
--- a/docs/snippets/angular/table-story-fully-customize-controls.ts.mdx
+++ /dev/null
@@ -1,39 +0,0 @@
-```ts
-// Table.stories.ts
-
-import type { Meta, StoryObj } from '@storybook/angular';
-
-import { Table } from './Table.component';
-
-const meta: Meta = {
- component: Table,
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Numeric: Story = {
- render: (args) => ({
- props: args,
- template: `
-
-
-
-
- {{data[i][j]}}
- |
-
-
-
- `,
- }),
- args: {
- data: [
- [1, 2, 3],
- [4, 5, 6],
- ],
- //π The remaining args get passed to the `Table` component
- size: 'large',
- },
-};
-```
diff --git a/docs/snippets/angular/typed-csf-file.ts.mdx b/docs/snippets/angular/typed-csf-file.ts.mdx
new file mode 100644
index 000000000000..6ac8b473a93b
--- /dev/null
+++ b/docs/snippets/angular/typed-csf-file.ts.mdx
@@ -0,0 +1,22 @@
+```ts
+// Button.stories.ts
+
+import type { Meta, StoryObj } from '@storybook/angular';
+
+import { Button } from './button.component';
+
+const meta: Meta