From d2b156defea4a9fa5796a8df93c778aec4e7e345 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Wed, 9 Aug 2023 23:10:49 +0200 Subject: [PATCH 01/48] add bottom slot to sidebar --- code/lib/types/src/modules/addons.ts | 19 +++++++- code/ui/components/src/new/Button/Button.tsx | 3 +- .../components/sidebar/Sidebar.stories.tsx | 46 ++++++++++++++++++- .../src/components/sidebar/Sidebar.tsx | 35 +++++++++++--- code/ui/manager/src/containers/sidebar.tsx | 4 +- 5 files changed, 97 insertions(+), 10 deletions(-) diff --git a/code/lib/types/src/modules/addons.ts b/code/lib/types/src/modules/addons.ts index 4735d41614f6..fbe621eccf03 100644 --- a/code/lib/types/src/modules/addons.ts +++ b/code/lib/types/src/modules/addons.ts @@ -444,15 +444,27 @@ export interface Addon_WrapperType { }> >; } +export interface Addon_BottomType { + type: Addon_TypesEnum.experimental_BOTTOM; + /** + * The unique id of the tool. + */ + id: string; + /** + * A React.FunctionComponent. + */ + render: FCWithoutChildren; +} type Addon_TypeBaseNames = Exclude< Addon_TypesEnum, - Addon_TypesEnum.PREVIEW | Addon_TypesEnum.experimental_PAGE + Addon_TypesEnum.PREVIEW | Addon_TypesEnum.experimental_PAGE | Addon_TypesEnum.experimental_BOTTOM >; export interface Addon_TypesMapping extends Record { [Addon_TypesEnum.PREVIEW]: Addon_WrapperType; [Addon_TypesEnum.experimental_PAGE]: Addon_PageType; + [Addon_TypesEnum.experimental_BOTTOM]: Addon_BottomType; } export type Addon_Loader = (api: API) => void; @@ -506,6 +518,11 @@ export enum Addon_TypesEnum { * @unstable */ experimental_PAGE = 'page', + /** + * This adds items in the bottom of the sidebar. + * @unstable + */ + experimental_BOTTOM = 'bottom', /** * @deprecated This property does nothing, and will be removed in Storybook 8.0. diff --git a/code/ui/components/src/new/Button/Button.tsx b/code/ui/components/src/new/Button/Button.tsx index f36ea73379d4..c65f4e78aed3 100644 --- a/code/ui/components/src/new/Button/Button.tsx +++ b/code/ui/components/src/new/Button/Button.tsx @@ -1,3 +1,4 @@ +import type { ReactNode } from 'react'; import React, { forwardRef } from 'react'; import { styled } from '@storybook/theming'; import { darken, lighten, rgba, transparentize } from 'polished'; @@ -6,7 +7,7 @@ import type { PropsOf } from '../utils/types'; import { Icon } from '../Icon/Icon'; interface ButtonProps { - children: string; + children?: ReactNode; as?: T; size?: 'small' | 'medium'; variant?: 'solid' | 'outline' | 'ghost'; diff --git a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx index 66fe63fbe43b..412afa5ec389 100644 --- a/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Sidebar.stories.tsx @@ -1,8 +1,10 @@ import React from 'react'; -import type { IndexHash, State } from 'lib/manager-api/src'; +import type { IndexHash, State } from '@storybook/manager-api'; +import { types } from '@storybook/manager-api'; import type { StoryObj, Meta } from '@storybook/react'; import { within, userEvent } from '@storybook/testing-library'; +import { Button } from '@storybook/components/experimental'; import { Sidebar, DEFAULT_REF_ID } from './Sidebar'; import { standardData as standardHeaderData } from './Heading.stories'; import * as ExplorerStories from './Explorer.stories'; @@ -222,3 +224,45 @@ export const Searching: Story = { userEvent.type(search, 'B2'); }, }; + +export const Bottom: Story = { + args: { + previewInitialized: true, + }, + render: (args) => ( + ( + + ), + }, + { + id: '2', + type: types.experimental_BOTTOM, + render: () => ( + + ), + }, + { + id: '3', + type: types.experimental_BOTTOM, + render: () =>