-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implementing StudioPageHeader component (#13559)
- Loading branch information
Showing
38 changed files
with
801 additions
and
0 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
...end/libs/studio-components/src/components/StudioPageHeader/StudioPageHeader.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Canvas, Meta } from '@storybook/blocks'; | ||
import { Heading, Paragraph } from '@digdir/designsystemet-react'; | ||
import * as StudioPageHeaderStories from './StudioPageHeader.stories'; | ||
|
||
<Meta of={StudioPageHeaderStories} /> | ||
|
||
<Heading level={1} size='small'> | ||
StudioPageHeader | ||
</Heading> | ||
<Paragraph> | ||
StudioPageHeader is used to display the header banner at the top of a page. If you want to add | ||
buttons in the header, use the `<StudioPageHeaderButton />` component. This component is created | ||
to match the colours of the page header. | ||
</Paragraph> | ||
|
||
<Canvas of={StudioPageHeaderStories.Preview} /> |
8 changes: 8 additions & 0 deletions
8
frontend/libs/studio-components/src/components/StudioPageHeader/StudioPageHeader.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.studioPageHeader { | ||
/* | ||
To avoid the header to go above the modal, and stay below | ||
the comboboxes on "Designer" page, this is the z-index that | ||
satisfies both. | ||
*/ | ||
z-index: 2000; | ||
} |
57 changes: 57 additions & 0 deletions
57
frontend/libs/studio-components/src/components/StudioPageHeader/StudioPageHeader.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React from 'react'; | ||
import type { Meta, StoryFn } from '@storybook/react'; | ||
import { StudioPageHeader, StudioPageHeaderButton } from './index'; | ||
import { StudioParagraph } from '../StudioParagraph'; | ||
|
||
const PreviewComponent = (args): React.ReactElement => ( | ||
<StudioPageHeader {...args}> | ||
<StudioPageHeader.Main> | ||
<StudioPageHeader.Left title='Left' showTitle={false} /> | ||
<StudioPageHeader.Center> | ||
<StudioPageHeaderButton | ||
color={args.variant === 'regular' ? 'light' : 'dark'} | ||
variant={args.variant} | ||
> | ||
Button | ||
</StudioPageHeaderButton> | ||
</StudioPageHeader.Center> | ||
<StudioPageHeader.Right> | ||
<StudioParagraph size='sm' style={{ color: 'white', paddingLeft: '20px' }}> | ||
Right | ||
</StudioParagraph> | ||
</StudioPageHeader.Right> | ||
</StudioPageHeader.Main> | ||
<StudioPageHeader.Sub> | ||
<div style={{ padding: '10px' }}> | ||
<StudioParagraph size='sm' style={{ color: 'white' }}> | ||
<StudioPageHeaderButton | ||
color={args.variant === 'regular' ? 'dark' : 'light'} | ||
variant={args.variant} | ||
> | ||
Subheader Button | ||
</StudioPageHeaderButton> | ||
</StudioParagraph> | ||
</div> | ||
</StudioPageHeader.Sub> | ||
</StudioPageHeader> | ||
); | ||
|
||
type Story = StoryFn<typeof StudioPageHeader>; | ||
|
||
const meta: Meta = { | ||
title: 'StudioPageHeader', | ||
component: PreviewComponent, | ||
argTypes: { | ||
variant: { | ||
control: 'radio', | ||
options: ['regular', 'preview'], | ||
}, | ||
}, | ||
}; | ||
export const Preview: Story = (args): React.ReactElement => <PreviewComponent {...args} />; | ||
|
||
Preview.args = { | ||
variant: 'regular', | ||
}; | ||
|
||
export default meta; |
27 changes: 27 additions & 0 deletions
27
frontend/libs/studio-components/src/components/StudioPageHeader/StudioPageHeader.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { StudioPageHeader, type StudioPageHeaderProps } from './StudioPageHeader'; | ||
|
||
describe('StudioPageHeader', () => { | ||
it('should render the children passed to it', () => { | ||
const childText = 'Test Child'; | ||
renderStudioPageHeader({ children: <div>{childText}</div> }); | ||
|
||
expect(screen.getByText(childText)).toBeInTheDocument(); | ||
}); | ||
|
||
test('the root container should have role banner', () => { | ||
renderStudioPageHeader({ children: <div>Test Child</div> }); | ||
|
||
const banner = screen.getByRole('banner'); | ||
expect(banner).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
const renderStudioPageHeader = (props: Partial<StudioPageHeaderProps> = {}) => { | ||
const { children, variant = 'regular' } = props; | ||
|
||
return render( | ||
<StudioPageHeader variant={variant}>{children ?? <div>Default Child</div>}</StudioPageHeader>, | ||
); | ||
}; |
22 changes: 22 additions & 0 deletions
22
frontend/libs/studio-components/src/components/StudioPageHeader/StudioPageHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React, { type ReactNode } from 'react'; | ||
import classes from './StudioPageHeader.module.css'; | ||
import { type StudioPageHeaderVariant } from './types/StudioPageHeaderVariant'; | ||
import { StudioPageHeaderContextProvider } from './context'; | ||
|
||
export type StudioPageHeaderProps = { | ||
children: ReactNode; | ||
variant?: StudioPageHeaderVariant; | ||
}; | ||
|
||
export const StudioPageHeader = ({ | ||
children, | ||
variant = 'regular', | ||
}: StudioPageHeaderProps): React.ReactElement => { | ||
return ( | ||
<StudioPageHeaderContextProvider variant={variant}> | ||
<div role='banner' className={classes.studioPageHeader}> | ||
{children} | ||
</div> | ||
</StudioPageHeaderContextProvider> | ||
); | ||
}; |
40 changes: 40 additions & 0 deletions
40
.../src/components/StudioPageHeader/StudioPageHeaderButton/StudioPageHeaderButton.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.button { | ||
--studio-button-regular-dark: #393b51; | ||
--studio-button-regular-medium: #3e4f62; | ||
--studio-button-regular-light: #657281; | ||
|
||
--studio-button-preview-dark: #0c6536; | ||
--studio-button-preview-medium: #118849; | ||
--studio-button-preview-light: #67b38a; | ||
|
||
color: var(--fds-semantic-background-default); | ||
} | ||
|
||
.regularDark { | ||
background-color: var(--studio-button-regular-dark); | ||
} | ||
.regularDark:hover { | ||
background-color: var(--studio-button-regular-medium); | ||
} | ||
|
||
.regularLight { | ||
background-color: var(--studio-button-regular-medium); | ||
} | ||
|
||
.regularLight:hover { | ||
background-color: var(--studio-button-regular-light); | ||
} | ||
|
||
.previewDark { | ||
background-color: var(--studio-button-preview-dark); | ||
} | ||
.previewDark:hover { | ||
background-color: var(--studio-button-preview-medium); | ||
} | ||
|
||
.previewLight { | ||
background-color: var(--studio-button-preview-medium); | ||
} | ||
.previewLight:hover { | ||
background-color: var(--studio-button-preview-light); | ||
} |
71 changes: 71 additions & 0 deletions
71
...ts/src/components/StudioPageHeader/StudioPageHeaderButton/StudioPageHeaderButton.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { StudioPageHeaderButton, type StudioPageHeaderButtonProps } from './StudioPageHeaderButton'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
describe('StudioPageHeaderButton', () => { | ||
it('should apply the correct class based on variant and color - regular dark', () => { | ||
renderStudioPageHeaderButton({ variant: 'regular', color: 'dark' }); | ||
|
||
const button = screen.getByRole('button', { name: buttonText }); | ||
expect(button).toHaveClass('regularDark'); | ||
}); | ||
|
||
it('should apply the correct class based on variant and color - regular light', () => { | ||
renderStudioPageHeaderButton({ variant: 'regular', color: 'light' }); | ||
|
||
const button = screen.getByRole('button', { name: buttonText }); | ||
expect(button).toHaveClass('regularLight'); | ||
}); | ||
|
||
it('should apply the correct class based on variant and color - preview dark', () => { | ||
renderStudioPageHeaderButton({ variant: 'preview', color: 'dark' }); | ||
|
||
const button = screen.getByRole('button', { name: buttonText }); | ||
expect(button).toHaveClass('previewDark'); | ||
}); | ||
|
||
it('should apply the correct class based on variant and color - preview light', () => { | ||
renderStudioPageHeaderButton({ variant: 'preview', color: 'light' }); | ||
|
||
const button = screen.getByRole('button', { name: buttonText }); | ||
expect(button).toHaveClass('previewLight'); | ||
}); | ||
|
||
it('should forward ref to the button element', () => { | ||
const ref = React.createRef<HTMLButtonElement>(); | ||
renderStudioPageHeaderButton({ color: 'dark' }, ref); | ||
|
||
expect(ref.current).toBeInstanceOf(HTMLButtonElement); | ||
}); | ||
|
||
it('should call the onClick function when the button is clicked', async () => { | ||
const user = userEvent.setup(); | ||
|
||
const mockOnClick = jest.fn(); | ||
renderStudioPageHeaderButton({ onClick: mockOnClick }); | ||
|
||
const button = screen.getByRole('button', { name: buttonText }); | ||
await user.click(button); | ||
|
||
expect(mockOnClick).toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
|
||
const buttonText: string = 'Button'; | ||
|
||
const defaultProps: StudioPageHeaderButtonProps = { | ||
color: 'dark', | ||
variant: 'regular', | ||
}; | ||
|
||
const renderStudioPageHeaderButton = ( | ||
props: Partial<StudioPageHeaderButtonProps> = {}, | ||
ref?: React.Ref<HTMLButtonElement>, | ||
) => { | ||
return render( | ||
<StudioPageHeaderButton ref={ref} {...defaultProps} {...props}> | ||
{buttonText} | ||
</StudioPageHeaderButton>, | ||
); | ||
}; |
26 changes: 26 additions & 0 deletions
26
...ponents/src/components/StudioPageHeader/StudioPageHeaderButton/StudioPageHeaderButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React, { forwardRef, type ReactElement } from 'react'; | ||
import classes from './StudioPageHeaderButton.module.css'; | ||
import { StudioButton, type StudioButtonProps } from '../../StudioButton'; | ||
import { type StudioPageHeaderColor } from '../types/StudioPageHeaderColor'; | ||
import cn from 'classnames'; | ||
import { type StudioPageHeaderVariant } from '../types/StudioPageHeaderVariant'; | ||
|
||
export type StudioPageHeaderButtonProps = { | ||
color: StudioPageHeaderColor; | ||
variant: StudioPageHeaderVariant; | ||
} & Omit<StudioButtonProps, 'color' | 'variant'>; | ||
|
||
export const StudioPageHeaderButton = forwardRef<HTMLButtonElement, StudioPageHeaderButtonProps>( | ||
({ color, variant, ...rest }, ref): ReactElement => { | ||
const getClassName = (): string => { | ||
if (variant === 'regular' && color === 'dark') return classes.regularDark; | ||
if (variant === 'regular' && color === 'light') return classes.regularLight; | ||
if (variant === 'preview' && color === 'dark') return classes.previewDark; | ||
if (variant === 'preview' && color === 'light') return classes.previewLight; | ||
}; | ||
|
||
return <StudioButton ref={ref} className={cn(classes.button, getClassName())} {...rest} />; | ||
}, | ||
); | ||
|
||
StudioPageHeaderButton.displayName = 'StudioPageHeaderButton'; |
1 change: 1 addition & 0 deletions
1
...nd/libs/studio-components/src/components/StudioPageHeader/StudioPageHeaderButton/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { StudioPageHeaderButton } from './StudioPageHeaderButton'; |
30 changes: 30 additions & 0 deletions
30
...ts/src/components/StudioPageHeader/StudioPageHeaderCenter/StudioPageHeaderCenter.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { StudioPageHeaderCenter, type StudioPageHeaderCenterProps } from './StudioPageHeaderCenter'; | ||
|
||
describe('StudioPageHeaderCenter', () => { | ||
it('should render the children passed as prop', () => { | ||
const childText = 'Test Child'; | ||
renderStudioPageHeaderCenter({ children: <span>{childText}</span> }); | ||
|
||
expect(screen.getByText(childText)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render multiple children elements', () => { | ||
renderStudioPageHeaderCenter({ | ||
children: ( | ||
<> | ||
<span>Child 1</span> | ||
<span>Child 2</span> | ||
</> | ||
), | ||
}); | ||
|
||
expect(screen.getByText('Child 1')).toBeInTheDocument(); | ||
expect(screen.getByText('Child 2')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
const renderStudioPageHeaderCenter = (props: StudioPageHeaderCenterProps) => { | ||
return render(<StudioPageHeaderCenter {...props} />); | ||
}; |
9 changes: 9 additions & 0 deletions
9
...ponents/src/components/StudioPageHeader/StudioPageHeaderCenter/StudioPageHeaderCenter.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import React, { type ReactNode, type ReactElement } from 'react'; | ||
|
||
export type StudioPageHeaderCenterProps = { | ||
children: ReactNode; | ||
}; | ||
|
||
export const StudioPageHeaderCenter = ({ children }: StudioPageHeaderCenterProps): ReactElement => { | ||
return <div>{children}</div>; | ||
}; |
1 change: 1 addition & 0 deletions
1
...nd/libs/studio-components/src/components/StudioPageHeader/StudioPageHeaderCenter/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { StudioPageHeaderCenter } from './StudioPageHeaderCenter'; |
13 changes: 13 additions & 0 deletions
13
...onents/src/components/StudioPageHeader/StudioPageHeaderLeft/DigdirLogoLink/DigdirLogo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React, { type ReactElement } from 'react'; | ||
|
||
export const DigdirLogo = (): ReactElement => { | ||
return ( | ||
<svg role='img' width='30' height='30' fill='none' xmlns='http://www.w3.org/2000/svg'> | ||
<title>Altinn logo</title> | ||
<path | ||
d='M14.9512 0H0.590024C0.25961 0 0 0.259054 0 0.588759V28.5312C0 28.8609 0.25961 29.12 0.590024 29.12H14.9512C22.8457 28.9434 29.1826 22.4906 29.1826 14.5541C29.1826 6.62942 22.8339 0.176628 14.9512 0ZM16.3437 24.7632C9.23977 25.9289 3.20973 19.9 4.36618 12.8114C5.0742 8.51345 8.54354 5.05155 12.8389 4.35681C19.9546 3.20285 25.9846 9.21996 24.8282 16.3204C24.1202 20.6066 20.6508 24.0685 16.3437 24.7632Z' | ||
fill='white' | ||
/> | ||
</svg> | ||
); | ||
}; |
14 changes: 14 additions & 0 deletions
14
...components/StudioPageHeader/StudioPageHeaderLeft/DigdirLogoLink/DigdirLogoLink.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.wrapper { | ||
display: flex; | ||
align-items: center; | ||
gap: var(--fds-spacing-1); | ||
overflow: hidden; | ||
padding: var(--fds-spacing-2); | ||
} | ||
|
||
.titleText { | ||
color: var(--fds-semantic-background-default); | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
} |
Oops, something went wrong.