Skip to content

Commit

Permalink
Added Header component for desktop (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexdigdir committed Feb 9, 2024
1 parent d6db695 commit 038ad22
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pg*
*.env*
.DS*

*vscode
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,linux,visualstudiocode,vim,webstorm+all,node,yarn
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,linux,visualstudiocode,vim,webstorm+all,node,yarn

Expand Down
19 changes: 19 additions & 0 deletions packages/frontend-design-poc/src/components/Header/AltinnLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default function AltinnLogo() {
return (
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<title>Altinn logo</title>
<g id="SVG" clipPath="url(#clip0_272_15462)">
<path
id="Vector"
d="M16.4223 0H0.648079C0.476197 0 0.311357 0.0681372 0.189817 0.189421C0.0682796 0.310707 0 0.475203 0 0.646725V31.3533C0 31.5248 0.0682796 31.6893 0.189817 31.8105C0.311357 31.9319 0.476197 32 0.648079 32H16.4223C20.594 31.8816 24.5551 30.1447 27.4639 27.1581C30.3727 24.1717 32 20.1712 32 16.0065C32 11.8418 30.3727 7.84119 27.4639 4.85475C24.5551 1.86829 20.594 0.131336 16.4223 0.0129348V0ZM17.9647 27.1753C15.578 27.5853 13.1227 27.2265 10.9539 26.1509C8.78521 25.0755 7.01584 23.3389 5.90201 21.1931C4.78819 19.0471 4.38771 16.6031 4.75856 14.2148C5.12943 11.8267 6.25239 9.61827 7.96483 7.9094C9.67727 6.20053 11.8903 5.07992 14.2835 4.70983C16.6767 4.33975 19.1259 4.73939 21.2763 5.85089C23.4267 6.9624 25.1667 8.72807 26.2445 10.8922C27.3224 13.0564 27.6819 15.5068 27.2712 17.8884C26.8713 20.2063 25.7621 22.3435 24.0956 24.0065C22.4291 25.6695 20.2873 26.7765 17.9647 27.1753Z"
fill="black"
/>
</g>
<defs>
<clipPath id="clip0_272_15462">
<rect width="32" height="32" fill="white" />
</clipPath>
</defs>
</svg>
);
}
106 changes: 106 additions & 0 deletions packages/frontend-design-poc/src/components/Header/Header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
.navigation {
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
background: #E5EBEC;
/* Må byttes til variabel */
padding: 24px;
max-height: 68px;
}

.logo a {
color: #000;
text-align: center;
font-size: 1.5rem;
font-style: normal;
font-weight: 500;
line-height: 32px;
text-decoration: none;
display: flex;
align-items: center;
}

.logoText {
margin-left: 6px;
}

.searchBar {
margin: 0 42px;

input {
border-radius: 28px;
border: 2px solid black;
}
}



.userSection {
display: flex;
align-items: center;
}

.userProfile {
display: flex;
align-items: center;
margin-left: 20px;
}

.userProfile span {
margin-right: 10px;
}


.nameWithInitials {
display: flex;
align-items: center;
gap: 10px;
padding-right: 22px;
}


.primaryName {
text-align: center;
color: #000;
text-align: center;
font-family: Inter;
font-size: 18px;
font-style: normal;
font-weight: 500;
line-height: 28px;
/* 155.556% */
}

.secondaryName {
color: #000;
text-align: center;
font-family: Inter;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 150%;
}

.companyContainer {
display: flex;
flex-direction: column;
align-items: flex-end;
}

.initialsCircle {
min-width: 48px;
min-height: 48px;
background-color: var(--fds-semantic-surface-success-default);
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
font-size: 20px;
}

.initialsCircle.isOrganization {
border-radius: 4px;
background: var(--Bedrift-Primary, #008FD6);
}
73 changes: 73 additions & 0 deletions packages/frontend-design-poc/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import { Link } from 'react-router-dom';
import styles from './Header.module.css'; // Import the CSS module
import { Search } from '@digdir/design-system-react';
import AltinnLogo from './AltinnLogo';
import cx from 'classnames';

/**
* Simple header component with a logo, search bar, and user name with initials.
*
*
* @component
* @param {string} props.name - The name of the user.
* @param {string} props.companyName - The name of the company the user is associated with if any.
* @returns {JSX.Element} The header component.
*
* @example
* <Header
* name={'Ola Nordmann'}
* companyName="Aker Solutions AS"
* />
*/

export type HeaderProps = {
name: string;
companyName?: string;
};

const getInitials = (name: string, companyName?: string) => {
if (!companyName)
return name
.split(' ')
.map((n) => n[0])
.join('');
return companyName[0];
};

export const Header: React.FC<HeaderProps> = ({ name, companyName }) => {
return (
<header>
<nav className={styles.navigation} aria-label="Navigasjon">
<div className={styles.logo}>
<Link to="/" aria-label="Gå til hovedsiden">
<AltinnLogo aria-label="Altinn logo" />
<span className={styles.logoText}>Altinn</span>
</Link>
</div>
<div className={styles.searchBar}>
<Search size="small" aria-label="Søk" />
</div>
{companyName ? (
<div className={styles.nameWithInitials}>
<div className={styles.companyContainer}>
<div className={styles.primaryName}>{companyName}</div>
<div className={styles.secondaryName}>{name}</div>
</div>
<div className={styles.initialsCircle} aria-hidden="true">
{getInitials(name, companyName)}
</div>
</div>
) : (
<div className={styles.nameWithInitials}>
<span className={styles.primaryName}>{name}</span>
<div className={cx(styles.initialsCircle, styles.isOrganization)} aria-hidden="true">
{getInitials(name, companyName)}
</div>
</div>
)}
</nav>
</header>
);
};
29 changes: 15 additions & 14 deletions packages/storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'storybook-addon-react-router-v6',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
};
export default config;
8 changes: 5 additions & 3 deletions packages/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,28 @@
"@digdir/design-system-tokens": "^0.12.0",
"@navikt/aksel-icons": "^5.18.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.16.0"
},
"resolutions": {
"jackspeak": "2.1.1"
},
"devDependencies": {
"@storybook/addon-essentials": "^7.6.12",
"@storybook/addon-interactions": "^7.6.12",
"@storybook/theming": "^7.6.6",
"@storybook/manager-api": "^7.6.6",
"@storybook/addon-links": "^7.6.12",
"@storybook/addon-onboarding": "^1.0.11",
"@storybook/blocks": "^7.6.12",
"@storybook/manager-api": "^7.6.6",
"@storybook/react": "^7.6.12",
"@storybook/react-vite": "^7.6.12",
"@storybook/test": "^7.6.12",
"@storybook/theming": "^7.6.6",
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@vitejs/plugin-react": "^4.2.1",
"storybook": "^7.6.12",
"storybook-addon-react-router-v6": "^2.0.10",
"typescript": "^5.2.2",
"vite": "^5.0.8"
}
Expand Down
23 changes: 15 additions & 8 deletions packages/storybook/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import ReactDOM from 'react-dom/client';
import App from './App'; // Ensure this is the correct path, and typically you don't include the file extension
import { BrowserRouter } from 'react-router-dom';

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
const rootElement = document.getElementById('root');

if (rootElement) {
const root = ReactDOM.createRoot(rootElement);
root.render(
<BrowserRouter>
<App />
</BrowserRouter>,
);
} else {
console.error('Failed to find the root element');
}
25 changes: 25 additions & 0 deletions packages/storybook/src/stories/Header/Header.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Header, HeaderProps } from '../../../../frontend-design-poc/src/components/Header/Header';
import { Meta, StoryObj } from '@storybook/react';
import { withRouter } from 'storybook-addon-react-router-v6';

export default {
title: 'Components/Header',
component: Header,
decorators: [withRouter],
parameters: {
layout: 'fullscreen',
},
} as Meta<HeaderProps>;

export const Default: StoryObj<HeaderProps> = {
args: {
name: 'Ola Nordmann',
},
};

export const WithCompanyName: StoryObj<HeaderProps> = {
args: {
name: 'Ola Nordmann',
companyName: 'Aker Solutions AS',
},
};
Loading

0 comments on commit 038ad22

Please sign in to comment.