From 50e2926fb0d383db2aaa14127e6c032e3d078510 Mon Sep 17 00:00:00 2001 From: juliajforesti Date: Thu, 5 Sep 2024 20:11:13 +0100 Subject: [PATCH] feat: `SidePanel` components --- .../components/SidePanel/SidePanel.spec.tsx | 19 +++++ .../SidePanel/SidePanel.stories.tsx | 75 +++++++++++++++++++ .../SidePanel/SidePanel.styles.scss | 44 +++++++++++ .../src/components/SidePanel/SidePanel.tsx | 11 +++ .../components/SidePanel/SidePanelDivider.tsx | 5 ++ .../components/SidePanel/SidePanelHeader.tsx | 16 ++++ .../SidePanel/SidePanelHeaderTitle.tsx | 13 ++++ .../components/SidePanel/SidePanelList.tsx | 16 ++++ .../SidePanel/SidePanelListItem.tsx | 18 +++++ .../components/SidePanel/SidePanelSection.tsx | 11 +++ .../SidePanel/SidePanelSectionAction.tsx | 13 ++++ .../src/components/SidePanel/index.ts | 8 ++ packages/fuselage/src/components/index.scss | 1 + packages/fuselage/src/components/index.ts | 1 + 14 files changed, 251 insertions(+) create mode 100644 packages/fuselage/src/components/SidePanel/SidePanel.spec.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanel.stories.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanel.styles.scss create mode 100644 packages/fuselage/src/components/SidePanel/SidePanel.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelDivider.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelHeader.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelHeaderTitle.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelList.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelListItem.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelSection.tsx create mode 100644 packages/fuselage/src/components/SidePanel/SidePanelSectionAction.tsx create mode 100644 packages/fuselage/src/components/SidePanel/index.ts diff --git a/packages/fuselage/src/components/SidePanel/SidePanel.spec.tsx b/packages/fuselage/src/components/SidePanel/SidePanel.spec.tsx new file mode 100644 index 0000000000..e133517959 --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanel.spec.tsx @@ -0,0 +1,19 @@ +import { composeStories } from '@storybook/react'; +import { axe } from 'jest-axe'; + +import { render } from '../../testing'; +import * as stories from './SidePanel.stories'; + +const { Default } = composeStories(stories); + +describe('[Sidebar Default story]', () => { + it('renders without crashing', () => { + render(); + }); + it('should have no a11y violations', async () => { + const { container } = render(); + + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); +}); diff --git a/packages/fuselage/src/components/SidePanel/SidePanel.stories.tsx b/packages/fuselage/src/components/SidePanel/SidePanel.stories.tsx new file mode 100644 index 0000000000..afbf626a5c --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanel.stories.tsx @@ -0,0 +1,75 @@ +import type { Meta, StoryFn } from '@storybook/react'; + +import { + SidePanel, + SidePanelSection, + SidePanelHeader, + SidePanelHeaderTitle, + SidePanelList, + SidePanelListItem, +} from '.'; +import { + Avatar, + Box, + Icon, + IconButton, + InputBox, + SideBarItem, + SideBarItemAvatarWrapper, + SideBarItemBadge, + SideBarItemIcon, + SideBarItemMenu, + SideBarItemTitle, +} from '../..'; +import { MenuTemplate, leterAvatarUrls, names } from '../SideBarV2/helpers'; + +export default { + title: 'Navigation/SidePanel', + component: SidePanel, + decorators: [ + (Story) => ( + + + + ), + ], +} as Meta; + +const Template: StoryFn = (args) => ( + + + All + + + + } + /> + + + + {new Array(20).fill(null).map((_, index) => ( + + + + + + + {names[index % 10]} + + } /> + + + ))} + + + +); + +export const Default = Template.bind({}); diff --git a/packages/fuselage/src/components/SidePanel/SidePanel.styles.scss b/packages/fuselage/src/components/SidePanel/SidePanel.styles.scss new file mode 100644 index 0000000000..3274e0effa --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanel.styles.scss @@ -0,0 +1,44 @@ +@use '../../styles/colors.scss'; +@use '../../styles/lengths.scss'; +@use '../../styles/typography.scss'; + +$sidepanel-color-default: colors.font(default); + +%section-base { + display: flex; + justify-content: space-between; + align-items: center; + gap: lengths.padding(8); +} + +.rcx-sidepanel { + display: flex; + flex-direction: column; + flex: 1 0 auto; + + width: lengths.size(276); + + color: $sidepanel-color-default; + border-right: lengths.border-width(default) solid colors.stroke(extra-light); + + background-color: colors.surface(room); + + &-section { + @extend %section-base; + padding: lengths.padding(16); + } + + &-header { + @extend %section-base; + height: lengths.size(44); + padding-inline: lengths.padding(16); + + &__title { + @include typography.use-font-scale(h4); + } + } + + &-list { + padding-block: lengths.padding(8); + } +} diff --git a/packages/fuselage/src/components/SidePanel/SidePanel.tsx b/packages/fuselage/src/components/SidePanel/SidePanel.tsx new file mode 100644 index 0000000000..56fc07610a --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanel.tsx @@ -0,0 +1,11 @@ +import type { HTMLAttributes } from 'react'; + +export const SidePanel = ({ + className, + ...props +}: HTMLAttributes) => ( +
+); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelDivider.tsx b/packages/fuselage/src/components/SidePanel/SidePanelDivider.tsx new file mode 100644 index 0000000000..c0afc0a1cd --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelDivider.tsx @@ -0,0 +1,5 @@ +import { Divider } from '../Divider'; + +export const SidePanelDivider = () => ( + +); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelHeader.tsx b/packages/fuselage/src/components/SidePanel/SidePanelHeader.tsx new file mode 100644 index 0000000000..1f3a26f352 --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelHeader.tsx @@ -0,0 +1,16 @@ +import type { HTMLAttributes } from 'react'; + +import { SidePanelDivider } from './SidePanelDivider'; + +export const SidePanelHeader = ({ + className, + ...props +}: HTMLAttributes) => ( + <> +
+ + +); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelHeaderTitle.tsx b/packages/fuselage/src/components/SidePanel/SidePanelHeaderTitle.tsx new file mode 100644 index 0000000000..2ee6a28fe3 --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelHeaderTitle.tsx @@ -0,0 +1,13 @@ +import type { HTMLAttributes } from 'react'; + +export const SidePanelHeaderTitle = ({ + className, + ...props +}: HTMLAttributes) => ( +
+); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelList.tsx b/packages/fuselage/src/components/SidePanel/SidePanelList.tsx new file mode 100644 index 0000000000..1fdbe6299f --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelList.tsx @@ -0,0 +1,16 @@ +import type { HTMLAttributes } from 'react'; +import { forwardRef } from 'react'; + +export const SidePanelList = forwardRef< + HTMLDivElement, + HTMLAttributes +>(function SidePanelList({ className, ...props }, ref) { + return ( +
+ ); +}); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelListItem.tsx b/packages/fuselage/src/components/SidePanel/SidePanelListItem.tsx new file mode 100644 index 0000000000..f72bdeb5a8 --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelListItem.tsx @@ -0,0 +1,18 @@ +import type { HTMLAttributes } from 'react'; +import { forwardRef } from 'react'; + +export const SidePanelListItem = forwardRef< + HTMLDivElement, + HTMLAttributes +>(function SidePanelListItem({ className, ...props }, ref) { + return ( +
+ ); +}); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelSection.tsx b/packages/fuselage/src/components/SidePanel/SidePanelSection.tsx new file mode 100644 index 0000000000..8c87fd699b --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelSection.tsx @@ -0,0 +1,11 @@ +import type { HTMLAttributes } from 'react'; + +export const SidePanelSection = ({ + className, + ...props +}: HTMLAttributes) => ( +
+); diff --git a/packages/fuselage/src/components/SidePanel/SidePanelSectionAction.tsx b/packages/fuselage/src/components/SidePanel/SidePanelSectionAction.tsx new file mode 100644 index 0000000000..b3a201587f --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/SidePanelSectionAction.tsx @@ -0,0 +1,13 @@ +import type { HTMLAttributes } from 'react'; + +export const SidePanelSectionAction = ({ + className, + ...props +}: HTMLAttributes) => ( +
+); diff --git a/packages/fuselage/src/components/SidePanel/index.ts b/packages/fuselage/src/components/SidePanel/index.ts new file mode 100644 index 0000000000..8ebb2a2734 --- /dev/null +++ b/packages/fuselage/src/components/SidePanel/index.ts @@ -0,0 +1,8 @@ +export * from './SidePanel'; +export * from './SidePanelSection'; +export * from './SidePanelSectionAction'; +export * from './SidePanelHeaderTitle'; +export * from './SidePanelHeader'; +export * from './SidePanelList'; +export * from './SidePanelListItem'; +export * from './SidePanelDivider'; diff --git a/packages/fuselage/src/components/index.scss b/packages/fuselage/src/components/index.scss index f6e0b94270..e05980f78a 100644 --- a/packages/fuselage/src/components/index.scss +++ b/packages/fuselage/src/components/index.scss @@ -33,6 +33,7 @@ @import './RadioButton/RadioButton.styles.scss'; @import './Select/Select.styles.scss'; @import './Sidebar/Sidebar.styles.scss'; +@import './SidePanel/SidePanel.styles.scss'; @import './SideBarV2/SideBar.styles.scss'; @import './Skeleton/Skeleton.styles.scss'; @import './States/States.styles.scss'; diff --git a/packages/fuselage/src/components/index.ts b/packages/fuselage/src/components/index.ts index 670ffb494f..dbe8029ca4 100644 --- a/packages/fuselage/src/components/index.ts +++ b/packages/fuselage/src/components/index.ts @@ -62,6 +62,7 @@ export * from './Popover'; export * from './SelectInput'; export { default as Sidebar } from './Sidebar'; export * from './Sidebar'; +export * from './SidePanel'; export * from './SideBarV2'; export * from './Skeleton'; export * from './States';