@altinn/altinn-components 0.4.1 → 0.5.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 +7 -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 +16 -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.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 +5 -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 +15 -3
- package/lib/components/Dropdown/index.ts +7 -1
- package/lib/components/Footer/footerMenu.module.css +5 -0
- package/lib/components/GlobalMenu/GlobalMenu.stories.tsx +9 -9
- package/lib/components/GlobalMenu/GlobalMenu.tsx +5 -5
- package/lib/components/Header/{Header.stories.ts → Header.stories.tsx} +79 -20
- package/lib/components/Header/Header.tsx +24 -37
- 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 +6 -4
- package/lib/components/Menu/MenuItemBase.tsx +7 -0
- 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/{MenuGroup.tsx → __MenuGroup.tsx} +1 -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 +5 -4
- 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 +1 -1
- 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/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
|
@@ -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
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { ButtonBase, ButtonLabel } from '../';
|
|
3
|
+
import styles from './drawerButton.module.css';
|
|
4
|
+
|
|
5
|
+
export interface DrawerButtonProps {
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
onClick?: MouseEventHandler;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const DrawerButton = ({ label, children, onClick }: DrawerButtonProps) => {
|
|
12
|
+
return (
|
|
13
|
+
<ButtonBase variant="solid" size="md" className={styles.button} onClick={onClick}>
|
|
14
|
+
<ButtonLabel size="md">{children || label}</ButtonLabel>
|
|
15
|
+
</ButtonBase>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import styles from './drawerFooter.module.css';
|
|
4
|
+
|
|
5
|
+
export interface DrawerFooterProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const DrawerFooter = ({ className, children }: DrawerFooterProps) => {
|
|
11
|
+
return <footer className={cx(styles.footer, className)}>{children}</footer>;
|
|
12
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import type { MouseEventHandler } from 'react';
|
|
3
|
+
import { IconButton } from '../Button';
|
|
4
|
+
import styles from './drawerHeader.module.css';
|
|
5
|
+
|
|
6
|
+
export interface DrawerHeaderProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
onClose?: MouseEventHandler;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DrawerHeader = ({ className, title, onClose }: DrawerHeaderProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<header className={cx(styles.header, className)}>
|
|
15
|
+
<h2 className={styles.title}>{title}</h2>
|
|
16
|
+
<IconButton size="sm" icon="x-mark" variant="outline" onClick={onClose} className={styles.close} />
|
|
17
|
+
</header>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { DrawerBase, DrawerBody, DrawerButton, DrawerFooter, DrawerHeader, DropdownBase } from '../';
|
|
3
|
+
import type { DrawerButtonProps } from '../';
|
|
4
|
+
import { Backdrop } from './Backdrop';
|
|
5
|
+
import styles from './drawerOrDropdown.module.css';
|
|
6
|
+
|
|
7
|
+
export interface DrawerOrDropdownProps {
|
|
8
|
+
title: string;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
expanded?: boolean;
|
|
11
|
+
onClose?: MouseEventHandler;
|
|
12
|
+
button?: DrawerButtonProps;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const DrawerOrDropdown = ({ expanded = false, title, onClose, button, children }: DrawerOrDropdownProps) => {
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
{expanded && <Backdrop onClick={onClose} />}
|
|
19
|
+
<DropdownBase className={styles.dropdown} expanded={expanded}>
|
|
20
|
+
{children}
|
|
21
|
+
</DropdownBase>
|
|
22
|
+
<DrawerBase className={styles.drawer} placement="bottom" expanded={expanded}>
|
|
23
|
+
<DrawerHeader title={title} onClose={onClose} />
|
|
24
|
+
<DrawerBody>{children}</DrawerBody>
|
|
25
|
+
<DrawerFooter>{button && <DrawerButton onClick={button?.onClick}>{button?.label}</DrawerButton>}</DrawerFooter>
|
|
26
|
+
</DrawerBase>
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -2,15 +2,18 @@ import cx from 'classnames';
|
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
3
|
import styles from './dropdownBase.module.css';
|
|
4
4
|
|
|
5
|
+
export type DropdownPlacement = 'left' | 'right';
|
|
6
|
+
|
|
5
7
|
export interface DropdownBaseProps {
|
|
8
|
+
placement?: DropdownPlacement;
|
|
6
9
|
expanded?: boolean;
|
|
7
10
|
className?: string;
|
|
8
11
|
children?: ReactNode;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
|
-
export const DropdownBase = ({ expanded = false, className, children }: DropdownBaseProps) => {
|
|
14
|
+
export const DropdownBase = ({ placement = 'left', expanded = false, className, children }: DropdownBaseProps) => {
|
|
12
15
|
return (
|
|
13
|
-
<div className={cx(styles.dropdown, className)} aria-expanded={expanded}>
|
|
16
|
+
<div className={cx(styles.dropdown, className)} data-placement={placement} aria-expanded={expanded}>
|
|
14
17
|
{children}
|
|
15
18
|
</div>
|
|
16
19
|
);
|