@altinn/altinn-components 0.5.1 → 0.6.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/CHANGELOG.md +14 -0
- package/lib/components/Bookmarks/BookmarksList.tsx +17 -0
- package/lib/components/Bookmarks/BookmarksListItem.stories.tsx +79 -0
- package/lib/components/Bookmarks/BookmarksListItem.tsx +32 -0
- package/lib/components/Bookmarks/QueryLabel.tsx +33 -0
- package/lib/components/Bookmarks/index.ts +3 -0
- package/lib/components/Bookmarks/queryLabel.module.css +45 -0
- package/lib/components/Button/ButtonBase.tsx +2 -1
- package/lib/components/Button/IconButton.tsx +3 -1
- package/lib/components/ContextMenu/ContextMenuBase.tsx +3 -1
- package/lib/components/Datepicker/Datepicker.tsx +49 -0
- package/lib/components/Datepicker/DatepickerBase.tsx +12 -0
- package/lib/components/Datepicker/DatepickerHeader.tsx +20 -0
- package/lib/components/Datepicker/DatepickerTable.tsx +50 -0
- package/lib/components/Datepicker/datepickerBase.module.css +5 -0
- package/lib/components/Datepicker/datepickerHeader.module.css +17 -0
- package/lib/components/Datepicker/datepickerTable.module.css +37 -0
- package/lib/components/Datepicker/index.ts +1 -0
- package/lib/components/Datepicker/useDatepicker.tsx +146 -0
- package/lib/components/Dropdown/DrawerOrDropdown.tsx +1 -1
- package/lib/components/Dropdown/dropdownBase.module.css +2 -1
- package/lib/components/Footer/FooterMenu.tsx +1 -1
- package/lib/components/GlobalMenu/AccountButton.tsx +20 -3
- package/lib/components/GlobalMenu/AccountMenu.tsx +13 -4
- package/lib/components/GlobalMenu/GlobalMenu.stories.tsx +6 -6
- package/lib/components/GlobalMenu/GlobalMenu.tsx +36 -24
- package/lib/components/Header/Header.stories.tsx +24 -8
- package/lib/components/Header/Header.tsx +15 -16
- package/lib/components/Header/HeaderButton.tsx +1 -0
- package/lib/components/Header/HeaderSearch.tsx +17 -0
- package/lib/components/Header/header.module.css +0 -21
- package/lib/components/Header/headerSearch.module.css +21 -0
- package/lib/components/History/HistoryList.stories.ts +3 -1
- package/lib/components/Layout/Layout.stories.tsx +7 -2
- package/lib/components/List/ListItemBase.tsx +4 -0
- package/lib/components/List/listBase.module.css +14 -0
- package/lib/components/List/listItemBase.module.css +9 -2
- package/lib/components/Menu/MenuInputField.tsx +38 -0
- package/lib/components/Menu/MenuItemBase.tsx +1 -1
- package/lib/components/Menu/MenuOption.tsx +1 -1
- package/lib/components/Menu/index.ts +1 -0
- package/lib/components/Menu/menuInputField.module.css +54 -0
- package/lib/components/Menu/menuItemBase.module.css +7 -0
- package/lib/components/Page/PageHeader.tsx +10 -6
- package/lib/components/Page/PageNav.tsx +34 -0
- package/lib/components/Page/pageHeader.module.css +13 -0
- package/lib/components/Page/pageNav.module.css +12 -0
- package/lib/components/Page/sectionBase.module.css +11 -1
- package/lib/components/RootProvider/RootProvider.tsx +1 -0
- package/lib/components/Searchbar/SearchField.tsx +4 -1
- package/lib/components/Searchbar/Searchbar.tsx +10 -2
- package/lib/components/Toolbar/Toolbar.tsx +4 -1
- package/lib/components/Toolbar/ToolbarAdd.tsx +3 -3
- package/lib/components/Toolbar/ToolbarDate.stories.ts +62 -0
- package/lib/components/Toolbar/ToolbarDaterange.stories.ts +24 -0
- package/lib/components/Toolbar/ToolbarDaterange.tsx +73 -0
- package/lib/components/Toolbar/ToolbarFilter.tsx +12 -5
- package/lib/components/Toolbar/ToolbarFilterBase.tsx +15 -0
- package/lib/components/Toolbar/ToolbarMenu.tsx +3 -3
- package/lib/components/Toolbar/ToolbarOptions.tsx +2 -2
- package/lib/components/Toolbar/toolbarDaterange.module.css +12 -0
- package/lib/components/Toolbar/{toolbarAdd.module.css → toolbarFilterBase.module.css} +2 -2
- package/lib/components/Typography/heading.module.css +1 -1
- package/lib/components/index.ts +3 -1
- package/lib/css/global.css +1 -0
- package/lib/hooks/useMenu.tsx +1 -0
- package/lib/stories/Inbox/BookmarksPage.tsx +38 -12
- package/lib/stories/Inbox/InboxLayout.tsx +1 -0
- package/lib/stories/Inbox/InboxPage.tsx +1 -0
- package/lib/stories/Inbox/InboxProvider.tsx +1 -1
- package/lib/stories/Inbox/InboxToolbar.tsx +3 -3
- package/lib/stories/Inbox/ProfilePage.tsx +1 -0
- package/lib/stories/Inbox/dialogs/brreg-draft.json +5 -9
- package/lib/stories/Inbox/dialogs/enova-in-progress.json +35 -0
- package/lib/stories/Inbox/dialogs/index.ts +44 -1
- package/lib/stories/Inbox/dialogs/sykmelding-referat.json +41 -0
- package/package.json +2 -2
- package/lib/components/Toolbar/toolbarFilter.module.css +0 -25
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MenuItemBase, MenuItemLabel, MenuItemMedia } from '../Menu';
|
|
2
2
|
|
|
3
|
-
type Account = {
|
|
3
|
+
export type Account = {
|
|
4
|
+
id: string;
|
|
4
5
|
type: 'person' | 'company';
|
|
5
6
|
name: string;
|
|
6
7
|
description?: string;
|
|
@@ -11,11 +12,27 @@ export type AccountButtonProps = {
|
|
|
11
12
|
description?: string;
|
|
12
13
|
linkText?: string;
|
|
13
14
|
onClick?: () => void;
|
|
15
|
+
multipleAccounts?: boolean;
|
|
14
16
|
};
|
|
15
17
|
|
|
16
|
-
export const AccountButton = ({ account, linkText, onClick }: AccountButtonProps) => {
|
|
18
|
+
export const AccountButton = ({ account, linkText, onClick, multipleAccounts }: AccountButtonProps) => {
|
|
19
|
+
if (multipleAccounts) {
|
|
20
|
+
return (
|
|
21
|
+
<MenuItemBase size="lg" onClick={onClick} linkText={linkText} linkIcon="arrow-right" as="button">
|
|
22
|
+
<MenuItemMedia
|
|
23
|
+
size="lg"
|
|
24
|
+
avatar={{
|
|
25
|
+
name: account.name,
|
|
26
|
+
type: account.type,
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
<MenuItemLabel size="lg" title={account?.name} description={account?.description} />
|
|
30
|
+
</MenuItemBase>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
17
34
|
return (
|
|
18
|
-
<MenuItemBase size="lg"
|
|
35
|
+
<MenuItemBase size="lg" as="div">
|
|
19
36
|
<MenuItemMedia
|
|
20
37
|
size="lg"
|
|
21
38
|
avatar={{
|
|
@@ -10,7 +10,7 @@ export interface AccountSearch extends MenuSearchProps {
|
|
|
10
10
|
export interface AccountMenuItem {
|
|
11
11
|
type: 'person' | 'company';
|
|
12
12
|
name: string;
|
|
13
|
-
id
|
|
13
|
+
id: string;
|
|
14
14
|
groupId?: string;
|
|
15
15
|
selected?: boolean;
|
|
16
16
|
}
|
|
@@ -19,20 +19,29 @@ export interface AccountMenuProps {
|
|
|
19
19
|
accounts?: AccountMenuItem[];
|
|
20
20
|
accountGroups?: MenuItemGroups;
|
|
21
21
|
accountSearch?: AccountSearch;
|
|
22
|
+
currentAccount?: AccountMenuItem;
|
|
23
|
+
onSelectAccount?: (id: string) => void;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const defaultResultLabel = (hits: number) => `${hits} hits`;
|
|
25
27
|
|
|
26
|
-
export const AccountMenu = ({
|
|
28
|
+
export const AccountMenu = ({
|
|
29
|
+
accounts = [],
|
|
30
|
+
accountGroups = {},
|
|
31
|
+
accountSearch,
|
|
32
|
+
onSelectAccount,
|
|
33
|
+
currentAccount,
|
|
34
|
+
}: AccountMenuProps) => {
|
|
27
35
|
const accountMenu: MenuItemProps[] = accounts.map((account) => ({
|
|
28
|
-
id: account.name,
|
|
36
|
+
id: account.id || account.name,
|
|
29
37
|
groupId: account.groupId || 'search',
|
|
30
|
-
selected: account.selected,
|
|
38
|
+
selected: account.selected ?? currentAccount?.id === account.id,
|
|
31
39
|
title: account.name,
|
|
32
40
|
avatar: {
|
|
33
41
|
type: account.type,
|
|
34
42
|
name: account.name,
|
|
35
43
|
},
|
|
44
|
+
onClick: () => onSelectAccount?.(account.id || account.name),
|
|
36
45
|
}));
|
|
37
46
|
|
|
38
47
|
const [filterString, setFilterString] = useState<string>('');
|
|
@@ -23,40 +23,40 @@ const meta = {
|
|
|
23
23
|
},
|
|
24
24
|
accounts: [
|
|
25
25
|
{
|
|
26
|
+
id: 'party:mathias',
|
|
26
27
|
groupId: 'primary',
|
|
27
28
|
type: 'person',
|
|
28
29
|
name: 'Mathias Dyngeland',
|
|
29
|
-
selected: true,
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
|
+
id: 'party:bergerbar',
|
|
32
33
|
groupId: 'favourites',
|
|
33
34
|
type: 'company',
|
|
34
35
|
name: 'Bergen bar',
|
|
35
|
-
selected: false,
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
+
id: 'party:keeperhansker',
|
|
38
39
|
groupId: 'secondary',
|
|
39
40
|
type: 'company',
|
|
40
41
|
name: 'Keeperhansker AS',
|
|
41
|
-
selected: false,
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
+
id: 'party:stadiondrift',
|
|
44
45
|
groupId: 'secondary',
|
|
45
46
|
type: 'company',
|
|
46
47
|
name: 'Stadion drift AS',
|
|
47
|
-
selected: false,
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
|
+
id: 'party:brann',
|
|
50
51
|
groupId: 'favourites',
|
|
51
52
|
type: 'company',
|
|
52
53
|
name: 'Sportsklubben Brann',
|
|
53
|
-
selected: false,
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
|
+
id: 'party:landslaget',
|
|
56
57
|
groupId: 'secondary',
|
|
57
58
|
type: 'company',
|
|
58
59
|
name: 'Landslaget',
|
|
59
|
-
selected: false,
|
|
60
60
|
},
|
|
61
61
|
],
|
|
62
62
|
groups: {
|
|
@@ -1,67 +1,79 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'react';
|
|
3
3
|
import { Menu, type MenuItemGroups, type MenuItemProps } from '../Menu';
|
|
4
|
-
import { AccountButton } from './AccountButton';
|
|
4
|
+
import { type Account, AccountButton } from './AccountButton';
|
|
5
5
|
import { AccountMenu, type AccountMenuProps } from './AccountMenu';
|
|
6
6
|
import { BackButton } from './BackButton';
|
|
7
7
|
import { GlobalMenuBase, GlobalMenuFooter, GlobalMenuHeader } from './GlobalMenuBase';
|
|
8
|
-
import { LogoutButton } from './LogoutButton';
|
|
9
|
-
|
|
10
|
-
export interface CurrentAccount {
|
|
11
|
-
type: 'person' | 'company';
|
|
12
|
-
name: string;
|
|
13
|
-
description?: string;
|
|
14
|
-
}
|
|
8
|
+
import { LogoutButton, type LogoutButtonProps } from './LogoutButton';
|
|
15
9
|
|
|
16
10
|
export interface GlobalMenuProps extends AccountMenuProps {
|
|
17
|
-
currentEndUser?: CurrentAccount;
|
|
18
|
-
expanded: boolean;
|
|
19
|
-
onToggle: MouseEventHandler;
|
|
20
11
|
items: MenuItemProps[];
|
|
21
12
|
groups?: MenuItemGroups;
|
|
22
13
|
menuLabel?: string;
|
|
23
14
|
backLabel?: string;
|
|
15
|
+
logoutButton?: LogoutButtonProps;
|
|
24
16
|
changeLabel?: string;
|
|
25
|
-
logoutLabel?: string;
|
|
26
17
|
className?: string;
|
|
18
|
+
currentAccount?: Account;
|
|
19
|
+
changeCurrentAccount?: (id: string) => void;
|
|
27
20
|
}
|
|
28
21
|
|
|
29
22
|
export const GlobalMenu = ({
|
|
30
|
-
currentEndUser,
|
|
31
23
|
accounts = [],
|
|
32
24
|
accountGroups = {},
|
|
33
25
|
accountSearch,
|
|
34
26
|
items = [],
|
|
35
27
|
groups,
|
|
36
28
|
changeLabel = 'Change',
|
|
37
|
-
logoutLabel = 'Logout',
|
|
38
29
|
backLabel = 'Back',
|
|
30
|
+
currentAccount,
|
|
31
|
+
changeCurrentAccount,
|
|
32
|
+
logoutButton,
|
|
39
33
|
}: GlobalMenuProps) => {
|
|
40
|
-
const [
|
|
34
|
+
const [selectingAccount, setSelectingAccount] = useState<boolean>(false);
|
|
41
35
|
|
|
42
36
|
const onToggleAccounts = () => {
|
|
43
|
-
|
|
37
|
+
setSelectingAccount((prevState) => !prevState);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const onSelectAccount = (id: string) => {
|
|
41
|
+
onToggleAccounts();
|
|
42
|
+
changeCurrentAccount?.(id);
|
|
44
43
|
};
|
|
45
44
|
|
|
46
|
-
if (
|
|
45
|
+
if (selectingAccount) {
|
|
47
46
|
return (
|
|
48
47
|
<GlobalMenuBase>
|
|
49
48
|
<BackButton onClick={onToggleAccounts} label={backLabel} />
|
|
50
|
-
<AccountMenu
|
|
49
|
+
<AccountMenu
|
|
50
|
+
currentAccount={currentAccount}
|
|
51
|
+
accounts={accounts}
|
|
52
|
+
accountGroups={accountGroups}
|
|
53
|
+
accountSearch={accountSearch}
|
|
54
|
+
onSelectAccount={onSelectAccount}
|
|
55
|
+
/>
|
|
51
56
|
</GlobalMenuBase>
|
|
52
57
|
);
|
|
53
58
|
}
|
|
54
59
|
|
|
55
|
-
if (
|
|
60
|
+
if (currentAccount) {
|
|
56
61
|
return (
|
|
57
62
|
<GlobalMenuBase>
|
|
58
63
|
<GlobalMenuHeader>
|
|
59
|
-
<AccountButton
|
|
64
|
+
<AccountButton
|
|
65
|
+
account={currentAccount}
|
|
66
|
+
linkText={changeLabel}
|
|
67
|
+
multipleAccounts={accounts.length > 1}
|
|
68
|
+
onClick={onToggleAccounts}
|
|
69
|
+
/>
|
|
60
70
|
</GlobalMenuHeader>
|
|
61
71
|
<Menu groups={groups} items={items} />
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
72
|
+
{logoutButton && (
|
|
73
|
+
<GlobalMenuFooter>
|
|
74
|
+
<LogoutButton {...logoutButton} />
|
|
75
|
+
</GlobalMenuFooter>
|
|
76
|
+
)}
|
|
65
77
|
</GlobalMenuBase>
|
|
66
78
|
);
|
|
67
79
|
}
|
|
@@ -25,46 +25,46 @@ const meta = {
|
|
|
25
25
|
},
|
|
26
26
|
accounts: [
|
|
27
27
|
{
|
|
28
|
+
id: 'party:aurora',
|
|
28
29
|
groupId: 'primary',
|
|
29
30
|
type: 'person',
|
|
30
31
|
name: 'Aurora Mikalsen',
|
|
31
|
-
selected: true,
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
|
+
id: 'party:rakel',
|
|
34
35
|
groupId: 'favourites',
|
|
35
36
|
type: 'person',
|
|
36
37
|
name: 'Rakel Engelsvik',
|
|
37
|
-
selected: false,
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
+
id: 'party:auroraskeeperskole',
|
|
40
41
|
groupId: 'favourites',
|
|
41
42
|
type: 'company',
|
|
42
43
|
name: 'Auroras keeperskole',
|
|
43
|
-
selected: false,
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
+
id: 'party:aurorashandsker',
|
|
46
47
|
groupId: 'secondary',
|
|
47
48
|
type: 'company',
|
|
48
49
|
name: 'Keeperhansker AS',
|
|
49
|
-
selected: false,
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
|
+
id: 'party:aurorasfotballskole',
|
|
52
53
|
groupId: 'secondary',
|
|
53
54
|
type: 'company',
|
|
54
55
|
name: 'Stadion drift AS',
|
|
55
|
-
selected: false,
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
|
+
id: 'party:aurorasfotballskole',
|
|
58
59
|
groupId: 'secondary',
|
|
59
60
|
type: 'company',
|
|
60
61
|
name: 'Sportsklubben Brann',
|
|
61
|
-
selected: false,
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
|
+
id: 'party:aurorasfotballskole',
|
|
64
65
|
groupId: 'secondary',
|
|
65
66
|
type: 'company',
|
|
66
67
|
name: 'Landslaget',
|
|
67
|
-
selected: false,
|
|
68
68
|
},
|
|
69
69
|
],
|
|
70
70
|
items: [
|
|
@@ -94,10 +94,20 @@ const meta = {
|
|
|
94
94
|
export default meta;
|
|
95
95
|
type Story = StoryObj<typeof meta>;
|
|
96
96
|
|
|
97
|
-
export const Default: Story = {
|
|
97
|
+
export const Default: Story = {
|
|
98
|
+
args: {
|
|
99
|
+
currentAccount: {
|
|
100
|
+
id: 'party:aurora',
|
|
101
|
+
type: 'person',
|
|
102
|
+
name: 'Aurora Mikalsen',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
98
106
|
|
|
99
107
|
export const ControlledState = (args) => {
|
|
100
108
|
const [q, setQ] = useState<string>('');
|
|
109
|
+
const currentEndUserId = 'party:aurora';
|
|
110
|
+
const [selectedAccountId, setSelectedAccountId] = useState<string>(currentEndUserId);
|
|
101
111
|
const onChange = (event) => {
|
|
102
112
|
setQ(event.target.value);
|
|
103
113
|
};
|
|
@@ -160,6 +170,12 @@ export const ControlledState = (args) => {
|
|
|
160
170
|
return (
|
|
161
171
|
<Header
|
|
162
172
|
{...args}
|
|
173
|
+
currentAccount={args.menu.accounts.find((account) => account.id === selectedAccountId)}
|
|
174
|
+
menu={{
|
|
175
|
+
...args.menu,
|
|
176
|
+
...args.menu.accounts,
|
|
177
|
+
changeCurrentAccount: setSelectedAccountId,
|
|
178
|
+
}}
|
|
163
179
|
search={{
|
|
164
180
|
...args.search,
|
|
165
181
|
value: q,
|
|
@@ -2,26 +2,24 @@
|
|
|
2
2
|
import { useEscapeKey } from '../../hooks';
|
|
3
3
|
import { DrawerBase, DropdownBase } from '../Dropdown';
|
|
4
4
|
import { GlobalMenu, type GlobalMenuProps } from '../GlobalMenu';
|
|
5
|
+
import type { Account } from '../GlobalMenu/AccountButton.tsx';
|
|
5
6
|
import { useRootContext } from '../RootProvider';
|
|
6
7
|
import { Searchbar, type SearchbarProps } from '../Searchbar';
|
|
7
8
|
import { HeaderBase } from './HeaderBase';
|
|
8
9
|
import { HeaderButton } from './HeaderButton';
|
|
9
10
|
import { HeaderLogo } from './HeaderLogo';
|
|
10
11
|
import { HeaderMenu } from './HeaderMenu';
|
|
12
|
+
import { HeaderSearch } from './HeaderSearch';
|
|
11
13
|
import styles from './header.module.css';
|
|
12
14
|
|
|
13
15
|
export interface HeaderProps {
|
|
14
16
|
menu: GlobalMenuProps;
|
|
15
17
|
search?: SearchbarProps;
|
|
18
|
+
currentAccount?: Account;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
export const Header = ({ search, menu }: HeaderProps) => {
|
|
21
|
+
export const Header = ({ search, menu, currentAccount }: HeaderProps) => {
|
|
19
22
|
const { currentId, toggleId, openId, closeAll } = useRootContext();
|
|
20
|
-
const selectedAccount = menu.accounts?.find((account) => account.selected);
|
|
21
|
-
const selectedAvatar = selectedAccount && {
|
|
22
|
-
type: selectedAccount.type,
|
|
23
|
-
name: selectedAccount.name,
|
|
24
|
-
};
|
|
25
23
|
|
|
26
24
|
useEscapeKey(closeAll);
|
|
27
25
|
|
|
@@ -42,29 +40,30 @@ export const Header = ({ search, menu }: HeaderProps) => {
|
|
|
42
40
|
<HeaderLogo className={styles.logo} />
|
|
43
41
|
<HeaderMenu className={styles.menu}>
|
|
44
42
|
<HeaderButton
|
|
45
|
-
avatar={
|
|
43
|
+
avatar={
|
|
44
|
+
currentAccount && {
|
|
45
|
+
type: currentAccount.type,
|
|
46
|
+
name: currentAccount.name,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
46
49
|
onClick={onToggleMenu}
|
|
47
50
|
expanded={currentId === 'menu'}
|
|
48
51
|
label={menu?.menuLabel}
|
|
49
52
|
/>
|
|
50
53
|
{menu && (
|
|
51
54
|
<DropdownBase padding={false} placement="right" expanded={currentId === 'menu'} className={styles.dropdown}>
|
|
52
|
-
<GlobalMenu {...menu}
|
|
55
|
+
<GlobalMenu {...menu} currentAccount={currentAccount} />
|
|
53
56
|
</DropdownBase>
|
|
54
57
|
)}
|
|
55
58
|
</HeaderMenu>
|
|
56
59
|
{search && (
|
|
57
|
-
<
|
|
58
|
-
{...search}
|
|
59
|
-
|
|
60
|
-
expanded={currentId === 'search'}
|
|
61
|
-
onClose={onSearchClose}
|
|
62
|
-
onFocus={onSearchFocus}
|
|
63
|
-
/>
|
|
60
|
+
<HeaderSearch expanded={currentId === 'search'}>
|
|
61
|
+
<Searchbar {...search} expanded={currentId === 'search'} onClose={onSearchClose} onFocus={onSearchFocus} />
|
|
62
|
+
</HeaderSearch>
|
|
64
63
|
)}
|
|
65
64
|
{menu && (
|
|
66
65
|
<DrawerBase expanded={currentId === 'menu'} className={styles.drawer}>
|
|
67
|
-
<GlobalMenu {...menu}
|
|
66
|
+
<GlobalMenu {...menu} currentAccount={currentAccount} />
|
|
68
67
|
</DrawerBase>
|
|
69
68
|
)}
|
|
70
69
|
</HeaderBase>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import styles from './headerSearch.module.css';
|
|
4
|
+
|
|
5
|
+
export interface HeaderSearchProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
expanded?: boolean;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const HeaderSearch = ({ expanded = false, className, children }: HeaderSearchProps) => {
|
|
12
|
+
return (
|
|
13
|
+
<div className={cx(styles.search, className)} aria-expanded={expanded}>
|
|
14
|
+
{children}
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -22,24 +22,3 @@
|
|
|
22
22
|
display: block;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
/* search */
|
|
27
|
-
|
|
28
|
-
.search {
|
|
29
|
-
width: 100%;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@media (min-width: 1024px) {
|
|
33
|
-
.search {
|
|
34
|
-
position: absolute;
|
|
35
|
-
left: 0;
|
|
36
|
-
right: 0;
|
|
37
|
-
margin: 0 auto;
|
|
38
|
-
max-width: 320px;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.search[aria-expanded="true"] {
|
|
42
|
-
z-index: 2;
|
|
43
|
-
max-width: 640px;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
.search {
|
|
2
|
+
width: 100%;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.search[aria-expanded="true"] {
|
|
6
|
+
z-index: 2;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@media (min-width: 1024px) {
|
|
10
|
+
.search {
|
|
11
|
+
position: absolute;
|
|
12
|
+
left: 0;
|
|
13
|
+
right: 0;
|
|
14
|
+
margin: 0 auto;
|
|
15
|
+
max-width: 320px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.search[aria-expanded="true"] {
|
|
19
|
+
max-width: 640px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -11,7 +11,8 @@ const meta = {
|
|
|
11
11
|
args: {
|
|
12
12
|
items: [
|
|
13
13
|
{
|
|
14
|
-
createdAt: '
|
|
14
|
+
createdAt: '2024-09-22 13:34',
|
|
15
|
+
createdAtLabel: '22. september 2024 kl 13.34',
|
|
15
16
|
createdBy: {
|
|
16
17
|
name: 'Eirik Horneland',
|
|
17
18
|
},
|
|
@@ -44,6 +45,7 @@ const meta = {
|
|
|
44
45
|
},
|
|
45
46
|
{
|
|
46
47
|
createdAt: '2004-09-09 13:34',
|
|
48
|
+
createdAtLabel: '22. september 2024 kl 13.34',
|
|
47
49
|
createdBy: {
|
|
48
50
|
name: 'Eirik Horneland',
|
|
49
51
|
},
|
|
@@ -9,12 +9,17 @@ const header: HeaderProps = {
|
|
|
9
9
|
name: 'search',
|
|
10
10
|
placeholder: 'Søk i Altinn',
|
|
11
11
|
},
|
|
12
|
+
currentAccount: {
|
|
13
|
+
id: 'party:aurora',
|
|
14
|
+
type: 'person',
|
|
15
|
+
name: 'Aurora Mikalsen',
|
|
16
|
+
},
|
|
12
17
|
menu: {
|
|
13
18
|
accounts: [
|
|
14
19
|
{
|
|
20
|
+
id: 'party:aurora',
|
|
15
21
|
type: 'person',
|
|
16
22
|
name: 'Aurora Mikalsen',
|
|
17
|
-
selected: true,
|
|
18
23
|
},
|
|
19
24
|
],
|
|
20
25
|
},
|
|
@@ -197,7 +202,7 @@ export const ControlledStateSearch = (args) => {
|
|
|
197
202
|
};
|
|
198
203
|
|
|
199
204
|
export const InboxBulkMode = (args) => {
|
|
200
|
-
const [snackbars,
|
|
205
|
+
const [snackbars, setSnackbars] = useState([]);
|
|
201
206
|
|
|
202
207
|
const [itemsById, setItemsById] = useState({
|
|
203
208
|
1: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import cx from 'classnames';
|
|
2
2
|
import type { ElementType, KeyboardEvent, KeyboardEventHandler, ReactNode } from 'react';
|
|
3
3
|
import { Badge, type BadgeProps } from '../Badge';
|
|
4
|
+
import { ContextMenu, type ContextMenuProps } from '../ContextMenu';
|
|
4
5
|
import { Icon, type IconName } from '../Icon';
|
|
5
6
|
import styles from './listItemBase.module.css';
|
|
6
7
|
|
|
@@ -10,6 +11,7 @@ export type ListItemSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
|
10
11
|
interface ListItemBaseProps {
|
|
11
12
|
as?: ElementType;
|
|
12
13
|
size?: ListItemSize;
|
|
14
|
+
menu?: ContextMenuProps;
|
|
13
15
|
linkIcon?: IconName;
|
|
14
16
|
color?: ListItemColor;
|
|
15
17
|
badge?: BadgeProps;
|
|
@@ -39,6 +41,7 @@ export const ListItemBase = ({
|
|
|
39
41
|
selected,
|
|
40
42
|
expanded,
|
|
41
43
|
linkIcon,
|
|
44
|
+
menu,
|
|
42
45
|
badge,
|
|
43
46
|
onClick,
|
|
44
47
|
onKeyPress,
|
|
@@ -71,6 +74,7 @@ export const ListItemBase = ({
|
|
|
71
74
|
</div>
|
|
72
75
|
<div className={styles.action}>
|
|
73
76
|
{badge && <Badge {...badge} />}
|
|
77
|
+
{menu && <ContextMenu {...menu} />}
|
|
74
78
|
{applicableIcon && <Icon name={applicableIcon} className={styles.linkIcon} />}
|
|
75
79
|
</div>
|
|
76
80
|
</Component>
|
|
@@ -14,3 +14,17 @@
|
|
|
14
14
|
.list[data-spacing="lg"] {
|
|
15
15
|
row-gap: 16px;
|
|
16
16
|
}
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
|
|
20
|
+
.list[data-spacing="none"] > :first-child {
|
|
21
|
+
border-top-left-radius: 0.25rem;
|
|
22
|
+
border-top-right-radius: 0.25rem;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.list[data-spacing="none"] > :last-child {
|
|
26
|
+
border-bottom-left-radius: 0.25rem;
|
|
27
|
+
border-bottom-right-radius: 0.25rem;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
*/
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/* reset */
|
|
2
2
|
|
|
3
3
|
.item {
|
|
4
|
-
border: none;
|
|
5
|
-
|
|
6
4
|
color: inherit;
|
|
7
5
|
font: inherit;
|
|
8
6
|
text-align: inherit;
|
|
@@ -77,6 +75,15 @@
|
|
|
77
75
|
box-shadow: var(--ds-shadow-xs);
|
|
78
76
|
}
|
|
79
77
|
|
|
78
|
+
.item:hover {
|
|
79
|
+
outline: 2px solid var(--theme-border-strong);
|
|
80
|
+
z-index: 2;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.item:hover strong {
|
|
84
|
+
text-decoration: underline;
|
|
85
|
+
}
|
|
86
|
+
|
|
80
87
|
.item[data-active="true"] {
|
|
81
88
|
background-color: var(--theme-surface-default);
|
|
82
89
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ChangeEventHandler } from 'react';
|
|
2
|
+
import styles from './menuInputField.module.css';
|
|
3
|
+
|
|
4
|
+
type InputType = 'text' | 'date' | 'search';
|
|
5
|
+
|
|
6
|
+
export interface MenuInputFieldProps {
|
|
7
|
+
placeholder?: string;
|
|
8
|
+
type?: InputType;
|
|
9
|
+
label?: string;
|
|
10
|
+
name: string;
|
|
11
|
+
value: string;
|
|
12
|
+
onChange: ChangeEventHandler;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const MenuInputField = ({
|
|
16
|
+
label,
|
|
17
|
+
type = 'text',
|
|
18
|
+
value,
|
|
19
|
+
name,
|
|
20
|
+
placeholder = 'Søk',
|
|
21
|
+
onChange,
|
|
22
|
+
}: MenuInputFieldProps) => {
|
|
23
|
+
return (
|
|
24
|
+
<label className={styles.field}>
|
|
25
|
+
{label && <span className={styles.label}>{label}</span>}
|
|
26
|
+
<input
|
|
27
|
+
data-value={value && true}
|
|
28
|
+
type={type}
|
|
29
|
+
value={value}
|
|
30
|
+
name={name}
|
|
31
|
+
placeholder={placeholder}
|
|
32
|
+
className={styles.input}
|
|
33
|
+
onChange={onChange}
|
|
34
|
+
autoComplete="off"
|
|
35
|
+
/>
|
|
36
|
+
</label>
|
|
37
|
+
);
|
|
38
|
+
};
|