@altinn/altinn-components 0.0.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.storybook/StoryDecorator.tsx +27 -0
- package/.storybook/ThemeProvider.tsx +16 -0
- package/.storybook/main.ts +4 -5
- package/.storybook/preview.tsx +35 -0
- package/.storybook/storyDecorator.module.css +20 -0
- package/.storybook/theme.module.css +3 -0
- package/CHANGELOG.md +21 -0
- package/CONTRIBUTING.MD +59 -0
- package/README.md +33 -1
- package/lib/components/Attachment/AttachmentLink.stories.ts +21 -0
- package/lib/components/Attachment/AttachmentLink.tsx +20 -0
- package/lib/components/Attachment/AttachmentList.stories.ts +39 -0
- package/lib/components/Attachment/AttachmentList.tsx +26 -0
- package/lib/components/Attachment/attachmentLink.module.css +20 -0
- package/lib/components/Attachment/attachmentList.module.css +12 -0
- package/lib/components/Attachment/index.ts +2 -0
- package/lib/components/Avatar/Avatar.tsx +8 -16
- package/lib/components/Avatar/AvatarGroup.stories.ts +3 -4
- package/lib/components/Avatar/AvatarGroup.tsx +20 -3
- package/lib/components/Avatar/avatar.module.css +2 -0
- package/lib/components/Avatar/avatar.stories.tsx +1 -6
- package/lib/components/Badge/Badge.stories.ts +32 -0
- package/lib/components/Badge/Badge.tsx +13 -10
- package/lib/components/Badge/badge.module.css +18 -27
- package/lib/components/Button/Button.stories.ts +6 -0
- package/lib/components/Button/Button.tsx +19 -1
- package/lib/components/Button/ButtonBase.tsx +1 -1
- package/lib/components/Button/button.module.css +0 -19
- package/lib/components/Button/buttonBase.module.css +30 -12
- package/lib/components/Button/comboButton.module.css +4 -2
- package/lib/components/ContextMenu/ContextMenu.tsx +28 -0
- package/lib/components/ContextMenu/contextMenu.module.css +35 -0
- package/lib/components/Dialog/Dialog.stories.ts +320 -0
- package/lib/components/Dialog/Dialog.tsx +101 -0
- package/lib/components/Dialog/DialogAction.stories.ts +54 -0
- package/lib/components/Dialog/DialogAction.tsx +79 -0
- package/lib/components/Dialog/DialogActivityLog.tsx +18 -0
- package/lib/components/Dialog/DialogArticleBase.tsx +10 -0
- package/lib/components/Dialog/DialogAttachments.stories.ts +40 -0
- package/lib/components/Dialog/DialogAttachments.tsx +25 -0
- package/lib/components/Dialog/DialogBase.tsx +10 -0
- package/lib/components/Dialog/DialogBodyBase.tsx +17 -0
- package/lib/components/Dialog/DialogBorder.tsx +19 -0
- package/lib/components/Dialog/DialogContent.stories.ts +26 -0
- package/lib/components/Dialog/DialogContent.tsx +24 -0
- package/lib/components/Dialog/DialogFooter.tsx +14 -0
- package/lib/components/Dialog/DialogHeader.stories.ts +26 -0
- package/lib/components/Dialog/DialogHeader.tsx +23 -0
- package/lib/components/Dialog/DialogHeaderBase.tsx +10 -0
- package/lib/components/Dialog/DialogHeadings.stories.ts +35 -0
- package/lib/components/Dialog/DialogHeadings.tsx +77 -0
- package/lib/components/Dialog/DialogHistory.stories.ts +67 -0
- package/lib/components/Dialog/DialogHistory.tsx +19 -0
- package/lib/components/Dialog/DialogList.stories.ts +61 -0
- package/lib/components/Dialog/DialogList.tsx +20 -0
- package/lib/components/Dialog/DialogListItem.stories.tsx +238 -0
- package/lib/components/Dialog/DialogListItem.tsx +114 -0
- package/lib/components/Dialog/DialogListItemBase.tsx +50 -0
- package/lib/components/Dialog/DialogMetadata.stories.ts +77 -0
- package/lib/components/Dialog/DialogMetadata.tsx +56 -0
- package/lib/components/Dialog/DialogNav.stories.ts +90 -0
- package/lib/components/Dialog/DialogNav.tsx +60 -0
- package/lib/components/Dialog/DialogSectionBase.tsx +20 -0
- package/lib/components/Dialog/DialogSeenBy.stories.tsx +58 -0
- package/lib/components/Dialog/DialogSeenBy.tsx +36 -0
- package/lib/components/Dialog/DialogSelect.tsx +23 -0
- package/lib/components/Dialog/DialogStatus.stories.ts +57 -0
- package/lib/components/Dialog/DialogStatus.tsx +61 -0
- package/lib/components/Dialog/DialogTitle.stories.ts +33 -0
- package/lib/components/Dialog/DialogTitle.tsx +31 -0
- package/lib/components/Dialog/DialogTouchedBy.stories.tsx +27 -0
- package/lib/components/Dialog/DialogTouchedBy.tsx +19 -0
- package/lib/components/Dialog/dialog.module.css +21 -0
- package/lib/components/Dialog/dialogAction.module.css +26 -0
- package/lib/components/Dialog/dialogArticleBase.module.css +5 -0
- package/lib/components/Dialog/dialogBodyBase.module.css +13 -0
- package/lib/components/Dialog/dialogBorder.module.css +42 -0
- package/lib/components/Dialog/dialogHeaderBase.module.css +6 -0
- package/lib/components/Dialog/dialogHeadings.module.css +24 -0
- package/lib/components/Dialog/dialogHistory.module.css +12 -0
- package/lib/components/Dialog/dialogListItem.module.css +81 -0
- package/lib/components/Dialog/dialogListItemBase.module.css +28 -0
- package/lib/components/Dialog/dialogSectionBase.module.css +11 -0
- package/lib/components/Dialog/dialogSelect.module.css +34 -0
- package/lib/components/Dialog/dialogTitle.module.css +47 -0
- package/lib/components/Dialog/index.ts +2 -0
- package/lib/components/Header/GlobalMenu.tsx +1 -1
- package/lib/components/Header/Header.tsx +3 -3
- package/lib/components/Header/HeaderSearch.tsx +1 -1
- package/lib/components/History/HistoryBorder.tsx +17 -0
- package/lib/components/History/HistoryItem.stories.ts +47 -0
- package/lib/components/History/HistoryItem.tsx +64 -0
- package/lib/components/History/HistoryList.stories.ts +58 -0
- package/lib/components/History/HistoryList.tsx +26 -0
- package/lib/components/History/historyBorder.module.css +8 -0
- package/lib/components/History/historyItem.module.css +19 -0
- package/lib/components/History/historyList.module.css +12 -0
- package/lib/components/History/index.ts +2 -0
- package/lib/components/Icon/CheckboxCheckedIcon.tsx +28 -0
- package/lib/components/Icon/CheckboxIcon.stories.ts +7 -0
- package/lib/components/Icon/CheckboxIcon.tsx +6 -18
- package/lib/components/Icon/CheckboxUncheckedIcon.tsx +38 -0
- package/lib/components/Icon/ProgressIcon.stories.ts +43 -0
- package/lib/components/Icon/ProgressIcon.tsx +44 -0
- package/lib/components/Icon/RadioCheckedIcon.tsx +29 -0
- package/lib/components/Icon/RadioIcon.stories.ts +7 -0
- package/lib/components/Icon/RadioIcon.tsx +7 -19
- package/lib/components/Icon/RadioUncheckedIcon.tsx +30 -0
- package/lib/components/Icon/checkboxIcon.module.css +2 -0
- package/lib/components/Icon/index.ts +1 -0
- package/lib/components/Icon/progressIcon.module.css +29 -0
- package/lib/components/Layout/Layout.stories.ts +0 -3
- package/lib/components/List/List.tsx +20 -0
- package/lib/components/List/ListBase.tsx +19 -0
- package/lib/components/List/ListItem.stories.tsx +208 -0
- package/lib/components/List/ListItem.tsx +70 -0
- package/lib/components/List/ListItemBase.tsx +62 -0
- package/lib/components/List/ListItemLabel.tsx +29 -0
- package/lib/components/List/ListItemMedia.tsx +59 -0
- package/lib/components/List/index.ts +4 -0
- package/lib/components/List/listBase.module.css +16 -0
- package/lib/components/List/listItemBase.module.css +86 -0
- package/lib/components/List/listItemLabel.module.css +55 -0
- package/lib/components/List/listItemMedia.module.css +41 -0
- package/lib/components/Menu/Menu.stories.ts +46 -27
- package/lib/components/Menu/Menu.tsx +3 -3
- package/lib/components/Menu/MenuItem.stories.ts +12 -7
- package/lib/components/Menu/MenuItem.tsx +4 -3
- package/lib/components/Menu/MenuItemBase.tsx +7 -7
- package/lib/components/Menu/MenuItemLabel.tsx +4 -4
- package/lib/components/Menu/MenuItemMedia.tsx +2 -2
- package/lib/components/Menu/MenuOption.stories.ts +4 -2
- package/lib/components/Menu/MenuOption.tsx +4 -4
- package/lib/components/Menu/menuItemBase.module.css +72 -0
- package/lib/components/Menu/menuItemLabel.module.css +22 -0
- package/lib/components/Menu/menuItemMedia.module.css +36 -0
- package/lib/components/Menu/menuOption.module.css +6 -8
- package/lib/components/Meta/MetaBase.tsx +15 -0
- package/lib/components/Meta/MetaItem.stories.ts +25 -0
- package/lib/components/Meta/MetaItem.tsx +31 -0
- package/lib/components/Meta/MetaItemBase.tsx +46 -0
- package/lib/components/Meta/MetaItemLabel.tsx +20 -0
- package/lib/components/Meta/MetaItemMedia.tsx +22 -0
- package/lib/components/Meta/MetaList.stories.ts +29 -0
- package/lib/components/Meta/MetaList.tsx +43 -0
- package/lib/components/Meta/MetaProgress.stories.ts +29 -0
- package/lib/components/Meta/MetaProgress.tsx +26 -0
- package/lib/components/Meta/MetaTimestamp.stories.ts +33 -0
- package/lib/components/Meta/MetaTimestamp.tsx +29 -0
- package/lib/components/Meta/index.ts +6 -0
- package/lib/components/Meta/meta.module.css +6 -0
- package/lib/components/Meta/metaItem.module.css +107 -0
- package/lib/components/Meta/metaList.module.css +15 -0
- package/lib/components/Toolbar/ToolbarAdd.tsx +1 -1
- package/lib/components/Typography/Typography.tsx +21 -0
- package/lib/components/Typography/index.ts +1 -0
- package/lib/components/Typography/typography.module.css +56 -0
- package/lib/components/index.ts +9 -0
- package/lib/css/global.css +2 -0
- package/lib/css/shadows.css +7 -0
- package/lib/css/theme-article.css +15 -0
- package/lib/css/theme.css +5 -7
- package/package.json +4 -2
- package/renovate.json +4 -0
- package/.storybook/preview.ts +0 -15
- /package/lib/components/Toolbar/{index.js → index.ts} +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import styles from "./storyDecorator.module.css";
|
|
3
|
+
|
|
4
|
+
interface StoryDecoratorProps {
|
|
5
|
+
tags: string[];
|
|
6
|
+
theme: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const StoryDecorator = ({
|
|
11
|
+
tags,
|
|
12
|
+
theme,
|
|
13
|
+
children,
|
|
14
|
+
}: StoryDecoratorProps) => {
|
|
15
|
+
const isStable = (tags || []).includes("stable");
|
|
16
|
+
const state = isStable ? "stable" : "experimental";
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className={styles.preview} data-theme={theme}>
|
|
20
|
+
<span className={styles.tag} data-tag={state}>
|
|
21
|
+
{state}
|
|
22
|
+
</span>
|
|
23
|
+
|
|
24
|
+
<div className={styles.component}>{children}</div>
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import styles from "./theme.module.css";
|
|
3
|
+
|
|
4
|
+
export const ThemeProvider = <Theme,>({
|
|
5
|
+
children,
|
|
6
|
+
theme,
|
|
7
|
+
}: {
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
theme?: Theme;
|
|
10
|
+
}) => {
|
|
11
|
+
return (
|
|
12
|
+
<div className={styles.theme} data-theme={theme}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
};
|
package/.storybook/main.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import {StorybookConfig} from "@storybook/react-vite";
|
|
1
|
+
import { StorybookConfig } from "@storybook/react-vite";
|
|
2
2
|
|
|
3
3
|
const config: StorybookConfig = {
|
|
4
|
-
stories: [
|
|
5
|
-
"../lib/components/**/*.stories.@(ts|tsx)",
|
|
6
|
-
],
|
|
4
|
+
stories: ["../lib/components/**/*.stories.@(ts|tsx)"],
|
|
7
5
|
addons: [
|
|
8
6
|
"@storybook/addon-onboarding",
|
|
9
7
|
"@storybook/addon-links",
|
|
10
8
|
"@storybook/addon-essentials",
|
|
9
|
+
"@storybook/addon-themes",
|
|
11
10
|
"@chromatic-com/storybook",
|
|
12
|
-
"@storybook/addon-interactions"
|
|
11
|
+
"@storybook/addon-interactions"
|
|
13
12
|
],
|
|
14
13
|
framework: {
|
|
15
14
|
name: "@storybook/react-vite",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { withThemeByDataAttribute } from "@storybook/addon-themes";
|
|
2
|
+
import { Preview, StoryFn } from "@storybook/react";
|
|
3
|
+
import { StoryDecorator } from "./StoryDecorator";
|
|
4
|
+
import "../lib/css/global.css";
|
|
5
|
+
/** @type { import('@storybook/react').Preview } */
|
|
6
|
+
const preview: Preview = {
|
|
7
|
+
parameters: {
|
|
8
|
+
controls: {
|
|
9
|
+
matchers: {
|
|
10
|
+
color: /(background|color)$/i,
|
|
11
|
+
date: /Date$/i,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
decorators: [
|
|
16
|
+
(Story: StoryFn, data) => {
|
|
17
|
+
const { tags, globals } = data;
|
|
18
|
+
return (
|
|
19
|
+
<StoryDecorator tags={tags} theme={globals?.theme}>
|
|
20
|
+
<Story />
|
|
21
|
+
</StoryDecorator>
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
withThemeByDataAttribute({
|
|
25
|
+
themes: {
|
|
26
|
+
global: "global",
|
|
27
|
+
neutral: "neutral",
|
|
28
|
+
company: "company",
|
|
29
|
+
person: "person",
|
|
30
|
+
},
|
|
31
|
+
defaultTheme: "neutral",
|
|
32
|
+
}),
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
export default preview;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.preview {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
row-gap: 1rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.tag {
|
|
8
|
+
font-size: 1rem;
|
|
9
|
+
color: #fff;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.tag[data-tag="experimental"] {
|
|
13
|
+
background-color: #f0ad4e;
|
|
14
|
+
padding: 0.25rem 0.5rem;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.tag[data-tag="stable"] {
|
|
18
|
+
background-color: #5cb85c;
|
|
19
|
+
padding: 0.25rem 0.5rem;
|
|
20
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0](https://github.com/Altinn/altinn-components/compare/v0.1.0...v0.2.0) (2024-11-06)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add dialogs as experimental ([#24](https://github.com/Altinn/altinn-components/issues/24)) ([12b3e4d](https://github.com/Altinn/altinn-components/commit/12b3e4dc81c236eff5a5ab0364b3a7e992606c3a))
|
|
9
|
+
* add meta fields ([#23](https://github.com/Altinn/altinn-components/issues/23)) ([ea8ef87](https://github.com/Altinn/altinn-components/commit/ea8ef87ca03c089e52a331ab62526be2b5acc089))
|
|
10
|
+
* list item + meta tags ([#17](https://github.com/Altinn/altinn-components/issues/17)) ([f865f6c](https://github.com/Altinn/altinn-components/commit/f865f6c226e8f7ce9d4ce18c0014fb4e1c9d0383))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* icons for checkbox and radio ([#25](https://github.com/Altinn/altinn-components/issues/25)) ([fb796e2](https://github.com/Altinn/altinn-components/commit/fb796e25636ec0b27ff643a3036ea25171202a11))
|
|
16
|
+
|
|
17
|
+
## [0.1.0](https://github.com/Altinn/altinn-components/compare/v0.0.1...v0.1.0) (2024-11-01)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* mark Avatar and AvatarGroup as stable ([#14](https://github.com/Altinn/altinn-components/issues/14)) ([fd8bbce](https://github.com/Altinn/altinn-components/commit/fd8bbce2ce59954d8682527b1a9d70bd08b9ccd7))
|
|
23
|
+
|
|
3
24
|
## 0.0.1 (2024-10-31)
|
|
4
25
|
|
|
5
26
|
|
package/CONTRIBUTING.MD
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Contributing to altinn-components
|
|
2
|
+
|
|
3
|
+
Thank you for contributing to altinn 3 components!
|
|
4
|
+
|
|
5
|
+
This project is a collection of reusable components for building web applications for [Altinn 3](https://docs.altinn.studio/nb/community/about/), and not a general-purpose library.
|
|
6
|
+
If you are looking for a more general-purpose library, you might be looking for [Norwegian public sector's Design system](https://designsystemet.no/).
|
|
7
|
+
|
|
8
|
+
We appreciate your help in making this project better, and keep in mind that the project is in an early development stage, and we are actively working to improve both the documentation and the codebase.
|
|
9
|
+
|
|
10
|
+
## Share your feedback and report issues
|
|
11
|
+
|
|
12
|
+
You can report bugs or suggest new features by going to our [Github Issue Templates](https://github.com/Altinn/altinn-components/issues/new/choose).
|
|
13
|
+
We also welcome questions and feedback.
|
|
14
|
+
|
|
15
|
+
## I Want To Contribute
|
|
16
|
+
|
|
17
|
+
### Getting started with development
|
|
18
|
+
Follow these steps to set up Storybook and the necessary tools for development.
|
|
19
|
+
|
|
20
|
+
#### Prerequisites for local development and storybook
|
|
21
|
+
|
|
22
|
+
- The project uses `pnpm` as package manager. It is recommended to use install and use correct version of `pnpm` by using `corepack`, cf. [Using corepack section](https://pnpm.io/installation).
|
|
23
|
+
- Install dependencies with `pnpm install`
|
|
24
|
+
- Required node version is `20.x` or higher.
|
|
25
|
+
|
|
26
|
+
#### Storybook
|
|
27
|
+
Run storybook with `pnpm storybook` and navigate to `http://localhost:6006/` in your browser.
|
|
28
|
+
|
|
29
|
+
### Pull requests
|
|
30
|
+
A lot has been written already about how to write good pull requests. [Here are some](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/getting-started/best-practices-for-pull-requests) tips to make the process smoother.
|
|
31
|
+
|
|
32
|
+
## Style guides
|
|
33
|
+
|
|
34
|
+
### Code Style
|
|
35
|
+
This project uses [`Biome`](https://biomejs.dev/) for linting and formatting. The configuration is found in the `biome.jsonc` file.
|
|
36
|
+
We recommend using the `biome` CLI to lint and format your code before committing, or using the `biome` extension in your IDE.
|
|
37
|
+
|
|
38
|
+
Use `pnpm format` to format staged files.
|
|
39
|
+
|
|
40
|
+
### Commit Messages
|
|
41
|
+
|
|
42
|
+
This project uses Changesets with the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
43
|
+
specification in order to generate changelogs, communicating the nature of changes.
|
|
44
|
+
|
|
45
|
+
To include commits in the changelog, please ensure that you include the following keywords:
|
|
46
|
+
|
|
47
|
+
- Start the commit with `fix:` to trigger a patch (0.0.x) version.
|
|
48
|
+
- Start the commit with `feat:` to trigger a minor (0.x.0) version.
|
|
49
|
+
|
|
50
|
+
Other keywords are also supported, but will not trigger a version bump. These keywords include:
|
|
51
|
+
- `chore:` for changes that do not affect the end user, such as refactoring or updating dependencies.
|
|
52
|
+
- `docs:` for changes to the documentation.
|
|
53
|
+
- `refactor:` for changes that neither fixes a bug nor adds a feature. but improves the codebase.
|
|
54
|
+
|
|
55
|
+
To make the changelog more specific, you have the option to scope your commits by adding a keyword in parentheses that indicates the area or aspect you are working on.
|
|
56
|
+
For example:
|
|
57
|
+
- Modifying documentation for contributing: `docs(contributing): add a section on commit messages`.
|
|
58
|
+
- Fixing a bug in the Avatar component: `fix(avatar): fix bug with incorrect image size`.
|
|
59
|
+
|
package/README.md
CHANGED
|
@@ -1,2 +1,34 @@
|
|
|
1
1
|
# altinn-components
|
|
2
|
-
|
|
2
|
+
This package is a set of reusable components for building web applications for [Altinn 3](https://docs.altinn.studio/nb/community/about/).
|
|
3
|
+
This is *not* a general purpose library, but a library of components that are specifically designed for the Altinn platform, to ensure
|
|
4
|
+
a consistent look and feel across all applications. It also contains a storybook with stories explaining the purpose and usage of each component, and
|
|
5
|
+
with real examples of how to use them separately or together (composition).
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
To install the package, run the following command:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# for npm users
|
|
12
|
+
npm install @altinn/components
|
|
13
|
+
# for yarn users
|
|
14
|
+
yarn add @altinn/components
|
|
15
|
+
# for pnpm users
|
|
16
|
+
pnpm add @altinn/components
|
|
17
|
+
```
|
|
18
|
+
Tested with Node.js 20.x <
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
To use the components in your application, you need to import the components you want to use from the package. For example:
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
// example: import the Avatar component and type
|
|
25
|
+
import { Avatar, type AvatarVariant } from '@altinn/components';
|
|
26
|
+
```
|
|
27
|
+
and import the css file in your application once:
|
|
28
|
+
```ts
|
|
29
|
+
import '@altinn/components/dist/index.css';
|
|
30
|
+
```
|
|
31
|
+
for correct `font-family` and minimal collection of resets.
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
The documentation for the components can be found in the storybook, cf. [TODO ADD Storybook]()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { fn } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
import { AttachmentLink } from './AttachmentLink';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Attachment/AttachmentLink',
|
|
8
|
+
component: AttachmentLink,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {},
|
|
11
|
+
args: {
|
|
12
|
+
label: 'Document.pdf',
|
|
13
|
+
},
|
|
14
|
+
} satisfies Meta<typeof AttachmentLink>;
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof meta>;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {},
|
|
21
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Icon, type IconName } from '../Icon';
|
|
2
|
+
import styles from './attachmentLink.module.css';
|
|
3
|
+
|
|
4
|
+
export interface AttachmentLinkProps {
|
|
5
|
+
/** Link url */
|
|
6
|
+
href: string;
|
|
7
|
+
/** Label (filename) */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Icon */
|
|
10
|
+
icon?: IconName;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const AttachmentLink = ({ icon = 'file', href, label }: AttachmentLinkProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<a href={href} className={styles.link}>
|
|
16
|
+
<Icon name={icon} className={styles.icon} />
|
|
17
|
+
<span className={styles.label}>{label}</span>
|
|
18
|
+
</a>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { fn } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
import { AttachmentList } from './AttachmentList';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Attachment/AttachmentList',
|
|
8
|
+
component: AttachmentList,
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'fullscreen',
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
items: [
|
|
15
|
+
{
|
|
16
|
+
label: '1-0 Castro.pdf',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: '2-0 Kornvig.pdf',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: '3-0 Kartum.pdf',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: '3-1 Zinkernagel.pdf',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: '4-1 Castro.pdf',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
} satisfies Meta<typeof AttachmentList>;
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
type Story = StoryObj<typeof meta>;
|
|
36
|
+
|
|
37
|
+
export const Default: Story = {
|
|
38
|
+
args: {},
|
|
39
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TypographySize } from '../Typography';
|
|
2
|
+
import { AttachmentLink, type AttachmentLinkProps } from './AttachmentLink';
|
|
3
|
+
import styles from './attachmentList.module.css';
|
|
4
|
+
|
|
5
|
+
export interface AttachmentListProps {
|
|
6
|
+
items: AttachmentLinkProps[];
|
|
7
|
+
size?: TypographySize;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const AttachmentList = ({ size, items }: AttachmentListProps) => {
|
|
11
|
+
if (!items.length) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<ul className={styles.list} data-size={size}>
|
|
17
|
+
{items.map((item, index) => {
|
|
18
|
+
return (
|
|
19
|
+
<li key={index} className={styles.item}>
|
|
20
|
+
<AttachmentLink {...item} key={'attachment' + index} />
|
|
21
|
+
</li>
|
|
22
|
+
);
|
|
23
|
+
})}
|
|
24
|
+
</ul>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.link {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: start;
|
|
4
|
+
column-gap: 0.25em;
|
|
5
|
+
color: var(--theme-base-default);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.link:hover {
|
|
9
|
+
color: var(--theme-base-hover);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.label {
|
|
13
|
+
text-decoration: underline;
|
|
14
|
+
text-decoration-thickness: 2px;
|
|
15
|
+
text-underline-offset: 2px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.icon {
|
|
19
|
+
font-size: 1.5em;
|
|
20
|
+
}
|
|
@@ -6,8 +6,9 @@ import { fromStringToColor } from './color';
|
|
|
6
6
|
|
|
7
7
|
export type AvatarType = 'company' | 'person' | 'custom';
|
|
8
8
|
export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
type AvatarVariant = 'square' | 'circle';
|
|
11
|
+
type AvatarColor = 'dark' | 'light';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Props for the Avatar component.
|
|
@@ -19,10 +20,6 @@ export interface AvatarProps {
|
|
|
19
20
|
type?: AvatarType;
|
|
20
21
|
/** The size of the avatar. */
|
|
21
22
|
size?: AvatarSize;
|
|
22
|
-
/** The variant of the avatar shape. */
|
|
23
|
-
variant?: AvatarVariant;
|
|
24
|
-
/** The color theme of the avatar. */
|
|
25
|
-
color?: AvatarColor;
|
|
26
23
|
/** Additional class names to apply to the avatar. */
|
|
27
24
|
className?: string;
|
|
28
25
|
/** URL of the image to display in the avatar. */
|
|
@@ -39,10 +36,8 @@ export interface AvatarProps {
|
|
|
39
36
|
* Avatar component to display user or company avatars with various customization options.
|
|
40
37
|
*/
|
|
41
38
|
export const Avatar = ({
|
|
42
|
-
type,
|
|
39
|
+
type = 'person',
|
|
43
40
|
size = 'sm',
|
|
44
|
-
variant,
|
|
45
|
-
color,
|
|
46
41
|
name = 'Avatar',
|
|
47
42
|
outline = false,
|
|
48
43
|
imageUrl,
|
|
@@ -51,13 +46,10 @@ export const Avatar = ({
|
|
|
51
46
|
className,
|
|
52
47
|
}: AvatarProps): JSX.Element => {
|
|
53
48
|
const [hasImageError, setHasImageError] = useState<boolean>(false);
|
|
49
|
+
const variant: AvatarVariant = type === 'person' ? 'circle' : 'square';
|
|
50
|
+
const color: AvatarColor = type === 'person' ? 'light' : 'dark';
|
|
54
51
|
|
|
55
|
-
const
|
|
56
|
-
const defaultColor = type === 'person' ? 'light' : 'dark';
|
|
57
|
-
const appliedVariant = variant || defaultVariant;
|
|
58
|
-
const appliedColor = color || defaultColor;
|
|
59
|
-
|
|
60
|
-
const { backgroundColor, foregroundColor } = fromStringToColor(name, appliedColor);
|
|
52
|
+
const { backgroundColor, foregroundColor } = fromStringToColor(name, color);
|
|
61
53
|
const initials = (name[0] ?? '').toUpperCase();
|
|
62
54
|
const usingImageUrl = imageUrl && !hasImageError;
|
|
63
55
|
|
|
@@ -70,7 +62,7 @@ export const Avatar = ({
|
|
|
70
62
|
|
|
71
63
|
return (
|
|
72
64
|
<div
|
|
73
|
-
className={cx(styles.avatar, styles[
|
|
65
|
+
className={cx(styles.avatar, styles[variant], styles[size], { [styles.outline]: outline }, className)}
|
|
74
66
|
style={inlineStyles}
|
|
75
67
|
aria-hidden
|
|
76
68
|
>
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { fn } from '@storybook/test';
|
|
3
2
|
import { AvatarGroup } from './AvatarGroup';
|
|
4
3
|
|
|
5
4
|
const meta = {
|
|
6
5
|
title: 'Avatar/AvatarGroup',
|
|
7
6
|
component: AvatarGroup,
|
|
8
7
|
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
|
|
9
|
-
tags: ['autodocs'],
|
|
8
|
+
tags: ['autodocs', 'stable'],
|
|
10
9
|
parameters: {
|
|
11
10
|
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
|
|
12
11
|
// layout: 'fullscreen',
|
|
@@ -19,7 +18,7 @@ type Story = StoryObj<typeof meta>;
|
|
|
19
18
|
|
|
20
19
|
export const People: Story = {
|
|
21
20
|
args: {
|
|
22
|
-
|
|
21
|
+
defaultType: 'person',
|
|
23
22
|
items: [
|
|
24
23
|
{
|
|
25
24
|
name: 'Albert Åberg',
|
|
@@ -36,7 +35,7 @@ export const People: Story = {
|
|
|
36
35
|
|
|
37
36
|
export const Companies: Story = {
|
|
38
37
|
args: {
|
|
39
|
-
|
|
38
|
+
defaultType: 'company',
|
|
40
39
|
items: [
|
|
41
40
|
{
|
|
42
41
|
name: 'Albert Åberg',
|
|
@@ -3,15 +3,32 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { Avatar, type AvatarProps, type AvatarSize, type AvatarType } from '.';
|
|
4
4
|
import styles from './avatarGroup.module.css';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Props for the AvatarGroup components.
|
|
8
|
+
*/
|
|
6
9
|
export interface AvatarGroupProps {
|
|
10
|
+
/** Array of avatars to display in the group, each specified by AvatarProps. */
|
|
7
11
|
items?: AvatarProps[];
|
|
12
|
+
/** Maximum number of avatars to show in the group. Remaining avatars are summarized in a "+X" label. */
|
|
8
13
|
maxItemsCount?: number;
|
|
9
|
-
type
|
|
14
|
+
/** Default avatar type to apply if not specified in individual items. This affects the styling. */
|
|
15
|
+
defaultType?: AvatarType;
|
|
16
|
+
/** Size of all avatars in the group (e.g., 'sm', 'md', 'lg'). */
|
|
10
17
|
size?: AvatarSize;
|
|
18
|
+
/** Additional CSS class for styling the avatar group container. */
|
|
11
19
|
className?: string;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Avatar group component for displaying multiple avatars as a group.
|
|
24
|
+
*/
|
|
25
|
+
export const AvatarGroup = ({
|
|
26
|
+
items = [],
|
|
27
|
+
maxItemsCount = 4,
|
|
28
|
+
defaultType,
|
|
29
|
+
size = 'sm',
|
|
30
|
+
className,
|
|
31
|
+
}: AvatarGroupProps) => {
|
|
15
32
|
const maxItems = useMemo(() => items.slice(0, maxItemsCount), [items, maxItemsCount]);
|
|
16
33
|
|
|
17
34
|
if (items?.length === 0) {
|
|
@@ -30,7 +47,7 @@ export const AvatarGroup = ({ items = [], maxItemsCount = 4, type, size = 'sm',
|
|
|
30
47
|
customLabel={customLabel}
|
|
31
48
|
imageUrl={avatar.imageUrl}
|
|
32
49
|
imageUrlAlt={avatar.imageUrlAlt}
|
|
33
|
-
type={avatar?.type ||
|
|
50
|
+
type={avatar?.type || defaultType}
|
|
34
51
|
size={size}
|
|
35
52
|
outline
|
|
36
53
|
/>
|
|
@@ -4,13 +4,11 @@ import { Avatar } from './';
|
|
|
4
4
|
const meta = {
|
|
5
5
|
title: 'Avatar/Avatar',
|
|
6
6
|
component: Avatar,
|
|
7
|
-
tags: ['autodocs'],
|
|
7
|
+
tags: ['autodocs', 'stable'],
|
|
8
8
|
parameters: {},
|
|
9
9
|
args: {
|
|
10
10
|
name: 'Jane Doe',
|
|
11
11
|
type: 'person',
|
|
12
|
-
variant: 'circle',
|
|
13
|
-
color: 'light',
|
|
14
12
|
size: 'xl',
|
|
15
13
|
},
|
|
16
14
|
} satisfies Meta<typeof Avatar>;
|
|
@@ -30,15 +28,12 @@ export const Company: Story = {
|
|
|
30
28
|
args: {
|
|
31
29
|
type: 'company',
|
|
32
30
|
name: 'Boligeksperten',
|
|
33
|
-
variant: 'square',
|
|
34
31
|
},
|
|
35
32
|
};
|
|
36
33
|
|
|
37
34
|
export const Logo: Story = {
|
|
38
35
|
args: {
|
|
39
|
-
variant: 'square',
|
|
40
36
|
imageUrl: 'https://avatars.githubusercontent.com/u/1536293?s=200&v=4',
|
|
41
37
|
size: 'xl',
|
|
42
|
-
color: 'dark',
|
|
43
38
|
},
|
|
44
39
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Badge } from './Badge';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Atoms/Badge/Badge',
|
|
6
|
+
component: Badge,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {},
|
|
9
|
+
args: {
|
|
10
|
+
label: 'Badge',
|
|
11
|
+
},
|
|
12
|
+
} satisfies Meta<typeof Badge>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const Alert: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
color: 'alert',
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const UnreadCount: Story = {
|
|
28
|
+
args: {
|
|
29
|
+
label: '2',
|
|
30
|
+
color: 'alert',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -2,18 +2,21 @@ import cx from 'classnames';
|
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import styles from './badge.module.css';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
export type BadgeColor = 'subtle' | 'alert';
|
|
6
|
+
export type BadgeSize = 'sm';
|
|
7
|
+
|
|
8
|
+
export interface BadgeProps {
|
|
6
9
|
label?: string | number;
|
|
7
|
-
|
|
8
|
-
size?:
|
|
10
|
+
color?: BadgeColor;
|
|
11
|
+
size?: BadgeSize;
|
|
12
|
+
className?: string;
|
|
9
13
|
children?: ReactNode;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
return <span className={classNames}>{label || children}</span>;
|
|
16
|
+
export const Badge = ({ label, color = 'subtle', size = 'sm', className, children }: BadgeProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<span className={cx(styles.badge, className)} data-color={color} data-size={size}>
|
|
19
|
+
<span className={styles.label}>{label || children}</span>
|
|
20
|
+
</span>
|
|
21
|
+
);
|
|
19
22
|
};
|