diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 45415c2d447..e2ba33fff7d 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -10,6 +10,7 @@ import React from 'react'; import type { Preview } from '@storybook/react'; +import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport'; /* * Preload all EuiIcons - Storybook does not support dynamic icon loading @@ -93,6 +94,9 @@ const preview: Preview = { date: /Date$/, }, }, + viewport: { + viewports: MINIMAL_VIEWPORTS, + }, }, // Due to CommonProps, these props appear on almost every Story, but generally // aren't super useful to test - let's disable them by default and (if needed) diff --git a/src/components/side_nav/side_nav.stories.tsx b/src/components/side_nav/side_nav.stories.tsx new file mode 100644 index 00000000000..fdbfae7c9e1 --- /dev/null +++ b/src/components/side_nav/side_nav.stories.tsx @@ -0,0 +1,149 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { EuiText } from '../text'; + +import { EuiSideNav, EuiSideNavProps } from './side_nav'; + +const meta: Meta = { + title: 'EuiSideNav', + component: EuiSideNav, + decorators: [ + (Story) => ( +
+ {/* The side nav is visually easier to see with the width set */} + +
+ ), + ], +}; + +export default meta; +type Story = StoryObj; + +const componentDefaults: EuiSideNavProps = { + mobileBreakpoints: ['xs', 's'], + items: [], + // mobileTitle does not have defaults; they are being set here as they are shared between examples + mobileTitle: 'Mobile navigation header', + isOpenOnMobile: false, +}; + +const sharedSideNavItems = [ + { + name: 'Has nested children', + id: 'normal_children', + items: [ + { + name: 'Child 1', + id: 'child_1', + items: [ + { + name: 'Selected item', + id: 'selected_item', + onClick: () => {}, + isSelected: true, + items: [], + }, + ], + }, + ], + }, + { + name: 'Has forceOpen: true', + id: 'force_open', + forceOpen: true, + items: [ + { + name: 'Child 3', + id: 'child_3', + }, + ], + }, + { + name: 'Children only without link', + id: 'children_only', + onClick: undefined, + items: [ + { + name: 'Child 4', + id: 'child_4', + }, + ], + }, +]; + +export const Playground: Story = { + args: { + ...componentDefaults, + heading: 'Elastic', + headingProps: { element: 'h1', screenReaderOnly: false }, + items: sharedSideNavItems, + }, +}; + +export const MobileSideNav: Story = { + args: { + ...componentDefaults, + isOpenOnMobile: true, + items: sharedSideNavItems, + mobileTitle: 'Toggle isOpenOnMobile in the controls panel', + }, + argTypes: { + // This story demos the side nav on smaller screens; removing other props to streamline controls + 'aria-label': { table: { disable: true } }, + heading: { table: { disable: true } }, + headingProps: { table: { disable: true } }, + items: { table: { disable: true } }, + renderItem: { table: { disable: true } }, + truncate: { table: { disable: true } }, + }, + parameters: { + viewport: { + defaultViewport: 'mobile1', + }, + }, +}; + +export const RenderItem: Story = { + args: { + ...componentDefaults, + renderItem: ({ children }) => {children}, + items: [ + { + name: 'Kibana', + id: 'kibana', + }, + { + name: 'Observability', + id: 'observability', + }, + { + name: 'Security', + id: 'security', + renderItem: ({ children }) => ( + {children} + ), + }, + ], + }, + argTypes: { + // This story demos the renderItem prop; removing other props to streamline controls + 'aria-label': { table: { disable: true } }, + heading: { table: { disable: true } }, + headingProps: { table: { disable: true } }, + toggleOpenOnMobile: { table: { disable: true } }, + isOpenOnMobile: { table: { disable: true } }, + mobileBreakpoints: { table: { disable: true } }, + mobileTitle: { table: { disable: true } }, + truncate: { table: { disable: true } }, + }, +};