@altinn/altinn-components 0.5.0 → 0.5.2
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/lib/components/Button/ButtonLabel.tsx +4 -2
- package/lib/components/Dialog/Dialog.stories.ts +12 -5
- package/lib/components/Dropdown/DropdownBase.tsx +14 -2
- package/lib/components/Dropdown/dropdownBase.module.css +5 -1
- package/lib/components/GlobalMenu/AccountButton.tsx +30 -0
- package/lib/components/GlobalMenu/AccountMenu.stories.tsx +65 -0
- package/lib/components/GlobalMenu/AccountMenu.tsx +82 -0
- package/lib/components/GlobalMenu/BackButton.tsx +10 -0
- package/lib/components/GlobalMenu/GlobalMenu.stories.tsx +110 -119
- package/lib/components/GlobalMenu/GlobalMenu.tsx +50 -91
- 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.tsx +24 -8
- package/lib/components/Header/Header.tsx +12 -10
- package/lib/components/Layout/Layout.stories.tsx +7 -2
- package/lib/components/Menu/MenuItem.tsx +2 -0
- package/lib/components/Menu/MenuItemBase.tsx +8 -2
- package/lib/components/Menu/menuItemBase.module.css +6 -1
- package/lib/components/Menu/menuItemLabel.module.css +11 -1
- package/lib/components/Menu/menuSearch.module.css +1 -0
- package/lib/stories/Inbox/InboxLayout.tsx +1 -0
- package/lib/stories/Inbox/InboxProvider.tsx +0 -1
- package/package.json +16 -14
- package/lib/components/Menu/__MenuGroup.tsx +0 -18
- package/lib/components/Menu/__menuItem.module.css +0 -130
|
@@ -1,122 +1,81 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { type MouseEventHandler, useState } from 'react';
|
|
3
|
-
import type
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export interface AccountSearch extends MenuSearchProps {
|
|
14
|
-
getResultsLabel?: (hits: number) => string;
|
|
15
|
-
hidden?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type MobileMenuType = 'dropdown' | 'drawer';
|
|
19
|
-
|
|
20
|
-
export interface GlobalMenuProps {
|
|
21
|
-
variant: MobileMenuType;
|
|
3
|
+
import { Menu, type MenuItemGroups, type MenuItemProps } from '../Menu';
|
|
4
|
+
import { type Account, AccountButton } from './AccountButton';
|
|
5
|
+
import { AccountMenu, type AccountMenuProps } from './AccountMenu';
|
|
6
|
+
import { BackButton } from './BackButton';
|
|
7
|
+
import { GlobalMenuBase, GlobalMenuFooter, GlobalMenuHeader } from './GlobalMenuBase';
|
|
8
|
+
import { LogoutButton } from './LogoutButton';
|
|
9
|
+
|
|
10
|
+
export interface GlobalMenuProps extends AccountMenuProps {
|
|
22
11
|
expanded: boolean;
|
|
23
12
|
onToggle: MouseEventHandler;
|
|
24
13
|
items: MenuItemProps[];
|
|
25
14
|
groups?: MenuItemGroups;
|
|
26
|
-
accounts?: Account[];
|
|
27
|
-
accountGroups?: MenuItemGroups;
|
|
28
|
-
accountSearch?: AccountSearch;
|
|
29
15
|
menuLabel?: string;
|
|
30
16
|
backLabel?: string;
|
|
17
|
+
changeLabel?: string;
|
|
18
|
+
logoutLabel?: string;
|
|
31
19
|
className?: string;
|
|
20
|
+
currentAccount?: Account;
|
|
21
|
+
changeCurrentAccount?: (id: string) => void;
|
|
32
22
|
}
|
|
33
23
|
|
|
34
|
-
const defaultResultLabel = (hits: number) => `${hits} hits`;
|
|
35
|
-
|
|
36
24
|
export const GlobalMenu = ({
|
|
37
25
|
accounts = [],
|
|
38
26
|
accountGroups = {},
|
|
39
27
|
accountSearch,
|
|
40
28
|
items = [],
|
|
41
29
|
groups,
|
|
30
|
+
changeLabel = 'Change',
|
|
31
|
+
logoutLabel = 'Logout',
|
|
42
32
|
backLabel = 'Back',
|
|
33
|
+
currentAccount,
|
|
34
|
+
changeCurrentAccount,
|
|
43
35
|
}: GlobalMenuProps) => {
|
|
44
|
-
const
|
|
45
|
-
id: account.name,
|
|
46
|
-
group: account.group || 'search',
|
|
47
|
-
selected: account.selected,
|
|
48
|
-
title: account.name,
|
|
49
|
-
avatar: {
|
|
50
|
-
type: account.type,
|
|
51
|
-
name: account.name,
|
|
52
|
-
},
|
|
53
|
-
}));
|
|
54
|
-
|
|
55
|
-
const selectedAccount = accountMenu.find((account) => account.selected);
|
|
56
|
-
const [selectAccount, setSelectAccount] = useState<boolean>(false);
|
|
57
|
-
const [filterString, setFilterString] = useState<string>('');
|
|
36
|
+
const [selectingAccount, setSelectingAccount] = useState<boolean>(false);
|
|
58
37
|
|
|
59
38
|
const onToggleAccounts = () => {
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const accountMenuItem: MenuItemProps = {
|
|
64
|
-
...selectedAccount,
|
|
65
|
-
id: 'account',
|
|
66
|
-
selected: false,
|
|
67
|
-
size: 'lg',
|
|
68
|
-
onClick: onToggleAccounts,
|
|
39
|
+
setSelectingAccount((prevState) => !prevState);
|
|
69
40
|
};
|
|
70
41
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
? accountMenu
|
|
75
|
-
.filter((item) => item?.title?.toLowerCase().includes(filterString.toLowerCase()))
|
|
76
|
-
.map((item) => {
|
|
77
|
-
return {
|
|
78
|
-
...item,
|
|
79
|
-
groupId: 'search',
|
|
80
|
-
};
|
|
81
|
-
})
|
|
82
|
-
: accountMenu;
|
|
83
|
-
|
|
84
|
-
const filterAccountGroups = filterString
|
|
85
|
-
? {
|
|
86
|
-
search: {
|
|
87
|
-
title:
|
|
88
|
-
accountSearch?.getResultsLabel?.(filteredAccountMenu.length) ??
|
|
89
|
-
defaultResultLabel(filteredAccountMenu.length),
|
|
90
|
-
},
|
|
91
|
-
}
|
|
92
|
-
: accountGroups;
|
|
93
|
-
|
|
94
|
-
const accountSearchItem: MenuSearchProps = {
|
|
95
|
-
name: 'account-search',
|
|
96
|
-
value: filterString,
|
|
97
|
-
placeholder: accountSearch?.placeholder ?? 'Find account',
|
|
98
|
-
onChange: (event: React.ChangeEvent<HTMLInputElement>) => setFilterString(event.target.value),
|
|
42
|
+
const onSelectAccount = (id: string) => {
|
|
43
|
+
onToggleAccounts();
|
|
44
|
+
changeCurrentAccount?.(id);
|
|
99
45
|
};
|
|
100
46
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
47
|
+
if (selectingAccount) {
|
|
48
|
+
return (
|
|
49
|
+
<GlobalMenuBase>
|
|
50
|
+
<BackButton onClick={onToggleAccounts} label={backLabel} />
|
|
51
|
+
<AccountMenu
|
|
52
|
+
currentAccount={currentAccount}
|
|
53
|
+
accounts={accounts}
|
|
54
|
+
accountGroups={accountGroups}
|
|
55
|
+
accountSearch={accountSearch}
|
|
56
|
+
onSelectAccount={onSelectAccount}
|
|
57
|
+
/>
|
|
58
|
+
</GlobalMenuBase>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
111
61
|
|
|
112
|
-
if (
|
|
62
|
+
if (currentAccount) {
|
|
113
63
|
return (
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
64
|
+
<GlobalMenuBase>
|
|
65
|
+
<GlobalMenuHeader>
|
|
66
|
+
<AccountButton account={currentAccount} linkText={changeLabel} onClick={onToggleAccounts} />
|
|
67
|
+
</GlobalMenuHeader>
|
|
68
|
+
<Menu groups={groups} items={items} />
|
|
69
|
+
<GlobalMenuFooter>
|
|
70
|
+
<LogoutButton label={logoutLabel} />
|
|
71
|
+
</GlobalMenuFooter>
|
|
72
|
+
</GlobalMenuBase>
|
|
118
73
|
);
|
|
119
74
|
}
|
|
120
75
|
|
|
121
|
-
return
|
|
76
|
+
return (
|
|
77
|
+
<GlobalMenuBase>
|
|
78
|
+
<Menu groups={groups} items={items} />
|
|
79
|
+
</GlobalMenuBase>
|
|
80
|
+
);
|
|
122
81
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import styles from './globalMenuBase.module.css';
|
|
3
|
+
|
|
4
|
+
export interface GlobalMenuBaseProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const GlobalMenuBase = ({ children }: GlobalMenuBaseProps) => {
|
|
9
|
+
return (
|
|
10
|
+
<nav className={styles.nav} data-theme="global">
|
|
11
|
+
{children}
|
|
12
|
+
</nav>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const GlobalMenuHeader = ({ children }: GlobalMenuBaseProps) => {
|
|
17
|
+
return <header className={styles.header}>{children}</header>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const GlobalMenuFooter = ({ children }: GlobalMenuBaseProps) => {
|
|
21
|
+
return <footer className={styles.footer}>{children}</footer>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { ButtonBase, ButtonLabel } from '../Button';
|
|
3
|
+
import styles from './logoutButton.module.css';
|
|
4
|
+
|
|
5
|
+
export interface LogoutButtonProps {
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
onClick?: MouseEventHandler;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const LogoutButton = ({ label = 'Logout', children, onClick }: LogoutButtonProps) => {
|
|
12
|
+
return (
|
|
13
|
+
<ButtonBase className={styles.button} variant="outline" size="lg" onClick={onClick}>
|
|
14
|
+
<ButtonLabel className={styles.label} size="lg">
|
|
15
|
+
{children || label}
|
|
16
|
+
</ButtonLabel>
|
|
17
|
+
</ButtonBase>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
.nav {
|
|
2
|
+
background-color: #fff;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
padding: 0 0.5rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.header {
|
|
9
|
+
border-bottom: 1px solid var(--theme-border-subtle);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.footer {
|
|
13
|
+
border-top: 1px solid var(--theme-border-subtle);
|
|
14
|
+
padding: 1rem 0.5rem;
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
align-items: stretch;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.drawer[aria-expanded="true"] {
|
|
21
|
+
display: block;
|
|
22
|
+
padding: 0.5rem;
|
|
23
|
+
z-index: 2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.dropdown[aria-expanded="true"] {
|
|
27
|
+
display: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@media (min-width: 1024px) {
|
|
31
|
+
.drawer[aria-expanded="true"] {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.dropdown[aria-expanded="true"] {
|
|
36
|
+
display: block;
|
|
37
|
+
z-index: 2;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './GlobalMenu
|
|
1
|
+
export * from './GlobalMenu';
|
|
@@ -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,6 +2,7 @@
|
|
|
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';
|
|
@@ -13,15 +14,11 @@ import styles from './header.module.css';
|
|
|
13
14
|
export interface HeaderProps {
|
|
14
15
|
menu: GlobalMenuProps;
|
|
15
16
|
search?: SearchbarProps;
|
|
17
|
+
currentAccount?: Account;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
export const Header = ({ search, menu }: HeaderProps) => {
|
|
20
|
+
export const Header = ({ search, menu, currentAccount }: HeaderProps) => {
|
|
19
21
|
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
22
|
|
|
26
23
|
useEscapeKey(closeAll);
|
|
27
24
|
|
|
@@ -42,14 +39,19 @@ export const Header = ({ search, menu }: HeaderProps) => {
|
|
|
42
39
|
<HeaderLogo className={styles.logo} />
|
|
43
40
|
<HeaderMenu className={styles.menu}>
|
|
44
41
|
<HeaderButton
|
|
45
|
-
avatar={
|
|
42
|
+
avatar={
|
|
43
|
+
currentAccount && {
|
|
44
|
+
type: currentAccount.type,
|
|
45
|
+
name: currentAccount.name,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
46
48
|
onClick={onToggleMenu}
|
|
47
49
|
expanded={currentId === 'menu'}
|
|
48
50
|
label={menu?.menuLabel}
|
|
49
51
|
/>
|
|
50
52
|
{menu && (
|
|
51
|
-
<DropdownBase placement="right" expanded={currentId === 'menu'} className={styles.dropdown}>
|
|
52
|
-
<GlobalMenu {...menu}
|
|
53
|
+
<DropdownBase padding={false} placement="right" expanded={currentId === 'menu'} className={styles.dropdown}>
|
|
54
|
+
<GlobalMenu {...menu} currentAccount={currentAccount} />
|
|
53
55
|
</DropdownBase>
|
|
54
56
|
)}
|
|
55
57
|
</HeaderMenu>
|
|
@@ -64,7 +66,7 @@ export const Header = ({ search, menu }: HeaderProps) => {
|
|
|
64
66
|
)}
|
|
65
67
|
{menu && (
|
|
66
68
|
<DrawerBase expanded={currentId === 'menu'} className={styles.drawer}>
|
|
67
|
-
<GlobalMenu {...menu}
|
|
69
|
+
<GlobalMenu {...menu} expanded={currentId === 'menu'} currentAccount={currentAccount} />
|
|
68
70
|
</DrawerBase>
|
|
69
71
|
)}
|
|
70
72
|
</HeaderBase>
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import cx from 'classnames';
|
|
2
|
-
import type { ElementType, ReactNode } from 'react';
|
|
2
|
+
import type { ElementType, MouseEventHandler, ReactNode } from 'react';
|
|
3
3
|
import { Badge, type BadgeProps } from '../Badge';
|
|
4
4
|
import { Icon, type IconName } from '../Icon';
|
|
5
5
|
import styles from './menuItemBase.module.css';
|
|
@@ -9,11 +9,13 @@ export type MenuItemSize = 'sm' | 'md' | 'lg';
|
|
|
9
9
|
|
|
10
10
|
export interface MenuItemBaseProps {
|
|
11
11
|
as?: ElementType;
|
|
12
|
+
onClick?: MouseEventHandler;
|
|
12
13
|
color?: MenuItemColor;
|
|
13
14
|
children?: ReactNode;
|
|
14
15
|
tabIndex?: number;
|
|
15
16
|
size?: MenuItemSize;
|
|
16
17
|
linkIcon?: IconName;
|
|
18
|
+
linkText?: string;
|
|
17
19
|
badge?: BadgeProps;
|
|
18
20
|
collapsible?: boolean;
|
|
19
21
|
active?: boolean;
|
|
@@ -25,9 +27,11 @@ export interface MenuItemBaseProps {
|
|
|
25
27
|
|
|
26
28
|
export const MenuItemBase = ({
|
|
27
29
|
as,
|
|
30
|
+
onClick,
|
|
28
31
|
size,
|
|
29
32
|
color,
|
|
30
33
|
linkIcon,
|
|
34
|
+
linkText,
|
|
31
35
|
badge,
|
|
32
36
|
tabIndex = 0,
|
|
33
37
|
active = false,
|
|
@@ -54,6 +58,7 @@ export const MenuItemBase = ({
|
|
|
54
58
|
aria-expanded={expanded}
|
|
55
59
|
aria-disabled={disabled}
|
|
56
60
|
aria-selected={selected}
|
|
61
|
+
onClick={onClick}
|
|
57
62
|
className={cx(styles.item, className)}
|
|
58
63
|
{...rest}
|
|
59
64
|
>
|
|
@@ -63,7 +68,8 @@ export const MenuItemBase = ({
|
|
|
63
68
|
</div>
|
|
64
69
|
{applicableIcon && (
|
|
65
70
|
<div className={styles.action}>
|
|
66
|
-
|
|
71
|
+
<span className={styles.linkText}>{linkText}</span>
|
|
72
|
+
{applicableIcon && <Icon name={applicableIcon} className={styles.linkIcon} />}
|
|
67
73
|
</div>
|
|
68
74
|
)}
|
|
69
75
|
</Component>
|
|
@@ -4,12 +4,22 @@
|
|
|
4
4
|
padding: 0 0.25rem;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
.title {
|
|
8
|
+
color: var(--theme-text-default);
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
.title[data-size="lg"] {
|
|
8
12
|
font-size: 1.125rem;
|
|
9
13
|
line-height: 1.25;
|
|
10
14
|
font-weight: 500;
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
.title[data-size="md"] {
|
|
18
|
+
font-size: 1rem;
|
|
19
|
+
line-height: 1.25;
|
|
20
|
+
font-weight: 500;
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
.title[data-size="sm"] {
|
|
14
24
|
font-size: 1rem;
|
|
15
25
|
line-height: 1.25;
|
|
@@ -17,6 +27,6 @@
|
|
|
17
27
|
}
|
|
18
28
|
|
|
19
29
|
.description {
|
|
20
|
-
font-size:
|
|
30
|
+
font-size: 0.875rem;
|
|
21
31
|
color: var(--theme-text-subtle);
|
|
22
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@altinn/altinn-components",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"main": "lib/index.ts",
|
|
5
5
|
"description": "Reusable react components",
|
|
6
6
|
"publishConfig": {
|
|
@@ -15,24 +15,26 @@
|
|
|
15
15
|
"react": "^18.3.1"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@biomejs/biome": "1.9.
|
|
19
|
-
"@chromatic-com/storybook": "^
|
|
20
|
-
"@storybook/addon-
|
|
21
|
-
"@storybook/addon-
|
|
22
|
-
"@storybook/addon-
|
|
23
|
-
"@storybook/addon-
|
|
24
|
-
"@storybook/addon-
|
|
25
|
-
"@storybook/
|
|
26
|
-
"@storybook/
|
|
27
|
-
"@storybook/react
|
|
28
|
-
"@storybook/
|
|
18
|
+
"@biomejs/biome": "1.9.4",
|
|
19
|
+
"@chromatic-com/storybook": "^3.2.2",
|
|
20
|
+
"@storybook/addon-a11y": "^8.4.4",
|
|
21
|
+
"@storybook/addon-essentials": "^8.4.4",
|
|
22
|
+
"@storybook/addon-interactions": "^8.4.4",
|
|
23
|
+
"@storybook/addon-links": "^8.4.4",
|
|
24
|
+
"@storybook/addon-onboarding": "^8.4.4",
|
|
25
|
+
"@storybook/addon-themes": "^8.4.4",
|
|
26
|
+
"@storybook/blocks": "^8.4.4",
|
|
27
|
+
"@storybook/react": "^8.4.4",
|
|
28
|
+
"@storybook/react-vite": "^8.4.4",
|
|
29
|
+
"@storybook/test": "^8.4.4",
|
|
29
30
|
"@types/react": "^18.3.11",
|
|
30
31
|
"@types/react-dom": "^18.3.1",
|
|
31
32
|
"@vitejs/plugin-react-swc": "^3.7.1",
|
|
33
|
+
"axe-core": "^4.10.2",
|
|
32
34
|
"lint-staged": "^15.2.10",
|
|
33
35
|
"prop-types": "^15.8.1",
|
|
34
|
-
"storybook": "^8.
|
|
35
|
-
"storybook-addon-theme-provider": "^0.2.
|
|
36
|
+
"storybook": "^8.4.4",
|
|
37
|
+
"storybook-addon-theme-provider": "^0.2.8",
|
|
36
38
|
"typescript": "^5.6.3",
|
|
37
39
|
"vite": "^5.4.9"
|
|
38
40
|
},
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ElementType, ReactNode } from 'react';
|
|
2
|
-
import styles from './menu.module.css';
|
|
3
|
-
|
|
4
|
-
export interface MenuGroupProps {
|
|
5
|
-
as?: ElementType;
|
|
6
|
-
expanded?: boolean;
|
|
7
|
-
divider?: boolean;
|
|
8
|
-
children?: ReactNode;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const MenuGroup = ({ as = 'div', expanded, divider = true, children }: MenuGroupProps) => {
|
|
12
|
-
const Component = as;
|
|
13
|
-
return (
|
|
14
|
-
<Component aria-expanded={expanded} data-divider={divider} className={styles.group}>
|
|
15
|
-
{children}
|
|
16
|
-
</Component>
|
|
17
|
-
);
|
|
18
|
-
};
|