-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Altinn/chore/setup_project
feat: setup project with components: Layout, Header, Toolbar, Menu and Avatar
- Loading branch information
Showing
125 changed files
with
11,674 additions
and
0 deletions.
There are no files selected for viewing
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 |
---|---|---|
|
@@ -396,3 +396,9 @@ FodyWeavers.xsd | |
|
||
# JetBrains Rider | ||
*.sln.iml | ||
|
||
*storybook.log | ||
|
||
.idea/ | ||
dist/ | ||
**/.DS_Store |
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 {StorybookConfig} from "@storybook/react-vite"; | ||
|
||
const config: StorybookConfig = { | ||
stories: [ | ||
"../lib/components/**/*.stories.@(ts|tsx)", | ||
], | ||
addons: [ | ||
"@storybook/addon-onboarding", | ||
"@storybook/addon-links", | ||
"@storybook/addon-essentials", | ||
"@chromatic-com/storybook", | ||
"@storybook/addon-interactions", | ||
], | ||
framework: { | ||
name: "@storybook/react-vite", | ||
options: {}, | ||
}, | ||
docs: { | ||
autodocs: "tag", | ||
}, | ||
}; | ||
export default config; |
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,15 @@ | ||
import "../lib/css/global.css"; | ||
|
||
/** @type { import('@storybook/react').Preview } */ | ||
const preview = { | ||
parameters: { | ||
controls: { | ||
matchers: { | ||
color: /(background|color)$/i, | ||
date: /Date$/i, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
export default preview; |
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,65 @@ | ||
{ | ||
"$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", | ||
"vcs": { | ||
"enabled": true, | ||
"clientKind": "git", | ||
"defaultBranch": "main" | ||
}, | ||
"organizeImports": { | ||
"enabled": true | ||
}, | ||
"formatter": { | ||
"formatWithErrors": true, | ||
"enabled": true, | ||
"lineWidth": 120, | ||
"lineEnding": "lf", | ||
"ignore": [], | ||
"indentStyle": "space", | ||
"indentWidth": 2 | ||
}, | ||
"javascript": { | ||
"formatter": { | ||
"arrowParentheses": "always", | ||
"quoteStyle": "single", | ||
"jsxQuoteStyle": "double", | ||
"semicolons": "always", | ||
"trailingCommas": "all", | ||
"quoteProperties": "asNeeded", | ||
"bracketSpacing": true, | ||
"bracketSameLine": false | ||
} | ||
}, | ||
"css": { | ||
"parser": { | ||
"cssModules": true | ||
}, | ||
"formatter": { | ||
"enabled": true, | ||
"indentStyle": "space", | ||
"indentWidth": 2 | ||
}, | ||
"linter": { | ||
"enabled": true | ||
} | ||
}, | ||
"linter": { | ||
"enabled": true, | ||
"rules": { | ||
"suspicious": { | ||
"noArrayIndexKey": "off" | ||
}, | ||
"recommended": true, | ||
"style": { | ||
"noUnusedTemplateLiteral": "off", | ||
"noNonNullAssertion": "off", | ||
"useTemplate": "off" | ||
}, | ||
"correctness": { | ||
"useExhaustiveDependencies": "warn" | ||
} | ||
} | ||
}, | ||
"files": { | ||
"ignore": [".github", "node_modules", "dist", "build", ".storybook"] | ||
} | ||
} |
Binary file not shown.
Binary file not shown.
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,100 @@ | ||
"use client"; | ||
import cx from "classnames"; | ||
import { useState } from "react"; | ||
import { fromStringToColor } from "./color"; | ||
import styles from "./avatar.module.css"; | ||
|
||
export type AvatarType = "company" | "person" | "custom"; | ||
export type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl"; | ||
export type AvatarVariant = "square" | "circle"; | ||
export type AvatarColor = "dark" | "light"; | ||
|
||
/** | ||
* Props for the Avatar component. | ||
*/ | ||
export interface AvatarProps { | ||
/** The name to display in the avatar. */ | ||
name: string; | ||
/** The type of avatar. */ | ||
type?: AvatarType; | ||
/** The size of the avatar. */ | ||
size?: AvatarSize; | ||
/** The variant of the avatar shape. */ | ||
variant?: AvatarVariant; | ||
/** The color theme of the avatar. */ | ||
color?: AvatarColor; | ||
/** Additional class names to apply to the avatar. */ | ||
className?: string; | ||
/** URL of the image to display in the avatar. */ | ||
imageUrl?: string; | ||
/** Alt text for the image. */ | ||
imageUrlAlt?: string; | ||
/** Whether to display an outline around the avatar. */ | ||
outline?: boolean; | ||
/** Custom label to display inside the avatar. */ | ||
customLabel?: string; | ||
} | ||
|
||
/** | ||
* Avatar component to display user or company avatars with various customization options. | ||
*/ | ||
export const Avatar = ({ | ||
type, | ||
size = "sm", | ||
variant, | ||
color, | ||
name = "Avatar", | ||
outline = false, | ||
imageUrl, | ||
imageUrlAlt, | ||
customLabel, | ||
className, | ||
}: AvatarProps): JSX.Element => { | ||
const [hasImageError, setHasImageError] = useState<boolean>(false); | ||
|
||
const defaultVariant = type === "person" ? "circle" : "square"; | ||
const defaultColor = type === "person" ? "light" : "dark"; | ||
const appliedVariant = variant || defaultVariant; | ||
const appliedColor = color || defaultColor; | ||
|
||
const { backgroundColor, foregroundColor } = fromStringToColor( | ||
name, | ||
appliedColor | ||
); | ||
const initials = (name[0] ?? "").toUpperCase(); | ||
const usingImageUrl = imageUrl && !hasImageError; | ||
|
||
const inlineStyles = !usingImageUrl | ||
? { | ||
backgroundColor, | ||
color: foregroundColor, | ||
} | ||
: undefined; | ||
|
||
return ( | ||
<div | ||
className={cx( | ||
styles.avatar, | ||
styles[appliedVariant], | ||
styles[size], | ||
{ [styles.outline]: outline }, | ||
className | ||
)} | ||
style={inlineStyles} | ||
aria-hidden | ||
> | ||
{usingImageUrl ? ( | ||
<img | ||
src={imageUrl} | ||
className={styles.image} | ||
alt={imageUrlAlt || imageUrl} | ||
onError={() => { | ||
setHasImageError(true); | ||
}} | ||
/> | ||
) : ( | ||
<span>{customLabel || initials}</span> | ||
)} | ||
</div> | ||
); | ||
}; |
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,67 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import { fn } from "@storybook/test"; | ||
import { AvatarGroup } from "./AvatarGroup"; | ||
|
||
const meta = { | ||
title: "Avatar/AvatarGroup", | ||
component: AvatarGroup, | ||
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs | ||
tags: ["autodocs"], | ||
parameters: { | ||
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout | ||
// layout: 'fullscreen', | ||
}, | ||
args: {}, | ||
} satisfies Meta<typeof AvatarGroup>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
export const People: Story = { | ||
args: { | ||
type: "person", | ||
items: [ | ||
{ | ||
name: "Albert Åberg", | ||
}, | ||
{ | ||
name: "Birger Meling", | ||
}, | ||
{ | ||
name: "Celine Dion", | ||
}, | ||
], | ||
}, | ||
}; | ||
|
||
export const Companies: Story = { | ||
args: { | ||
type: "company", | ||
items: [ | ||
{ | ||
name: "Albert Åberg", | ||
}, | ||
{ | ||
name: "Birger Meling", | ||
}, | ||
{ | ||
name: "Celine Dion", | ||
}, | ||
], | ||
}, | ||
}; | ||
|
||
export const CompanyAndPerson: Story = { | ||
args: { | ||
items: [ | ||
{ | ||
type: "company", | ||
name: "Albert Åberg", | ||
}, | ||
{ | ||
type: "person", | ||
name: "Birger Meling", | ||
}, | ||
], | ||
}, | ||
}; |
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,42 @@ | ||
import cx from 'classnames'; | ||
import {Avatar, type AvatarProps, type AvatarSize, type AvatarType} from '.'; | ||
import styles from './avatarGroup.module.css'; | ||
import {useMemo} from 'react'; | ||
|
||
export interface AvatarGroupProps { | ||
items?: AvatarProps[]; | ||
maxItemsCount?: number; | ||
type?: AvatarType; | ||
size?: AvatarSize; | ||
className?: string; | ||
} | ||
|
||
export const AvatarGroup = ({ items = [], maxItemsCount = 4, type, size = 'sm', className }: AvatarGroupProps) => { | ||
const maxItems = useMemo(() => items.slice(0, maxItemsCount), [items, maxItemsCount]); | ||
|
||
if (items?.length === 0) { | ||
return <div className={styles.avatarGroup} />; | ||
} | ||
|
||
return ( | ||
<ul className={cx(styles.reset, styles.group, styles[size], className)} data-count={maxItems?.length}> | ||
{maxItems.map((avatar, index) => { | ||
const lastLegalAvatarReached = index === maxItemsCount - 1; | ||
const customLabel = avatar.customLabel || lastLegalAvatarReached ? items.length.toString() : undefined; | ||
return ( | ||
<li className={cx(styles.reset, styles.item)} key={avatar.name}> | ||
<Avatar | ||
name={avatar.name} | ||
customLabel={customLabel} | ||
imageUrl={avatar.imageUrl} | ||
imageUrlAlt={avatar.imageUrlAlt} | ||
type={avatar?.type || type} | ||
size={size} | ||
outline | ||
/> | ||
</li> | ||
); | ||
})} | ||
</ul> | ||
); | ||
}; |
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,59 @@ | ||
.avatar { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
overflow: hidden; | ||
--avatar-font-size-xs: 0.75rem; | ||
--avatar-font-size-sm: 0.875rem; | ||
--avatar-font-size-md: 1.125rem; | ||
--avatar-font-size-lg: 1.25rem; | ||
--avatar-font-size-xl: 1.5rem; | ||
} | ||
|
||
.circle { | ||
border-radius: 50%; | ||
} | ||
|
||
.square { | ||
border-radius: 5%; | ||
} | ||
|
||
.outline { | ||
outline: 1px solid #ffffff; | ||
box-sizing: border-box; | ||
} | ||
|
||
.xs { | ||
font-size: var(--avatar-font-size-xs); | ||
width: 20px; | ||
height: 20px; | ||
} | ||
|
||
.sm { | ||
font-size: var(--avatar-font-size-sm); | ||
width: 24px; | ||
height: 24px; | ||
} | ||
|
||
.md { | ||
font-size: var(--avatar-font-size-md); | ||
width: 30px; | ||
height: 30px; | ||
} | ||
|
||
.lg { | ||
font-size: var(--avatar-font-size-lg); | ||
width: 36px; | ||
height: 36px; | ||
} | ||
|
||
.xl { | ||
font-size: var(--avatar-font-size-xl); | ||
width: 44px; | ||
height: 44px; | ||
} | ||
|
||
.image { | ||
width: 100%; | ||
height: 100%; | ||
} |
Oops, something went wrong.