@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.
Files changed (166) hide show
  1. package/.storybook/StoryDecorator.tsx +27 -0
  2. package/.storybook/ThemeProvider.tsx +16 -0
  3. package/.storybook/main.ts +4 -5
  4. package/.storybook/preview.tsx +35 -0
  5. package/.storybook/storyDecorator.module.css +20 -0
  6. package/.storybook/theme.module.css +3 -0
  7. package/CHANGELOG.md +21 -0
  8. package/CONTRIBUTING.MD +59 -0
  9. package/README.md +33 -1
  10. package/lib/components/Attachment/AttachmentLink.stories.ts +21 -0
  11. package/lib/components/Attachment/AttachmentLink.tsx +20 -0
  12. package/lib/components/Attachment/AttachmentList.stories.ts +39 -0
  13. package/lib/components/Attachment/AttachmentList.tsx +26 -0
  14. package/lib/components/Attachment/attachmentLink.module.css +20 -0
  15. package/lib/components/Attachment/attachmentList.module.css +12 -0
  16. package/lib/components/Attachment/index.ts +2 -0
  17. package/lib/components/Avatar/Avatar.tsx +8 -16
  18. package/lib/components/Avatar/AvatarGroup.stories.ts +3 -4
  19. package/lib/components/Avatar/AvatarGroup.tsx +20 -3
  20. package/lib/components/Avatar/avatar.module.css +2 -0
  21. package/lib/components/Avatar/avatar.stories.tsx +1 -6
  22. package/lib/components/Badge/Badge.stories.ts +32 -0
  23. package/lib/components/Badge/Badge.tsx +13 -10
  24. package/lib/components/Badge/badge.module.css +18 -27
  25. package/lib/components/Button/Button.stories.ts +6 -0
  26. package/lib/components/Button/Button.tsx +19 -1
  27. package/lib/components/Button/ButtonBase.tsx +1 -1
  28. package/lib/components/Button/button.module.css +0 -19
  29. package/lib/components/Button/buttonBase.module.css +30 -12
  30. package/lib/components/Button/comboButton.module.css +4 -2
  31. package/lib/components/ContextMenu/ContextMenu.tsx +28 -0
  32. package/lib/components/ContextMenu/contextMenu.module.css +35 -0
  33. package/lib/components/Dialog/Dialog.stories.ts +320 -0
  34. package/lib/components/Dialog/Dialog.tsx +101 -0
  35. package/lib/components/Dialog/DialogAction.stories.ts +54 -0
  36. package/lib/components/Dialog/DialogAction.tsx +79 -0
  37. package/lib/components/Dialog/DialogActivityLog.tsx +18 -0
  38. package/lib/components/Dialog/DialogArticleBase.tsx +10 -0
  39. package/lib/components/Dialog/DialogAttachments.stories.ts +40 -0
  40. package/lib/components/Dialog/DialogAttachments.tsx +25 -0
  41. package/lib/components/Dialog/DialogBase.tsx +10 -0
  42. package/lib/components/Dialog/DialogBodyBase.tsx +17 -0
  43. package/lib/components/Dialog/DialogBorder.tsx +19 -0
  44. package/lib/components/Dialog/DialogContent.stories.ts +26 -0
  45. package/lib/components/Dialog/DialogContent.tsx +24 -0
  46. package/lib/components/Dialog/DialogFooter.tsx +14 -0
  47. package/lib/components/Dialog/DialogHeader.stories.ts +26 -0
  48. package/lib/components/Dialog/DialogHeader.tsx +23 -0
  49. package/lib/components/Dialog/DialogHeaderBase.tsx +10 -0
  50. package/lib/components/Dialog/DialogHeadings.stories.ts +35 -0
  51. package/lib/components/Dialog/DialogHeadings.tsx +77 -0
  52. package/lib/components/Dialog/DialogHistory.stories.ts +67 -0
  53. package/lib/components/Dialog/DialogHistory.tsx +19 -0
  54. package/lib/components/Dialog/DialogList.stories.ts +61 -0
  55. package/lib/components/Dialog/DialogList.tsx +20 -0
  56. package/lib/components/Dialog/DialogListItem.stories.tsx +238 -0
  57. package/lib/components/Dialog/DialogListItem.tsx +114 -0
  58. package/lib/components/Dialog/DialogListItemBase.tsx +50 -0
  59. package/lib/components/Dialog/DialogMetadata.stories.ts +77 -0
  60. package/lib/components/Dialog/DialogMetadata.tsx +56 -0
  61. package/lib/components/Dialog/DialogNav.stories.ts +90 -0
  62. package/lib/components/Dialog/DialogNav.tsx +60 -0
  63. package/lib/components/Dialog/DialogSectionBase.tsx +20 -0
  64. package/lib/components/Dialog/DialogSeenBy.stories.tsx +58 -0
  65. package/lib/components/Dialog/DialogSeenBy.tsx +36 -0
  66. package/lib/components/Dialog/DialogSelect.tsx +23 -0
  67. package/lib/components/Dialog/DialogStatus.stories.ts +57 -0
  68. package/lib/components/Dialog/DialogStatus.tsx +61 -0
  69. package/lib/components/Dialog/DialogTitle.stories.ts +33 -0
  70. package/lib/components/Dialog/DialogTitle.tsx +31 -0
  71. package/lib/components/Dialog/DialogTouchedBy.stories.tsx +27 -0
  72. package/lib/components/Dialog/DialogTouchedBy.tsx +19 -0
  73. package/lib/components/Dialog/dialog.module.css +21 -0
  74. package/lib/components/Dialog/dialogAction.module.css +26 -0
  75. package/lib/components/Dialog/dialogArticleBase.module.css +5 -0
  76. package/lib/components/Dialog/dialogBodyBase.module.css +13 -0
  77. package/lib/components/Dialog/dialogBorder.module.css +42 -0
  78. package/lib/components/Dialog/dialogHeaderBase.module.css +6 -0
  79. package/lib/components/Dialog/dialogHeadings.module.css +24 -0
  80. package/lib/components/Dialog/dialogHistory.module.css +12 -0
  81. package/lib/components/Dialog/dialogListItem.module.css +81 -0
  82. package/lib/components/Dialog/dialogListItemBase.module.css +28 -0
  83. package/lib/components/Dialog/dialogSectionBase.module.css +11 -0
  84. package/lib/components/Dialog/dialogSelect.module.css +34 -0
  85. package/lib/components/Dialog/dialogTitle.module.css +47 -0
  86. package/lib/components/Dialog/index.ts +2 -0
  87. package/lib/components/Header/GlobalMenu.tsx +1 -1
  88. package/lib/components/Header/Header.tsx +3 -3
  89. package/lib/components/Header/HeaderSearch.tsx +1 -1
  90. package/lib/components/History/HistoryBorder.tsx +17 -0
  91. package/lib/components/History/HistoryItem.stories.ts +47 -0
  92. package/lib/components/History/HistoryItem.tsx +64 -0
  93. package/lib/components/History/HistoryList.stories.ts +58 -0
  94. package/lib/components/History/HistoryList.tsx +26 -0
  95. package/lib/components/History/historyBorder.module.css +8 -0
  96. package/lib/components/History/historyItem.module.css +19 -0
  97. package/lib/components/History/historyList.module.css +12 -0
  98. package/lib/components/History/index.ts +2 -0
  99. package/lib/components/Icon/CheckboxCheckedIcon.tsx +28 -0
  100. package/lib/components/Icon/CheckboxIcon.stories.ts +7 -0
  101. package/lib/components/Icon/CheckboxIcon.tsx +6 -18
  102. package/lib/components/Icon/CheckboxUncheckedIcon.tsx +38 -0
  103. package/lib/components/Icon/ProgressIcon.stories.ts +43 -0
  104. package/lib/components/Icon/ProgressIcon.tsx +44 -0
  105. package/lib/components/Icon/RadioCheckedIcon.tsx +29 -0
  106. package/lib/components/Icon/RadioIcon.stories.ts +7 -0
  107. package/lib/components/Icon/RadioIcon.tsx +7 -19
  108. package/lib/components/Icon/RadioUncheckedIcon.tsx +30 -0
  109. package/lib/components/Icon/checkboxIcon.module.css +2 -0
  110. package/lib/components/Icon/index.ts +1 -0
  111. package/lib/components/Icon/progressIcon.module.css +29 -0
  112. package/lib/components/Layout/Layout.stories.ts +0 -3
  113. package/lib/components/List/List.tsx +20 -0
  114. package/lib/components/List/ListBase.tsx +19 -0
  115. package/lib/components/List/ListItem.stories.tsx +208 -0
  116. package/lib/components/List/ListItem.tsx +70 -0
  117. package/lib/components/List/ListItemBase.tsx +62 -0
  118. package/lib/components/List/ListItemLabel.tsx +29 -0
  119. package/lib/components/List/ListItemMedia.tsx +59 -0
  120. package/lib/components/List/index.ts +4 -0
  121. package/lib/components/List/listBase.module.css +16 -0
  122. package/lib/components/List/listItemBase.module.css +86 -0
  123. package/lib/components/List/listItemLabel.module.css +55 -0
  124. package/lib/components/List/listItemMedia.module.css +41 -0
  125. package/lib/components/Menu/Menu.stories.ts +46 -27
  126. package/lib/components/Menu/Menu.tsx +3 -3
  127. package/lib/components/Menu/MenuItem.stories.ts +12 -7
  128. package/lib/components/Menu/MenuItem.tsx +4 -3
  129. package/lib/components/Menu/MenuItemBase.tsx +7 -7
  130. package/lib/components/Menu/MenuItemLabel.tsx +4 -4
  131. package/lib/components/Menu/MenuItemMedia.tsx +2 -2
  132. package/lib/components/Menu/MenuOption.stories.ts +4 -2
  133. package/lib/components/Menu/MenuOption.tsx +4 -4
  134. package/lib/components/Menu/menuItemBase.module.css +72 -0
  135. package/lib/components/Menu/menuItemLabel.module.css +22 -0
  136. package/lib/components/Menu/menuItemMedia.module.css +36 -0
  137. package/lib/components/Menu/menuOption.module.css +6 -8
  138. package/lib/components/Meta/MetaBase.tsx +15 -0
  139. package/lib/components/Meta/MetaItem.stories.ts +25 -0
  140. package/lib/components/Meta/MetaItem.tsx +31 -0
  141. package/lib/components/Meta/MetaItemBase.tsx +46 -0
  142. package/lib/components/Meta/MetaItemLabel.tsx +20 -0
  143. package/lib/components/Meta/MetaItemMedia.tsx +22 -0
  144. package/lib/components/Meta/MetaList.stories.ts +29 -0
  145. package/lib/components/Meta/MetaList.tsx +43 -0
  146. package/lib/components/Meta/MetaProgress.stories.ts +29 -0
  147. package/lib/components/Meta/MetaProgress.tsx +26 -0
  148. package/lib/components/Meta/MetaTimestamp.stories.ts +33 -0
  149. package/lib/components/Meta/MetaTimestamp.tsx +29 -0
  150. package/lib/components/Meta/index.ts +6 -0
  151. package/lib/components/Meta/meta.module.css +6 -0
  152. package/lib/components/Meta/metaItem.module.css +107 -0
  153. package/lib/components/Meta/metaList.module.css +15 -0
  154. package/lib/components/Toolbar/ToolbarAdd.tsx +1 -1
  155. package/lib/components/Typography/Typography.tsx +21 -0
  156. package/lib/components/Typography/index.ts +1 -0
  157. package/lib/components/Typography/typography.module.css +56 -0
  158. package/lib/components/index.ts +9 -0
  159. package/lib/css/global.css +2 -0
  160. package/lib/css/shadows.css +7 -0
  161. package/lib/css/theme-article.css +15 -0
  162. package/lib/css/theme.css +5 -7
  163. package/package.json +4 -2
  164. package/renovate.json +4 -0
  165. package/.storybook/preview.ts +0 -15
  166. /package/lib/components/Toolbar/{index.js → index.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import type { MenuItemSize } from './MenuItemBase';
3
- import styles from './menuItem.module.css';
3
+ import styles from './menuItemLabel.module.css';
4
4
 
5
5
  export interface MenuItemLabelProps {
6
6
  size?: MenuItemSize;
@@ -12,15 +12,15 @@ export interface MenuItemLabelProps {
12
12
 
13
13
  export const MenuItemLabel = ({ size = 'sm', label, title, description, children }: MenuItemLabelProps) => {
14
14
  return (
15
- <span className={styles?.label} data-size={size}>
15
+ <span className={styles.label} data-size={size}>
16
16
  {children ? (
17
17
  children
18
18
  ) : (
19
19
  <>
20
- <strong className={styles?.title} data-size={size}>
20
+ <strong className={styles.title} data-size={size}>
21
21
  {title || label}
22
22
  </strong>
23
- <span className={styles?.description} data-size={size}>
23
+ <span className={styles.description} data-size={size}>
24
24
  {description}
25
25
  </span>
26
26
  </>
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
2
2
  import { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarSize } from '../Avatar';
3
3
  import { Icon, type IconName } from '../Icon';
4
4
  import type { MenuItemColor, MenuItemSize } from './MenuItemBase';
5
- import styles from './menuItem.module.css';
5
+ import styles from './menuItemMedia.module.css';
6
6
 
7
7
  interface MenuItemMediaProps {
8
8
  color?: MenuItemColor;
@@ -33,7 +33,7 @@ export const MenuItemMedia = ({ size = 'sm', color, icon, avatar, avatarGroup, c
33
33
 
34
34
  return (
35
35
  <div className={styles.media} data-size={size} data-color={!icon ? null : color}>
36
- {icon ? <Icon name={icon} variant={color === 'strong' ? 'solid' : 'outline'} className={styles?.icon} /> : ''}
36
+ {icon && <Icon name={icon} variant={color === 'strong' ? 'solid' : 'outline'} className={styles.icon} />}
37
37
  {avatar && <Avatar {...avatar} size={sizeMap?.avatar[size] as AvatarSize} />}
38
38
  {avatarGroup && <AvatarGroup {...avatarGroup} size={sizeMap?.avatarGroup[size] as AvatarSize} />}
39
39
  {children}
@@ -1,5 +1,4 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
-
3
2
  import { MenuOption } from './MenuOption';
4
3
 
5
4
  const meta = {
@@ -7,7 +6,10 @@ const meta = {
7
6
  component: MenuOption,
8
7
  tags: ['autodocs'],
9
8
  parameters: {},
10
- args: {},
9
+ args: {
10
+ value: '',
11
+ label: 'Label',
12
+ },
11
13
  } satisfies Meta<typeof MenuOption>;
12
14
 
13
15
  export default meta;
@@ -33,10 +33,10 @@ export const MenuOption = ({
33
33
  onChange,
34
34
  }: MenuOptionProps) => {
35
35
  return (
36
- <MenuItemBase className={styles?.label} disabled={disabled} selected={checked} size={size} as="label">
37
- <input className={styles?.input} name={name} value={value} type={type} checked={checked} onChange={onChange} />
38
- {type === 'checkbox' && <CheckboxIcon checked={checked} className={styles.icon} />}
39
- {type === 'radio' && <RadioIcon checked={checked} className={styles.icon} />}
36
+ <MenuItemBase className={styles.label} disabled={disabled} selected={checked} size={size} as="label">
37
+ <input className={styles.input} name={name} value={value} type={type} checked={checked} onChange={onChange} />
38
+ {type === 'checkbox' && <CheckboxIcon checked={checked} hover={true} className={styles.icon} />}
39
+ {type === 'radio' && <RadioIcon checked={checked} hover={true} className={styles.icon} />}
40
40
  <MenuItemLabel title={title} description={description} size={size}>
41
41
  {label}
42
42
  </MenuItemLabel>
@@ -0,0 +1,72 @@
1
+ .item {
2
+ background-color: transparent;
3
+ display: flex;
4
+ align-items: center;
5
+ column-gap: 4px;
6
+ border: 0;
7
+ user-select: none;
8
+ cursor: pointer;
9
+ margin: 0.5rem 0;
10
+ }
11
+
12
+ .item[aria-disabled="true"] {
13
+ opacity: 0.5;
14
+ pointer-events: none;
15
+ }
16
+
17
+ /* size */
18
+
19
+ .item[data-size="sm"] {
20
+ min-height: 44px;
21
+ }
22
+
23
+ /* content */
24
+
25
+ .content {
26
+ display: flex;
27
+ width: 100%;
28
+ align-items: center;
29
+ column-gap: 6px;
30
+ padding: 6px;
31
+ }
32
+
33
+ .action {
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+ padding: 10px;
38
+ }
39
+
40
+ .actionIcon {
41
+ font-size: 1.5rem;
42
+ }
43
+
44
+ /* colors */
45
+
46
+ .item:hover {
47
+ background-color: var(--theme-background-default);
48
+ }
49
+
50
+ .item[aria-selected="true"] {
51
+ background-color: var(--theme-background-default);
52
+ }
53
+
54
+ /* company */
55
+
56
+ .item[data-color="company"]:hover {
57
+ background-color: var(--company-background-subtle);
58
+ }
59
+
60
+ .item[data-color="company"][aria-selected="true"] {
61
+ background-color: var(--company-surface-default);
62
+ }
63
+
64
+ /* person */
65
+
66
+ .item[data-color="person"]:hover {
67
+ background-color: var(--person-background-subtle);
68
+ }
69
+
70
+ .item[data-color="person"][aria-selected="true"] {
71
+ background-color: var(--person-surface-default);
72
+ }
@@ -0,0 +1,22 @@
1
+ .label {
2
+ display: flex;
3
+ flex-direction: column;
4
+ padding: 0 0.25rem;
5
+ }
6
+
7
+ .title[data-size="lg"] {
8
+ font-size: 1.125rem;
9
+ line-height: 1.25;
10
+ font-weight: 500;
11
+ }
12
+
13
+ .title[data-size="sm"] {
14
+ font-size: 1rem;
15
+ line-height: 1.25;
16
+ font-weight: 400;
17
+ }
18
+
19
+ .description {
20
+ font-size: 14px;
21
+ color: var(--theme-text-subtle);
22
+ }
@@ -0,0 +1,36 @@
1
+ .media {
2
+ flex-shrink: 0;
3
+ display: flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ border-radius: 5%;
7
+ width: 2rem;
8
+ height: 2rem;
9
+ }
10
+
11
+ .media[data-size="lg"] {
12
+ width: 44px;
13
+ height: 44px;
14
+ }
15
+
16
+ .icon {
17
+ font-size: 1.5rem;
18
+ }
19
+
20
+ .media[data-color="subtle"] {
21
+ background-color: var(--theme-background-default);
22
+ color: var(--theme-text-default);
23
+ }
24
+
25
+ .media[data-color="strong"] {
26
+ background-color: var(--theme-base-default);
27
+ color: var(--theme-background-default);
28
+ }
29
+
30
+ .media[data-color="company"] {
31
+ background-color: var(--company-surface-default);
32
+ }
33
+
34
+ .media[data-color="person"] {
35
+ background-color: var(--person-surface-default);
36
+ }
@@ -9,21 +9,19 @@
9
9
 
10
10
  .icon {
11
11
  font-size: 1rem;
12
- border: 2px solid;
13
12
  display: flex;
14
13
  align-items: center;
15
14
  justify-content: center;
16
15
  }
17
16
 
18
- .icon > svg {
19
- color: transparent;
17
+ .icon {
18
+ color: var(--theme-base-default);
20
19
  }
21
20
 
22
- .label:hover .icon > svg {
23
- color: var(--theme-base-default);
21
+ .icon [data-hover="true"] {
22
+ opacity: 0;
24
23
  }
25
24
 
26
- .icon[data-checked="true"] > svg,
27
- .label:hover .icon[data-checked="true"] > svg {
28
- color: var(--theme-background-subtle);
25
+ .label:hover [data-hover="true"] {
26
+ opacity: 1;
29
27
  }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { MetaItemSize } from './MetaItemBase';
3
+ import styles from './meta.module.css';
4
+ export interface MetaBaseProps {
5
+ size?: MetaItemSize;
6
+ children?: ReactNode;
7
+ }
8
+
9
+ export const MetaBase = ({ size = 'xs', children }: MetaBaseProps) => {
10
+ return (
11
+ <div className={styles.meta} data-size={size}>
12
+ {children}
13
+ </div>
14
+ );
15
+ };
@@ -0,0 +1,25 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { MetaItem } from './MetaItem';
3
+
4
+ const meta = {
5
+ title: 'Meta/MetaItem',
6
+ component: MetaItem,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'centered',
10
+ },
11
+ args: {
12
+ children: 'Label',
13
+ },
14
+ } satisfies Meta<typeof MetaItem>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const Default: Story = {
20
+ args: {},
21
+ };
22
+
23
+ export const Icon: Story = {
24
+ args: { icon: 'clock-dashed' },
25
+ };
@@ -0,0 +1,31 @@
1
+ import type { ElementType, ReactNode } from 'react';
2
+ import type { IconName } from '../Icon';
3
+ import { MetaItemBase, type MetaItemSize, type MetaItemVariant } from './MetaItemBase';
4
+ import { MetaItemLabel } from './MetaItemLabel';
5
+ import { MetaItemMedia } from './MetaItemMedia';
6
+
7
+ export interface MetaItemProps {
8
+ /** Render as element */
9
+ as?: ElementType;
10
+ /** Meta size */
11
+ size?: MetaItemSize;
12
+ /** Variant */
13
+ variant?: MetaItemVariant;
14
+ /** Icon name */
15
+ icon?: IconName;
16
+ /** Label */
17
+ children?: ReactNode;
18
+ /** classname */
19
+ className?: string;
20
+ }
21
+
22
+ export const MetaItem = ({ size = 'xs', variant = 'text', icon, children, ...rest }: MetaItemProps) => {
23
+ return (
24
+ <MetaItemBase variant={variant} size={size} {...rest}>
25
+ {icon && <MetaItemMedia icon={icon} size={size} />}
26
+ <MetaItemLabel variant={variant} size={size}>
27
+ {children}
28
+ </MetaItemLabel>
29
+ </MetaItemBase>
30
+ );
31
+ };
@@ -0,0 +1,46 @@
1
+ import cx from 'classnames';
2
+ import type { ElementType, ReactNode } from 'react';
3
+ import styles from './metaItem.module.css';
4
+
5
+ export type MetaItemVariant = 'solid' | 'outline' | 'dotted' | 'text';
6
+ export type MetaItemSize = 'xs' | 'sm' | 'md';
7
+ export type MetaItemColor = 'subtle';
8
+
9
+ export interface MetaItemBaseProps {
10
+ as?: ElementType;
11
+ variant?: MetaItemVariant;
12
+ size?: MetaItemSize;
13
+ color?: MetaItemColor;
14
+ datetime?: string;
15
+ progress?: number;
16
+ className?: string;
17
+ children?: ReactNode;
18
+ }
19
+
20
+ export const MetaItemBase = ({
21
+ as,
22
+ variant = 'text',
23
+ size,
24
+ color,
25
+ progress,
26
+ datetime,
27
+ className,
28
+ children,
29
+ ...rest
30
+ }: MetaItemBaseProps) => {
31
+ const Component = as || 'span';
32
+
33
+ return (
34
+ <Component
35
+ data-size={size}
36
+ data-color={color}
37
+ data-variant={variant}
38
+ data-progress={progress}
39
+ dateTime={datetime}
40
+ className={cx(styles.item, className)}
41
+ {...rest}
42
+ >
43
+ {children}
44
+ </Component>
45
+ );
46
+ };
@@ -0,0 +1,20 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { MetaItemSize, MetaItemVariant } from './MetaItemBase';
3
+ import styles from './metaItem.module.css';
4
+
5
+ export interface MetaItemLabelProps {
6
+ /** Meta size */
7
+ size?: MetaItemSize;
8
+ /** Variant */
9
+ variant?: MetaItemVariant;
10
+ /** Label */
11
+ children?: ReactNode;
12
+ }
13
+
14
+ export const MetaItemLabel = ({ size = 'sm', variant = 'text', children }: MetaItemLabelProps) => {
15
+ return (
16
+ <span className={styles.label} data-variant={variant} data-size={size}>
17
+ {children}
18
+ </span>
19
+ );
20
+ };
@@ -0,0 +1,22 @@
1
+ import { Icon, type IconName, ProgressIcon } from '../Icon';
2
+ import type { MetaItemSize } from './MetaItemBase';
3
+ import styles from './metaItem.module.css';
4
+
5
+ interface MetaItemMediaProps {
6
+ size?: MetaItemSize;
7
+ progress?: number;
8
+ icon?: IconName;
9
+ }
10
+
11
+ export const MetaItemMedia = ({ size = 'sm', icon, progress }: MetaItemMediaProps) => {
12
+ if (!icon && typeof progress !== 'number') {
13
+ return false;
14
+ }
15
+
16
+ return (
17
+ <span className={styles.media} data-size={size}>
18
+ {icon && <Icon name={icon} className={styles.icon} />}
19
+ {progress && <ProgressIcon value={progress} className={styles.icon} />}
20
+ </span>
21
+ );
22
+ };
@@ -0,0 +1,29 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { MetaList } from './MetaList';
3
+
4
+ const meta = {
5
+ title: 'Meta/MetaList',
6
+ component: MetaList,
7
+ tags: ['autodocs'],
8
+ parameters: {},
9
+ args: {
10
+ items: [
11
+ {
12
+ label: 'Meta 1',
13
+ },
14
+ {
15
+ label: 'Meta 2',
16
+ },
17
+ {
18
+ label: 'Meta 3',
19
+ },
20
+ ],
21
+ },
22
+ } satisfies Meta<typeof MetaList>;
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof meta>;
26
+
27
+ export const Default: Story = {
28
+ args: {},
29
+ };
@@ -0,0 +1,43 @@
1
+ import { MetaBase } from './MetaBase';
2
+ import { MetaItem } from './MetaItem';
3
+ import type { MetaItemBaseProps, MetaItemSize } from './MetaItemBase';
4
+ import { MetaProgress } from './MetaProgress';
5
+ import { MetaTimestamp } from './MetaTimestamp';
6
+ import styles from './metaList.module.css';
7
+
8
+ export type MetaListItemType = 'default' | 'progress' | 'timestamp';
9
+
10
+ export interface MetaListItemProps extends MetaItemBaseProps {
11
+ label: string;
12
+ type?: MetaListItemType;
13
+ }
14
+
15
+ export interface MetaListProps {
16
+ items: MetaListItemProps[];
17
+ size?: MetaItemSize;
18
+ }
19
+
20
+ export const MetaListItem = ({ type = 'default', label, ...rest }: MetaListItemProps) => {
21
+ switch (type) {
22
+ case 'progress':
23
+ return <MetaProgress {...rest}>{label}</MetaProgress>;
24
+ case 'timestamp':
25
+ return <MetaTimestamp {...rest}>{label}</MetaTimestamp>;
26
+ default:
27
+ return <MetaItem {...rest}>{label}</MetaItem>;
28
+ }
29
+ };
30
+
31
+ export const MetaList = ({ size = 'xs', items = [] }: MetaListProps) => {
32
+ return (
33
+ <MetaBase size={size}>
34
+ <ul className={styles.list}>
35
+ {items.map((item, index) => (
36
+ <li className={styles.item} key={'meta-' + index}>
37
+ <MetaListItem {...item} />
38
+ </li>
39
+ ))}
40
+ </ul>
41
+ </MetaBase>
42
+ );
43
+ };
@@ -0,0 +1,29 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { MetaProgress } from './MetaProgress';
3
+
4
+ const meta = {
5
+ title: 'Meta/MetaProgress',
6
+ component: MetaProgress,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ layout: 'centered',
10
+ },
11
+ args: {},
12
+ } satisfies Meta<typeof MetaProgress>;
13
+
14
+ export default meta;
15
+ type Story = StoryObj<typeof meta>;
16
+
17
+ export const InProgress: Story = {
18
+ args: {
19
+ progress: 75,
20
+ children: 'Under arbeid',
21
+ },
22
+ };
23
+
24
+ export const ProgressComplete: Story = {
25
+ args: {
26
+ progress: 100,
27
+ children: 'Avsluttet',
28
+ },
29
+ };
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from 'react';
2
+ import { MetaItemBase, type MetaItemSize, type MetaItemVariant } from './MetaItemBase';
3
+ import { MetaItemLabel } from './MetaItemLabel';
4
+ import { MetaItemMedia } from './MetaItemMedia';
5
+
6
+ export interface MetaProgressProps {
7
+ /** Meta size */
8
+ size?: MetaItemSize;
9
+ /** Variant */
10
+ variant?: MetaItemVariant;
11
+ /** Progress of 100 */
12
+ progress?: number;
13
+ /** Label */
14
+ children?: ReactNode;
15
+ }
16
+
17
+ export const MetaProgress = ({ size = 'xs', variant = 'text', progress = 0, children }: MetaProgressProps) => {
18
+ return (
19
+ <MetaItemBase variant={variant} size={size}>
20
+ <MetaItemMedia size={size} progress={progress} />
21
+ <MetaItemLabel variant={variant} size={size}>
22
+ {children}
23
+ </MetaItemLabel>
24
+ </MetaItemBase>
25
+ );
26
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { MetaTimestamp } from './MetaTimestamp';
3
+
4
+ const meta = {
5
+ title: 'Meta/MetaTimestamp',
6
+ component: MetaTimestamp,
7
+ tags: ['autodocs'],
8
+ parameters: {
9
+ // layout: "fullscreen",
10
+ },
11
+ args: {
12
+ children: '26. mai 1999',
13
+ datetime: '1999-05-26',
14
+ },
15
+ } satisfies Meta<typeof MetaTimestamp>;
16
+
17
+ export default meta;
18
+ type Story = StoryObj<typeof meta>;
19
+
20
+ export const Default: Story = {
21
+ args: {
22
+ children: '26. mai 1999',
23
+ datetime: '1999-05-26',
24
+ },
25
+ };
26
+
27
+ export const Icon: Story = {
28
+ args: {
29
+ icon: 'clock',
30
+ children: 'Frist: 26. mai 1999',
31
+ datetime: '1999-05-26',
32
+ },
33
+ };
@@ -0,0 +1,29 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { IconName } from '../Icon';
3
+ import { MetaItemBase, type MetaItemSize, type MetaItemVariant } from './MetaItemBase';
4
+ import { MetaItemLabel } from './MetaItemLabel';
5
+ import { MetaItemMedia } from './MetaItemMedia';
6
+
7
+ export interface MetaTimestampProps {
8
+ /** Meta size */
9
+ size?: MetaItemSize;
10
+ /** Variant */
11
+ variant?: MetaItemVariant;
12
+ /** Datetime in ISO format */
13
+ datetime?: string;
14
+ /** Icon name */
15
+ icon?: IconName;
16
+ /** Label */
17
+ children?: ReactNode;
18
+ }
19
+
20
+ export const MetaTimestamp = ({ size = 'xs', variant = 'text', datetime, icon, children }: MetaTimestampProps) => {
21
+ return (
22
+ <MetaItemBase as="time" variant={variant} datetime={datetime} size={size}>
23
+ {icon && <MetaItemMedia size={size} icon={icon} />}
24
+ <MetaItemLabel variant={variant} size={size}>
25
+ {children}
26
+ </MetaItemLabel>
27
+ </MetaItemBase>
28
+ );
29
+ };
@@ -0,0 +1,6 @@
1
+ export * from './MetaBase';
2
+ export * from './MetaList';
3
+ export * from './MetaItemBase';
4
+ export * from './MetaItem';
5
+ export * from './MetaProgress';
6
+ export * from './MetaTimestamp';
@@ -0,0 +1,6 @@
1
+ .meta {
2
+ display: flex;
3
+ align-items: center;
4
+ flex-wrap: wrap;
5
+ column-gap: 0.5rem;
6
+ }