@altinn/altinn-components 0.4.1 → 0.5.1
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 +1 -1
- package/.storybook/main.ts +3 -4
- package/.storybook/preview.tsx +28 -0
- package/CHANGELOG.md +14 -0
- package/biome.jsonc +1 -1
- package/lib/components/Attachment/AttachmentLink.stories.ts +1 -1
- package/lib/components/Attachment/AttachmentList.stories.ts +1 -1
- package/lib/components/Button/Button.tsx +13 -10
- package/lib/components/Button/ButtonBase.tsx +1 -1
- package/lib/components/Button/ButtonIcon.tsx +16 -0
- package/lib/components/Button/ButtonLabel.tsx +18 -0
- package/lib/components/Button/Buttons.stories.tsx +64 -0
- package/lib/components/Button/ComboButton.tsx +9 -7
- package/lib/components/Button/IconButton.stories.tsx +47 -0
- package/lib/components/Button/IconButton.tsx +15 -5
- package/lib/components/Button/button.module.css +5 -46
- package/lib/components/Button/buttonBase.module.css +55 -23
- package/lib/components/Button/buttonIcon.module.css +17 -0
- package/lib/components/Button/buttonLabel.module.css +17 -0
- package/lib/components/Button/comboButton.module.css +15 -65
- package/lib/components/Button/iconButton.module.css +21 -4
- package/lib/components/Button/index.ts +2 -0
- package/lib/components/ContextMenu/ContextMenu.stories.ts +49 -0
- package/lib/components/ContextMenu/ContextMenu.tsx +12 -20
- package/lib/components/ContextMenu/ContextMenuBase.tsx +33 -0
- package/lib/components/Dialog/Dialog.stories.ts +12 -5
- package/lib/components/Dialog/Dialog.tsx +2 -0
- package/lib/components/Dialog/DialogGroup.tsx +24 -0
- package/lib/components/Dialog/DialogList.stories.ts +14 -10
- package/lib/components/Dialog/DialogList.tsx +26 -11
- package/lib/components/Dialog/DialogListItem.tsx +12 -2
- package/lib/components/Dialog/DialogListItemBase.tsx +4 -2
- package/lib/components/Dialog/DialogNav.stories.ts +5 -5
- package/lib/components/Dialog/DialogNav.tsx +2 -6
- package/lib/components/Dialog/DialogSelect.tsx +1 -1
- package/lib/components/Dialog/dialogGroup.module.css +35 -0
- package/lib/components/Dropdown/Backdrop.tsx +4 -3
- package/lib/components/Dropdown/DrawerBase.tsx +5 -2
- package/lib/components/Dropdown/DrawerBody.tsx +12 -0
- package/lib/components/Dropdown/DrawerButton.tsx +17 -0
- package/lib/components/Dropdown/DrawerFooter.tsx +12 -0
- package/lib/components/Dropdown/DrawerHeader.tsx +19 -0
- package/lib/components/Dropdown/DrawerOrDropdown.tsx +29 -0
- package/lib/components/Dropdown/DropdownBase.tsx +17 -2
- package/lib/components/Dropdown/backdrop.module.css +3 -0
- package/lib/components/Dropdown/drawerBase.module.css +9 -0
- package/lib/components/Dropdown/drawerBody.module.css +5 -0
- package/lib/components/Dropdown/drawerButton.module.css +6 -0
- package/lib/components/Dropdown/drawerFooter.module.css +13 -0
- package/lib/components/Dropdown/drawerHeader.module.css +17 -0
- package/lib/components/Dropdown/drawerOrDropdown.module.css +19 -0
- package/lib/components/Dropdown/dropdownBase.module.css +20 -4
- package/lib/components/Dropdown/index.ts +7 -1
- package/lib/components/Footer/footerMenu.module.css +5 -0
- package/lib/components/GlobalMenu/AccountButton.tsx +29 -0
- package/lib/components/GlobalMenu/AccountMenu.stories.tsx +65 -0
- package/lib/components/GlobalMenu/AccountMenu.tsx +73 -0
- package/lib/components/GlobalMenu/BackButton.tsx +10 -0
- package/lib/components/GlobalMenu/GlobalMenu.stories.tsx +112 -121
- package/lib/components/GlobalMenu/GlobalMenu.tsx +41 -89
- package/lib/components/GlobalMenu/GlobalMenuBase.tsx +22 -0
- package/lib/components/GlobalMenu/LogoutButton.tsx +19 -0
- package/lib/components/GlobalMenu/globalMenuBase.module.css +39 -0
- package/lib/components/GlobalMenu/index.tsx +1 -1
- package/lib/components/GlobalMenu/logoutButton.module.css +9 -0
- package/lib/components/Header/{Header.stories.ts → Header.stories.tsx} +79 -20
- package/lib/components/Header/Header.tsx +25 -38
- package/lib/components/Header/HeaderBase.tsx +7 -3
- package/lib/components/Header/header.module.css +10 -42
- package/lib/components/Header/headerBase.module.css +43 -0
- package/lib/components/Header/headerButton.module.css +1 -0
- package/lib/components/Layout/Layout.stories.tsx +77 -38
- package/lib/components/Layout/Layout.tsx +5 -3
- package/lib/components/Layout/LayoutBase.tsx +3 -2
- package/lib/components/Layout/layoutBase.module.css +11 -0
- package/lib/components/Layout/layoutBody.module.css +1 -0
- package/lib/components/LayoutAction/ActionHeader.tsx +1 -1
- package/lib/components/LayoutAction/ActionMenu.tsx +2 -4
- package/lib/components/LayoutAction/actionMenu.module.css +3 -0
- package/lib/components/List/List.stories.tsx +43 -0
- package/lib/components/List/List.tsx +6 -6
- package/lib/components/List/ListBase.tsx +6 -6
- package/lib/components/List/ListItem.tsx +4 -1
- package/lib/components/List/ListItemBase.tsx +20 -4
- package/lib/components/List/listBase.module.css +3 -3
- package/lib/components/List/listItemBase.module.css +4 -0
- package/lib/components/Menu/Menu.stories.ts +46 -46
- package/lib/components/Menu/Menu.tsx +3 -102
- package/lib/components/Menu/MenuBase.tsx +47 -3
- package/lib/components/Menu/MenuItem.tsx +8 -4
- package/lib/components/Menu/MenuItemBase.tsx +15 -2
- package/lib/components/Menu/MenuItems.stories.ts +438 -0
- package/lib/components/Menu/MenuItems.tsx +96 -0
- package/lib/components/Menu/MenuOption.tsx +4 -1
- package/lib/components/Menu/index.ts +1 -1
- package/lib/components/Menu/menu.module.css +2 -3
- package/lib/components/Menu/menuBase.module.css +25 -0
- package/lib/components/Menu/menuItemBase.module.css +11 -5
- package/lib/components/Menu/menuItemLabel.module.css +11 -1
- package/lib/components/Menu/menuSearch.module.css +1 -0
- package/lib/components/Meta/MetaItemBase.tsx +1 -1
- package/lib/components/Meta/MetaItemLabel.tsx +1 -1
- package/lib/components/Meta/MetaItemMedia.tsx +1 -1
- package/lib/components/Page/PageBase.tsx +14 -0
- package/lib/components/Page/PageHeader.tsx +21 -0
- package/lib/components/Page/PageHeaderMedia.tsx +25 -0
- package/lib/components/Page/SectionBase.tsx +52 -0
- package/lib/components/Page/SectionFooter.tsx +15 -0
- package/lib/components/Page/SectionHeader.tsx +16 -0
- package/lib/components/Page/index.ts +5 -0
- package/lib/components/Page/pageHeader.module.css +5 -0
- package/lib/components/Page/sectionBase.module.css +82 -0
- package/lib/components/Page/sectionFooter.module.css +8 -0
- package/lib/components/Page/sectionHeader.module.css +9 -0
- package/lib/components/RootProvider/RootProvider.tsx +43 -7
- package/lib/components/Searchbar/Autocomplete.stories.tsx +77 -0
- package/lib/components/Searchbar/Autocomplete.tsx +44 -0
- package/lib/components/Searchbar/AutocompleteBase.tsx +16 -0
- package/lib/components/Searchbar/AutocompleteGroup.tsx +17 -0
- package/lib/components/Searchbar/AutocompleteItem.tsx +23 -0
- package/lib/components/Searchbar/SearchField.tsx +78 -0
- package/lib/components/Searchbar/Searchbar.stories.tsx +151 -0
- package/lib/components/Searchbar/Searchbar.tsx +18 -0
- package/lib/components/Searchbar/SearchbarBase.tsx +23 -0
- package/lib/components/Searchbar/autocompleteBase.module.css +17 -0
- package/lib/components/Searchbar/autocompleteGroup.module.css +3 -0
- package/lib/components/Searchbar/autocompleteItem.module.css +19 -0
- package/lib/components/Searchbar/index.ts +1 -0
- package/lib/components/Searchbar/searchField.module.css +54 -0
- package/lib/components/Searchbar/searchbarBase.module.css +20 -0
- package/lib/components/Toolbar/Toolbar.stories.tsx +10 -10
- package/lib/components/Toolbar/Toolbar.tsx +28 -10
- package/lib/components/Toolbar/ToolbarAdd.tsx +6 -5
- package/lib/components/Toolbar/ToolbarBase.tsx +5 -20
- package/lib/components/Toolbar/ToolbarButton.tsx +1 -1
- package/lib/components/Toolbar/ToolbarFilter.tsx +11 -6
- package/lib/components/Toolbar/ToolbarMenu.tsx +8 -7
- package/lib/components/Toolbar/ToolbarOptions.stories.ts +5 -5
- package/lib/components/Toolbar/ToolbarOptions.tsx +34 -21
- package/lib/components/Toolbar/toolbarAdd.module.css +7 -0
- package/lib/components/Toolbar/toolbarBase.module.css +19 -0
- package/lib/components/Toolbar/toolbarButton.module.css +1 -1
- package/lib/components/Toolbar/toolbarFilter.module.css +25 -0
- package/lib/components/Toolbar/toolbarMenu.module.css +7 -0
- package/lib/components/Typography/Heading.tsx +23 -0
- package/lib/components/Typography/Typography.tsx +8 -5
- package/lib/components/Typography/heading.module.css +21 -0
- package/lib/components/Typography/index.ts +1 -0
- package/lib/components/Typography/typography.module.css +8 -0
- package/lib/components/index.ts +2 -0
- package/lib/hooks/index.ts +3 -0
- package/lib/{components/Menu → hooks}/useEscapeKey.ts +2 -2
- package/lib/hooks/useMenu.tsx +80 -0
- package/lib/index.ts +1 -0
- package/lib/stories/Color/MenuItem.stories.tsx +43 -0
- package/lib/stories/Color/Swatches.stories.tsx +19 -0
- package/lib/stories/Color/Swatches.tsx +42 -0
- package/lib/stories/Color/colors.json +62 -0
- package/lib/stories/Color/swatches.module.css +14 -0
- package/lib/stories/Inbox/BookmarksPage.tsx +52 -0
- package/lib/stories/Inbox/DialogPage.tsx +15 -0
- package/lib/stories/Inbox/Inbox.stories.tsx +55 -0
- package/lib/stories/Inbox/Inbox.tsx +12 -0
- package/lib/stories/Inbox/InboxLayout.tsx +50 -0
- package/lib/stories/Inbox/InboxPage.tsx +50 -0
- package/lib/stories/Inbox/InboxProvider.tsx +136 -0
- package/lib/stories/Inbox/InboxSection.tsx +39 -0
- package/lib/stories/Inbox/InboxToolbar.tsx +94 -0
- package/lib/stories/Inbox/ProfilePage.tsx +35 -0
- package/lib/stories/Inbox/SettingsPage.tsx +19 -0
- package/lib/stories/Inbox/accounts/accounts.ts +24 -0
- package/lib/stories/Inbox/accounts/index.ts +1 -0
- package/lib/stories/Inbox/actionMenu.ts +24 -0
- package/lib/stories/Inbox/dialogs/brreg-completed.json +35 -0
- package/lib/stories/Inbox/dialogs/brreg-draft.json +45 -0
- package/lib/stories/Inbox/dialogs/index.ts +10 -0
- package/lib/stories/Inbox/dialogs/skatt-2023.json +33 -0
- package/lib/stories/Inbox/groupBy.ts +19 -0
- package/lib/stories/Inbox/inboxSection.module.css +19 -0
- package/lib/stories/Inbox/index.ts +15 -0
- package/lib/stories/Inbox/layout/footer.ts +27 -0
- package/lib/stories/Inbox/layout/header.ts +11 -0
- package/lib/stories/Inbox/layout/index.ts +3 -0
- package/lib/stories/Inbox/layout/menu.ts +64 -0
- package/package.json +15 -13
- package/tsconfig.json +7 -2
- package/lib/components/Header/HeaderSearch.stories.ts +0 -20
- package/lib/components/Header/HeaderSearch.tsx +0 -44
- package/lib/components/Header/headerSearch.module.css +0 -30
- package/lib/components/Menu/MenuGroup.tsx +0 -18
- package/lib/components/Menu/__menuItem.module.css +0 -130
- package/lib/components/Toolbar/toolbar.module.css +0 -43
- /package/lib/components/ContextMenu/{contextMenu.module.css → contextMenuBase.module.css} +0 -0
- /package/lib/{components/Menu → hooks}/useClickOutside.ts +0 -0
|
@@ -2,84 +2,34 @@
|
|
|
2
2
|
display: inline-flex;
|
|
3
3
|
flex-direction: row-reverse;
|
|
4
4
|
align-items: center;
|
|
5
|
-
border: 1px solid;
|
|
6
5
|
border-radius: 2px;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
|
-
/*
|
|
10
|
-
.button[aria-selected="true"] {
|
|
11
|
-
background-color: var(--theme-background-subtle);
|
|
12
|
-
color: var(--theme-text-default);
|
|
13
|
-
}
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
.label {
|
|
17
|
-
line-height: 1rem;
|
|
18
|
-
font-weight: 600;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
8
|
.divider {
|
|
9
|
+
align-self: stretch;
|
|
22
10
|
border-left: 1px solid currentColor;
|
|
23
11
|
width: 1px;
|
|
24
|
-
|
|
12
|
+
margin: 0.375rem 0;
|
|
25
13
|
}
|
|
26
14
|
|
|
27
|
-
.
|
|
28
|
-
|
|
15
|
+
.primary,
|
|
16
|
+
.secondary {
|
|
17
|
+
display: inline-flex;
|
|
29
18
|
align-items: center;
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/* variant */
|
|
34
|
-
|
|
35
|
-
.button[data-variant="solid"] {
|
|
36
|
-
border-color: var(--theme-base-hover);
|
|
37
|
-
background-color: var(--theme-base-hover);
|
|
38
|
-
color: white;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/* sm 36px */
|
|
42
|
-
|
|
43
|
-
.label[data-size="sm"] {
|
|
44
|
-
font-size: 0.875rem;
|
|
45
|
-
padding: 8px 10px;
|
|
19
|
+
border: none;
|
|
46
20
|
}
|
|
47
21
|
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
.icon[data-size="sm"] {
|
|
53
|
-
font-size: 1.25rem;
|
|
54
|
-
padding: 6px 5px;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/* md 44px */
|
|
58
|
-
|
|
59
|
-
.button[data-size="md"] {
|
|
60
|
-
font-size: 1rem;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.label[data-size="md"] {
|
|
64
|
-
padding: 10px;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.icon[data-size="md"] {
|
|
68
|
-
font-size: 1.25rem;
|
|
69
|
-
padding: 12px 8px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/* lg 56 */
|
|
73
|
-
|
|
74
|
-
.button[data-size="lg"] {
|
|
75
|
-
font-size: 1.125rem;
|
|
22
|
+
.primary[data-size="sm"],
|
|
23
|
+
.secondary[data-size="sm"] {
|
|
24
|
+
padding: 0 0.375rem;
|
|
76
25
|
}
|
|
77
26
|
|
|
78
|
-
.
|
|
79
|
-
|
|
27
|
+
.primary[data-size="md"],
|
|
28
|
+
.secondary[data-size="md"] {
|
|
29
|
+
padding: 0 0.5rem;
|
|
80
30
|
}
|
|
81
31
|
|
|
82
|
-
.
|
|
83
|
-
|
|
84
|
-
padding:
|
|
32
|
+
.primary[data-size="lg"],
|
|
33
|
+
.secondary[data-size="lg"] {
|
|
34
|
+
padding: 0 0.625rem;
|
|
85
35
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
.button {
|
|
2
|
-
border: 1px solid;
|
|
3
|
-
width: 2.75rem;
|
|
4
|
-
height: 2.75rem;
|
|
5
2
|
display: flex;
|
|
6
3
|
align-items: center;
|
|
7
4
|
justify-content: center;
|
|
@@ -10,5 +7,25 @@
|
|
|
10
7
|
|
|
11
8
|
.icon {
|
|
12
9
|
font-size: 1.5rem;
|
|
13
|
-
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/* sm 36 */
|
|
13
|
+
|
|
14
|
+
.button[data-size="sm"] {
|
|
15
|
+
width: 2.25rem;
|
|
16
|
+
height: 2.25rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* md 44 */
|
|
20
|
+
|
|
21
|
+
.button[data-size="md"] {
|
|
22
|
+
width: 2.75rem;
|
|
23
|
+
height: 2.75rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* lg 56 */
|
|
27
|
+
|
|
28
|
+
.button[data-size="lg"] {
|
|
29
|
+
width: 3.5rem;
|
|
30
|
+
height: 3.5rem;
|
|
14
31
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { ContextMenu } from './ContextMenu';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'ContextMenu/ContextMenu',
|
|
6
|
+
component: ContextMenu,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
parameters: {},
|
|
9
|
+
args: {
|
|
10
|
+
placement: 'left',
|
|
11
|
+
items: [
|
|
12
|
+
{
|
|
13
|
+
id: '1',
|
|
14
|
+
groupId: '1',
|
|
15
|
+
icon: 'arrow-redo',
|
|
16
|
+
label: 'Del og gi tilgang',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: '2',
|
|
20
|
+
groupId: '1',
|
|
21
|
+
icon: 'eye-closed',
|
|
22
|
+
label: 'Marker som ny',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: '3',
|
|
26
|
+
groupId: '2',
|
|
27
|
+
icon: 'archive',
|
|
28
|
+
label: 'Flytt til arkiv',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: '4',
|
|
32
|
+
groupId: '2',
|
|
33
|
+
icon: 'trash',
|
|
34
|
+
label: 'Flytt til papirkurv',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: '5',
|
|
38
|
+
groupId: '3',
|
|
39
|
+
icon: 'clock-dashed',
|
|
40
|
+
label: 'Aktivitetslogg',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
} satisfies Meta<typeof ContextMenu>;
|
|
45
|
+
|
|
46
|
+
export default meta;
|
|
47
|
+
type Story = StoryObj<typeof meta>;
|
|
48
|
+
|
|
49
|
+
export const Default: Story = {};
|
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import styles from './contextMenu.module.css';
|
|
1
|
+
import type { DropdownPlacement, MenuItemProps } from '../';
|
|
2
|
+
import { type MenuItemGroups, MenuItems } from '../';
|
|
3
|
+
import { useRootContext } from '../RootProvider';
|
|
4
|
+
import { ContextMenuBase } from './ContextMenuBase';
|
|
6
5
|
|
|
7
6
|
export interface ContextMenuProps {
|
|
8
|
-
|
|
9
|
-
label: string;
|
|
10
|
-
value: string | number;
|
|
7
|
+
id: string;
|
|
11
8
|
items: MenuItemProps[];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
className?: string;
|
|
9
|
+
placement?: DropdownPlacement;
|
|
10
|
+
groups?: MenuItemGroups;
|
|
15
11
|
}
|
|
16
12
|
|
|
17
|
-
export const ContextMenu = ({
|
|
13
|
+
export const ContextMenu = ({ id = 'context-menu', placement = 'right', groups = {}, items }: ContextMenuProps) => {
|
|
14
|
+
const { currentId, toggleId } = useRootContext();
|
|
18
15
|
return (
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
</ButtonBase>
|
|
23
|
-
<div className={styles.dropdown} aria-expanded={expanded}>
|
|
24
|
-
<Menu theme="global" defaultItemColor="subtle" groups={groups} items={items} />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
16
|
+
<ContextMenuBase placement={placement} expanded={currentId === id} onToggle={() => toggleId(id)}>
|
|
17
|
+
<MenuItems groups={groups} items={items} />
|
|
18
|
+
</ContextMenuBase>
|
|
27
19
|
);
|
|
28
20
|
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { DropdownBase, IconButton } from '../';
|
|
3
|
+
import type { DropdownPlacement } from '../';
|
|
4
|
+
import styles from './contextMenuBase.module.css';
|
|
5
|
+
|
|
6
|
+
export interface ContextMenuBaseProps {
|
|
7
|
+
placement: DropdownPlacement;
|
|
8
|
+
expanded: boolean;
|
|
9
|
+
onToggle?: () => void;
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ContextMenuBase = ({
|
|
14
|
+
placement = 'right',
|
|
15
|
+
expanded = false,
|
|
16
|
+
onToggle,
|
|
17
|
+
children,
|
|
18
|
+
}: ContextMenuBaseProps) => {
|
|
19
|
+
return (
|
|
20
|
+
<div className={styles.toggle}>
|
|
21
|
+
<IconButton
|
|
22
|
+
className={styles.button}
|
|
23
|
+
icon="menu-elipsis-horizontal"
|
|
24
|
+
variant="text"
|
|
25
|
+
color="secondary"
|
|
26
|
+
onClick={onToggle}
|
|
27
|
+
/>
|
|
28
|
+
<DropdownBase className={styles.dropdown} placement={placement} expanded={expanded}>
|
|
29
|
+
{children}
|
|
30
|
+
</DropdownBase>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -8,11 +8,15 @@ const meta = {
|
|
|
8
8
|
parameters: {},
|
|
9
9
|
argTypes: { body: { control: 'text' } },
|
|
10
10
|
args: {
|
|
11
|
-
menu:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
menu: {
|
|
12
|
+
id: 'context-menu',
|
|
13
|
+
items: [
|
|
14
|
+
{
|
|
15
|
+
label: 'Fjern',
|
|
16
|
+
id: 'remove',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
},
|
|
16
20
|
updatedAt: '1999-05-26',
|
|
17
21
|
updatedAtLabel: '26. mai 1999',
|
|
18
22
|
title: 'Title',
|
|
@@ -42,9 +46,11 @@ export const Attachments: Story = {
|
|
|
42
46
|
items: [
|
|
43
47
|
{
|
|
44
48
|
label: 'Dokument 1.pdf',
|
|
49
|
+
href: '',
|
|
45
50
|
},
|
|
46
51
|
{
|
|
47
52
|
label: 'Dokument 2.pdf',
|
|
53
|
+
href: '',
|
|
48
54
|
},
|
|
49
55
|
],
|
|
50
56
|
},
|
|
@@ -106,6 +112,7 @@ export const Example: Story = {
|
|
|
106
112
|
items: [
|
|
107
113
|
{
|
|
108
114
|
label: 'Vedtak om innlevering av bedriftsdata.pdf',
|
|
115
|
+
href: '',
|
|
109
116
|
},
|
|
110
117
|
],
|
|
111
118
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { Heading, ListBase, SectionBase, SectionHeader } from '../';
|
|
3
|
+
import { Button } from '../Button';
|
|
4
|
+
|
|
5
|
+
export interface DialogGroupProps {
|
|
6
|
+
title?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const DialogGroup = ({ title, children }: DialogGroupProps) => {
|
|
11
|
+
return (
|
|
12
|
+
<SectionBase spacing="md">
|
|
13
|
+
{title && (
|
|
14
|
+
<SectionHeader padding margin>
|
|
15
|
+
<Heading>{title}</Heading>
|
|
16
|
+
<Button variant="text" icon="checkmark" size="sm" reverse>
|
|
17
|
+
Velg alle
|
|
18
|
+
</Button>
|
|
19
|
+
</SectionHeader>
|
|
20
|
+
)}
|
|
21
|
+
<ListBase spacing="md">{children}</ListBase>
|
|
22
|
+
</SectionBase>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { fn } from '@storybook/test';
|
|
3
|
-
|
|
4
2
|
import { DialogList } from './DialogList';
|
|
5
3
|
|
|
6
4
|
const meta = {
|
|
@@ -16,26 +14,31 @@ const meta = {
|
|
|
16
14
|
title: 'Støtte til utbygging av solceller',
|
|
17
15
|
summary: 'Din støtte er innvilget',
|
|
18
16
|
status: { value: 'draft' },
|
|
17
|
+
groupId: '2024-01',
|
|
19
18
|
},
|
|
20
19
|
{
|
|
21
20
|
title: 'Støtte til utbygging av solceller',
|
|
22
21
|
summary: 'Din støtte er innvilget',
|
|
23
22
|
status: { value: 'sent' },
|
|
23
|
+
groupId: '2024-02',
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
title: 'Støtte til utbygging av solceller',
|
|
27
27
|
summary: 'Din støtte er innvilget',
|
|
28
28
|
status: { value: 'requires-attention' },
|
|
29
|
+
groupId: '2024-01',
|
|
29
30
|
},
|
|
30
31
|
{
|
|
31
32
|
title: 'Støtte til utbygging av solceller',
|
|
32
33
|
summary: 'Din støtte er innvilget',
|
|
33
34
|
status: { value: 'in-progress' },
|
|
35
|
+
groupId: '2024-02',
|
|
34
36
|
},
|
|
35
37
|
{
|
|
36
38
|
title: 'Støtte til utbygging av solceller',
|
|
37
39
|
summary: 'Din støtte er innvilget.',
|
|
38
40
|
status: { value: 'completed' },
|
|
41
|
+
groupId: '2024-01',
|
|
39
42
|
},
|
|
40
43
|
],
|
|
41
44
|
},
|
|
@@ -48,14 +51,15 @@ export const Default: Story = {
|
|
|
48
51
|
args: {},
|
|
49
52
|
};
|
|
50
53
|
|
|
51
|
-
export const
|
|
54
|
+
export const Grouped: Story = {
|
|
52
55
|
args: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
groups: {
|
|
57
|
+
'2024-01': {
|
|
58
|
+
title: 'Januar 2024',
|
|
59
|
+
},
|
|
60
|
+
'2024-02': {
|
|
61
|
+
title: 'Februar 2024',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
60
64
|
},
|
|
61
65
|
};
|
|
@@ -1,20 +1,35 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { SectionBase } from '../';
|
|
2
|
+
import { useMenu } from '../../hooks';
|
|
3
|
+
import { DialogGroup, type DialogGroupProps } from './DialogGroup';
|
|
3
4
|
import { DialogListItem, type DialogListItemProps } from './DialogListItem';
|
|
4
|
-
import type { DialogListItemSize } from './DialogListItemBase';
|
|
5
5
|
|
|
6
6
|
export interface DialogListProps {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
items?: DialogListItemProps[];
|
|
7
|
+
items: DialogListItemProps[];
|
|
8
|
+
groups?: Record<string, DialogGroupProps>;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
export const DialogList = ({
|
|
11
|
+
export const DialogList = ({ items, groups = {} }: DialogListProps) => {
|
|
12
|
+
const { menu } = useMenu<DialogListItemProps, DialogGroupProps>({
|
|
13
|
+
items,
|
|
14
|
+
groups,
|
|
15
|
+
groupByKey: 'groupId',
|
|
16
|
+
keyboardEvents: false,
|
|
17
|
+
});
|
|
18
|
+
|
|
13
19
|
return (
|
|
14
|
-
<
|
|
15
|
-
{
|
|
16
|
-
|
|
20
|
+
<SectionBase spacing="none" margin="md">
|
|
21
|
+
{menu?.map((group, groupIndex) => {
|
|
22
|
+
const groupProps = group.props || {};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<DialogGroup {...groupProps} key={groupIndex}>
|
|
26
|
+
{group?.items.map((item, index) => {
|
|
27
|
+
const itemProps = item.props || {};
|
|
28
|
+
return <DialogListItem {...itemProps} key={index} />;
|
|
29
|
+
})}
|
|
30
|
+
</DialogGroup>
|
|
31
|
+
);
|
|
17
32
|
})}
|
|
18
|
-
</
|
|
33
|
+
</SectionBase>
|
|
19
34
|
);
|
|
20
35
|
};
|
|
@@ -55,6 +55,8 @@ export type DialogListItemProps = {
|
|
|
55
55
|
attachmentsCount?: number;
|
|
56
56
|
/** OnClick handler */
|
|
57
57
|
onClick?: () => void;
|
|
58
|
+
/** Group id */
|
|
59
|
+
groupId?: string;
|
|
58
60
|
};
|
|
59
61
|
|
|
60
62
|
/**
|
|
@@ -68,6 +70,7 @@ export const DialogListItem = ({
|
|
|
68
70
|
size = 'lg',
|
|
69
71
|
variant = 'neutral',
|
|
70
72
|
href,
|
|
73
|
+
onClick,
|
|
71
74
|
select,
|
|
72
75
|
selected,
|
|
73
76
|
status,
|
|
@@ -84,10 +87,17 @@ export const DialogListItem = ({
|
|
|
84
87
|
attachmentsCount,
|
|
85
88
|
title,
|
|
86
89
|
summary,
|
|
87
|
-
...rest
|
|
88
90
|
}: DialogListItemProps) => {
|
|
89
91
|
return (
|
|
90
|
-
<DialogListItemBase
|
|
92
|
+
<DialogListItemBase
|
|
93
|
+
as={as}
|
|
94
|
+
size={size}
|
|
95
|
+
href={href}
|
|
96
|
+
select={select}
|
|
97
|
+
selected={selected}
|
|
98
|
+
variant={variant}
|
|
99
|
+
onClick={onClick}
|
|
100
|
+
>
|
|
91
101
|
<DialogBorder className={styles.border} size={size} seen={seen}>
|
|
92
102
|
<header data-size={size} className={styles.header}>
|
|
93
103
|
<DialogTitle size={size} seen={seen} variant={variant}>
|
|
@@ -20,6 +20,8 @@ export type DialogListItemBaseProps = {
|
|
|
20
20
|
children?: ReactNode;
|
|
21
21
|
/** Variant */
|
|
22
22
|
variant?: DialogListItemVariant;
|
|
23
|
+
/** OnClick handler */
|
|
24
|
+
onClick?: () => void;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
/**
|
|
@@ -35,13 +37,13 @@ export const DialogListItemBase = ({
|
|
|
35
37
|
select,
|
|
36
38
|
selected,
|
|
37
39
|
children,
|
|
38
|
-
|
|
40
|
+
onClick,
|
|
39
41
|
}: DialogListItemBaseProps) => {
|
|
40
42
|
const Component = as || 'button';
|
|
41
43
|
|
|
42
44
|
return (
|
|
43
45
|
<article className={styles.item} data-size={size} aria-selected={selected}>
|
|
44
|
-
<Component className={styles.link} data-size={size} href={href} {
|
|
46
|
+
<Component className={styles.link} data-size={size} href={href} onClick={onClick} tabIndex={0}>
|
|
45
47
|
{children}
|
|
46
48
|
</Component>
|
|
47
49
|
{select && <DialogSelect className={styles.select} {...select} />}
|
|
@@ -54,31 +54,31 @@ export const ContextMenu: Story = {
|
|
|
54
54
|
items: [
|
|
55
55
|
{
|
|
56
56
|
id: '1',
|
|
57
|
-
|
|
57
|
+
groupId: '1',
|
|
58
58
|
icon: 'arrow-redo',
|
|
59
59
|
label: 'Del og gi tilgang',
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
id: '2',
|
|
63
|
-
|
|
63
|
+
groupId: '1',
|
|
64
64
|
icon: 'eye-closed',
|
|
65
65
|
label: 'Marker som ny',
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
68
|
id: '3',
|
|
69
|
-
|
|
69
|
+
groupId: '2',
|
|
70
70
|
icon: 'archive',
|
|
71
71
|
label: 'Flytt til arkiv',
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
74
|
id: '4',
|
|
75
|
-
|
|
75
|
+
groupId: '2',
|
|
76
76
|
icon: 'trash',
|
|
77
77
|
label: 'Flytt til papirkurv',
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
id: '5',
|
|
81
|
-
|
|
81
|
+
groupId: '3',
|
|
82
82
|
icon: 'clock-dashed',
|
|
83
83
|
label: 'Aktivitetslogg',
|
|
84
84
|
},
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useState } from 'react';
|
|
3
2
|
import type { ElementType } from 'react';
|
|
4
3
|
import { Button } from '../Button';
|
|
5
|
-
import { ContextMenu, type ContextMenuProps } from '../ContextMenu
|
|
4
|
+
import { ContextMenu, type ContextMenuProps } from '../ContextMenu';
|
|
6
5
|
import { MetaTimestamp } from '../Meta';
|
|
7
6
|
import { DialogStatus, type DialogStatusProps } from './DialogStatus';
|
|
8
7
|
import { DialogTouchedBy, type DialogTouchedByActor } from './DialogTouchedBy';
|
|
@@ -37,9 +36,6 @@ export const DialogNav = ({
|
|
|
37
36
|
touchedBy,
|
|
38
37
|
menu,
|
|
39
38
|
}: DialogNavProps) => {
|
|
40
|
-
const [expandedItem, setexpandedItem] = useState<boolean>(false);
|
|
41
|
-
const onToggle = () => setexpandedItem((expanded) => !expanded);
|
|
42
|
-
|
|
43
39
|
return (
|
|
44
40
|
<nav className={styles.nav}>
|
|
45
41
|
<Button {...backButton} variant="text" color="secondary" icon="arrow-left" reverse>
|
|
@@ -53,7 +49,7 @@ export const DialogNav = ({
|
|
|
53
49
|
)}
|
|
54
50
|
{status && <DialogStatus {...status} />}
|
|
55
51
|
{touchedBy && <DialogTouchedBy touchedBy={touchedBy} />}
|
|
56
|
-
{menu && <ContextMenu {...menu}
|
|
52
|
+
{menu && <ContextMenu {...menu} />}
|
|
57
53
|
</div>
|
|
58
54
|
</nav>
|
|
59
55
|
);
|
|
@@ -16,7 +16,7 @@ export type DialogSelectProps = {
|
|
|
16
16
|
export const DialogSelect = ({ checked = false, onChange, className }: DialogSelectProps) => {
|
|
17
17
|
return (
|
|
18
18
|
<label className={cx(styles.label, className)}>
|
|
19
|
-
<input type="checkbox" checked={checked} onChange={onChange} className={styles.input} />
|
|
19
|
+
<input type="checkbox" checked={checked} onChange={onChange} className={styles.input} tabIndex={-1} />
|
|
20
20
|
<CheckboxIcon hover={true} checked={checked} className={styles.icon} />
|
|
21
21
|
</label>
|
|
22
22
|
);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.section {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
row-gap: 0.5rem;
|
|
5
|
+
margin: 0.5rem 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.header {
|
|
9
|
+
display: flex;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
margin: 0.5rem 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.title {
|
|
15
|
+
font-size: 1.25rem;
|
|
16
|
+
font-weight: 500;
|
|
17
|
+
line-height: 1.5rem;
|
|
18
|
+
margin: 0.375rem 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.title {
|
|
22
|
+
padding: 0 1rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (min-width: 1024px) {
|
|
26
|
+
.title {
|
|
27
|
+
padding: 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.list {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
row-gap: 0.5rem;
|
|
35
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import cx from 'classnames';
|
|
2
|
+
import type { MouseEventHandler } from 'react';
|
|
2
3
|
import styles from './backdrop.module.css';
|
|
3
4
|
|
|
4
5
|
export interface BackdropProps {
|
|
5
|
-
expanded?: boolean;
|
|
6
6
|
className?: string;
|
|
7
|
+
onClick?: MouseEventHandler;
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
export const Backdrop = ({
|
|
10
|
-
return <div className={cx(styles.backdrop, className)}
|
|
10
|
+
export const Backdrop = ({ className, onClick }: BackdropProps) => {
|
|
11
|
+
return <div className={cx(styles.backdrop, className)} onMouseDown={onClick} />;
|
|
11
12
|
};
|
|
@@ -2,15 +2,18 @@ import cx from 'classnames';
|
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import styles from './drawerBase.module.css';
|
|
4
4
|
|
|
5
|
+
export type DrawerPlacement = 'inline' | 'bottom';
|
|
6
|
+
|
|
5
7
|
export interface DrawerBaseProps {
|
|
8
|
+
placement?: DrawerPlacement;
|
|
6
9
|
expanded?: boolean;
|
|
7
10
|
className?: string;
|
|
8
11
|
children?: ReactNode;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
export const DrawerBase = ({ expanded = false, className, children }: DrawerBaseProps) => {
|
|
14
|
+
export const DrawerBase = ({ placement = 'inline', expanded = false, className, children }: DrawerBaseProps) => {
|
|
12
15
|
return (
|
|
13
|
-
<div className={cx(styles.drawer, className)} aria-expanded={expanded}>
|
|
16
|
+
<div className={cx(styles.drawer, className)} data-placement={placement} aria-expanded={expanded}>
|
|
14
17
|
{children}
|
|
15
18
|
</div>
|
|
16
19
|
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import styles from './drawerBody.module.css';
|
|
4
|
+
|
|
5
|
+
export interface DrawerBodyProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const DrawerBody = ({ className, children }: DrawerBodyProps) => {
|
|
11
|
+
return <div className={cx(styles.body, className)}>{children}</div>;
|
|
12
|
+
};
|