@frontify/guideline-blocks-settings 0.32.2 → 0.33.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 +108 -1
- package/dist/components/BlockItemWrapper/BlockItemWrapper.es.js +23 -27
- package/dist/components/BlockItemWrapper/BlockItemWrapper.es.js.map +1 -1
- package/dist/components/BlockItemWrapper/Toolbar/DragHandleToolbarButton/DragHandleToolbarButton.es.js.map +1 -1
- package/dist/components/BlockItemWrapper/Toolbar/Toolbar.es.js +10 -14
- package/dist/components/BlockItemWrapper/Toolbar/Toolbar.es.js.map +1 -1
- package/dist/index.cjs.js +3 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +42 -11
- package/dist/index.es.js +201 -193
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +3 -3
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -2
- package/src/components/BlockItemWrapper/BlockItemWrapper.spec.ct.tsx +37 -38
- package/src/components/BlockItemWrapper/BlockItemWrapper.tsx +0 -4
- package/src/components/BlockItemWrapper/Toolbar/DragHandleToolbarButton/DragHandleToolbarButton.tsx +2 -1
- package/src/components/BlockItemWrapper/Toolbar/Toolbar.spec.tsx +165 -30
- package/src/components/BlockItemWrapper/Toolbar/Toolbar.tsx +14 -9
- package/src/components/BlockItemWrapper/Toolbar/context/index.ts +4 -0
- package/src/components/BlockItemWrapper/Toolbar/hooks/index.ts +3 -0
- package/src/components/BlockItemWrapper/Toolbar/index.ts +2 -0
- package/src/components/BlockItemWrapper/Toolbar/types.ts +8 -9
- package/src/components/BlockItemWrapper/types.ts +1 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontify/guideline-blocks-settings",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "Provides types and helpers for the guideline block development",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "dist/index.umd.js",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"@frontify/eslint-config-typescript": "^0.16.2",
|
|
28
28
|
"@testing-library/jest-dom": "^6.4.2",
|
|
29
29
|
"@testing-library/react": "^14.1.2",
|
|
30
|
+
"@testing-library/user-event": "14.5.2",
|
|
30
31
|
"@types/node": "^18.18.11",
|
|
31
32
|
"@types/react": "^18.2.38",
|
|
32
33
|
"@types/react-dom": "^18.2.16",
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"@udecode/plate": "^21.5.0",
|
|
65
66
|
"slate": "^0.94.1",
|
|
66
67
|
"slate-react": "^0.98.3",
|
|
67
|
-
"@frontify/sidebar-settings": "^0.9.
|
|
68
|
+
"@frontify/sidebar-settings": "^0.9.2"
|
|
68
69
|
},
|
|
69
70
|
"peerDependencies": {
|
|
70
71
|
"@frontify/app-bridge": "^3.0.0 || ^4.0.0-alpha.0",
|
|
@@ -14,7 +14,7 @@ const ChildSelector = '[data-test-id="block-item-wrapper-child"]';
|
|
|
14
14
|
describe('Block Item Wrapper', () => {
|
|
15
15
|
it('should render the wrapper and the children', () => {
|
|
16
16
|
mount(
|
|
17
|
-
<BlockItemWrapper
|
|
17
|
+
<BlockItemWrapper toolbarItems={[]}>
|
|
18
18
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
19
19
|
</BlockItemWrapper>,
|
|
20
20
|
);
|
|
@@ -24,7 +24,7 @@ describe('Block Item Wrapper', () => {
|
|
|
24
24
|
|
|
25
25
|
it('should render the outline class', () => {
|
|
26
26
|
mount(
|
|
27
|
-
<BlockItemWrapper
|
|
27
|
+
<BlockItemWrapper toolbarItems={[]}>
|
|
28
28
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
29
29
|
</BlockItemWrapper>,
|
|
30
30
|
);
|
|
@@ -33,7 +33,7 @@ describe('Block Item Wrapper', () => {
|
|
|
33
33
|
|
|
34
34
|
it('should not render the outline class if the hide prop is set', () => {
|
|
35
35
|
mount(
|
|
36
|
-
<BlockItemWrapper
|
|
36
|
+
<BlockItemWrapper toolbarItems={[]} shouldHideWrapper>
|
|
37
37
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
38
38
|
</BlockItemWrapper>,
|
|
39
39
|
);
|
|
@@ -43,10 +43,9 @@ describe('Block Item Wrapper', () => {
|
|
|
43
43
|
it('should render the right amount of toolbar items', () => {
|
|
44
44
|
mount(
|
|
45
45
|
<BlockItemWrapper
|
|
46
|
-
toolbarFlyoutItems={[]}
|
|
47
46
|
toolbarItems={[
|
|
48
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
49
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
47
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
48
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
50
49
|
]}
|
|
51
50
|
>
|
|
52
51
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
@@ -58,30 +57,33 @@ describe('Block Item Wrapper', () => {
|
|
|
58
57
|
it('should render the flyout button with the right amount of menu items', () => {
|
|
59
58
|
mount(
|
|
60
59
|
<BlockItemWrapper
|
|
61
|
-
toolbarFlyoutItems={[
|
|
62
|
-
[
|
|
63
|
-
{
|
|
64
|
-
icon: <IconMagnifier16 />,
|
|
65
|
-
onClick: cy.stub(),
|
|
66
|
-
title: 'Test title',
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
[
|
|
70
|
-
{
|
|
71
|
-
icon: <IconMagnifier16 />,
|
|
72
|
-
onClick: cy.stub(),
|
|
73
|
-
title: 'Test title',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
icon: <IconMagnifier16 />,
|
|
77
|
-
onClick: cy.stub(),
|
|
78
|
-
title: 'Test title',
|
|
79
|
-
},
|
|
80
|
-
],
|
|
81
|
-
]}
|
|
82
60
|
toolbarItems={[
|
|
83
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
84
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
61
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
62
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
63
|
+
{
|
|
64
|
+
type: 'menu',
|
|
65
|
+
items: [
|
|
66
|
+
[
|
|
67
|
+
{
|
|
68
|
+
icon: <IconMagnifier16 />,
|
|
69
|
+
onClick: cy.stub(),
|
|
70
|
+
title: 'Test title',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
[
|
|
74
|
+
{
|
|
75
|
+
icon: <IconMagnifier16 />,
|
|
76
|
+
onClick: cy.stub(),
|
|
77
|
+
title: 'Test title',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
icon: <IconMagnifier16 />,
|
|
81
|
+
onClick: cy.stub(),
|
|
82
|
+
title: 'Test title',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
],
|
|
86
|
+
},
|
|
85
87
|
]}
|
|
86
88
|
>
|
|
87
89
|
<div data-test-id="block-item-wrapper-child" className="tw-mt-8 tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
@@ -96,10 +98,9 @@ describe('Block Item Wrapper', () => {
|
|
|
96
98
|
it('should render the outline if a toolbar button is focused', () => {
|
|
97
99
|
mount(
|
|
98
100
|
<BlockItemWrapper
|
|
99
|
-
toolbarFlyoutItems={[]}
|
|
100
101
|
toolbarItems={[
|
|
101
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
102
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
102
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
103
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
103
104
|
]}
|
|
104
105
|
>
|
|
105
106
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
@@ -112,11 +113,10 @@ describe('Block Item Wrapper', () => {
|
|
|
112
113
|
it('should render the toolbar if a button is focused', () => {
|
|
113
114
|
mount(
|
|
114
115
|
<BlockItemWrapper
|
|
115
|
-
toolbarFlyoutItems={[]}
|
|
116
116
|
shouldHideComponent={false}
|
|
117
117
|
toolbarItems={[
|
|
118
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
119
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
118
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
119
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
120
120
|
]}
|
|
121
121
|
>
|
|
122
122
|
<div data-test-id="block-item-wrapper-child" className="tw-w-8 tw-h-8 tw-bg-red-50" />
|
|
@@ -129,10 +129,9 @@ describe('Block Item Wrapper', () => {
|
|
|
129
129
|
it('should render the outline and the toolbar if enabled', () => {
|
|
130
130
|
mount(
|
|
131
131
|
<BlockItemWrapper
|
|
132
|
-
toolbarFlyoutItems={[]}
|
|
133
132
|
toolbarItems={[
|
|
134
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
135
|
-
{ icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
133
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
134
|
+
{ type: 'button', icon: <IconMagnifier16 />, onClick: cy.stub(), tooltip: 'Test tooltip' },
|
|
136
135
|
]}
|
|
137
136
|
shouldBeShown
|
|
138
137
|
>
|
|
@@ -11,7 +11,6 @@ import { MultiFlyoutContextProvider } from './Toolbar/context/MultiFlyoutContext
|
|
|
11
11
|
|
|
12
12
|
export const BlockItemWrapper = ({
|
|
13
13
|
children,
|
|
14
|
-
toolbarFlyoutItems,
|
|
15
14
|
toolbarItems,
|
|
16
15
|
shouldHideWrapper,
|
|
17
16
|
shouldHideComponent = false,
|
|
@@ -63,9 +62,6 @@ export const BlockItemWrapper = ({
|
|
|
63
62
|
])}
|
|
64
63
|
>
|
|
65
64
|
<Toolbar
|
|
66
|
-
flyoutMenu={{
|
|
67
|
-
items: toolbarFlyoutItems,
|
|
68
|
-
}}
|
|
69
65
|
attachments={{
|
|
70
66
|
isEnabled: showAttachments,
|
|
71
67
|
}}
|
package/src/components/BlockItemWrapper/Toolbar/DragHandleToolbarButton/DragHandleToolbarButton.tsx
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
2
|
|
|
3
|
+
import { ReactNode } from 'react';
|
|
3
4
|
import { DEFAULT_DRAGGING_TOOLTIP, DEFAULT_DRAG_TOOLTIP } from '../../constants';
|
|
4
5
|
import { useDragPreviewContext } from '../context/DragPreviewContext';
|
|
5
6
|
import { BaseToolbarButton } from '../BaseToolbarButton';
|
|
6
7
|
import { ToolbarButtonTooltip } from '../ToolbarButtonTooltip';
|
|
7
8
|
|
|
8
9
|
export type DragHandleToolbarButtonProps = {
|
|
9
|
-
icon
|
|
10
|
+
icon?: ReactNode;
|
|
10
11
|
tooltip?: string;
|
|
11
12
|
draggableProps: Record<string, unknown>;
|
|
12
13
|
setActivatorNodeRef?: (node: HTMLElement | null) => void;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { getAppBridgeBlockStub } from '@frontify/app-bridge';
|
|
4
|
-
import {
|
|
4
|
+
import { IconArrowMove16, IconMoveTo, IconTrashBin } from '@frontify/fondue';
|
|
5
|
+
import { fireEvent, render } from '@testing-library/react';
|
|
6
|
+
import userEvent from '@testing-library/user-event';
|
|
5
7
|
import { beforeAll, describe, expect, it, vi } from 'vitest';
|
|
6
8
|
|
|
7
9
|
import { AttachmentsProvider } from '../../../hooks/useAttachments';
|
|
8
10
|
|
|
9
11
|
import { Toolbar } from './Toolbar';
|
|
10
12
|
import { MultiFlyoutContextProvider } from './context/MultiFlyoutContext';
|
|
11
|
-
import { DEFAULT_ATTACHMENTS_BUTTON_ID, DEFAULT_MENU_BUTTON_ID } from '.';
|
|
12
13
|
import { DragPreviewContextProvider } from './context/DragPreviewContext';
|
|
14
|
+
import { DEFAULT_ATTACHMENTS_BUTTON_ID } from './AttachmentsToolbarButton';
|
|
15
|
+
import { DEFAULT_MENU_BUTTON_ID } from './MenuToolbarButton';
|
|
16
|
+
import { ToolbarItem } from './types';
|
|
13
17
|
|
|
14
18
|
/**
|
|
15
19
|
* @vitest-environment happy-dom
|
|
@@ -21,6 +25,54 @@ const MENU_FLYOUT_ID = 'menu-item';
|
|
|
21
25
|
const MOCK_ASSET_FIELD_ID = 'attachment';
|
|
22
26
|
|
|
23
27
|
describe('Toolbar', () => {
|
|
28
|
+
const stubs = vi.hoisted(() => ({
|
|
29
|
+
setOpenFlyoutIds: vi.fn(),
|
|
30
|
+
onClick: vi.fn(),
|
|
31
|
+
onDrag: vi.fn(),
|
|
32
|
+
onKeyDown: vi.fn(),
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
const STUB_WITH_NO_ASSETS = getAppBridgeBlockStub({
|
|
36
|
+
blockId: 1,
|
|
37
|
+
blockAssets: { [MOCK_ASSET_FIELD_ID]: [] },
|
|
38
|
+
editorState: true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const FULL_ITEMS: ToolbarItem[] = [
|
|
42
|
+
{
|
|
43
|
+
type: 'dragHandle',
|
|
44
|
+
setActivatorNodeRef: vi.fn(),
|
|
45
|
+
icon: <IconMoveTo />,
|
|
46
|
+
draggableProps: { onDrag: stubs.onDrag, onKeyDown: stubs.onKeyDown },
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: 'button',
|
|
50
|
+
onClick: stubs.onClick,
|
|
51
|
+
icon: <IconTrashBin />,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'flyout',
|
|
55
|
+
icon: <IconArrowMove16 />,
|
|
56
|
+
tooltip: 'Move To',
|
|
57
|
+
content: <div>Content</div>,
|
|
58
|
+
flyoutHeader: <div>Fixed Header</div>,
|
|
59
|
+
flyoutFooter: <div>Fixed Footer</div>,
|
|
60
|
+
flyoutId: 'move',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'menu',
|
|
64
|
+
items: [
|
|
65
|
+
[
|
|
66
|
+
{
|
|
67
|
+
title: 'Replace with upload',
|
|
68
|
+
icon: <div></div>,
|
|
69
|
+
onClick: stubs.onClick,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
|
|
24
76
|
beforeAll(() => {
|
|
25
77
|
vi.stubGlobal(
|
|
26
78
|
'Worker',
|
|
@@ -33,15 +85,94 @@ describe('Toolbar', () => {
|
|
|
33
85
|
});
|
|
34
86
|
|
|
35
87
|
it('should not throw error if toolbar does not have attachments enabled', () => {
|
|
36
|
-
expect(() =>
|
|
37
|
-
render(<Toolbar items={[]} flyoutMenu={{ items: [] }} attachments={{ isEnabled: false }} />),
|
|
38
|
-
).not.toThrowError();
|
|
88
|
+
expect(() => render(<Toolbar items={[]} attachments={{ isEnabled: false }} />)).not.toThrowError();
|
|
39
89
|
});
|
|
40
90
|
|
|
41
91
|
it('should throw error if toolbar does have attachments enabled without provider', () => {
|
|
42
|
-
expect(() =>
|
|
43
|
-
|
|
44
|
-
|
|
92
|
+
expect(() => render(<Toolbar items={[]} attachments={{ isEnabled: true }} />)).toThrowError();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should have every item type accessible by mouse', async () => {
|
|
96
|
+
const ToolbarWithAttachments = () => (
|
|
97
|
+
<MultiFlyoutContextProvider openFlyoutIds={[]} setOpenFlyoutIds={stubs.setOpenFlyoutIds}>
|
|
98
|
+
<AttachmentsProvider appBridge={STUB_WITH_NO_ASSETS} assetId={MOCK_ASSET_FIELD_ID}>
|
|
99
|
+
<Toolbar items={FULL_ITEMS} attachments={{ isEnabled: true }} />
|
|
100
|
+
</AttachmentsProvider>
|
|
101
|
+
</MultiFlyoutContextProvider>
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const { getAllByRole } = render(<ToolbarWithAttachments />);
|
|
105
|
+
|
|
106
|
+
const buttons = getAllByRole('button');
|
|
107
|
+
expect(buttons).toHaveLength(5);
|
|
108
|
+
|
|
109
|
+
const [attachmentBtn, dragBtn, btn, flyoutBtn, menuBtn] = buttons;
|
|
110
|
+
|
|
111
|
+
// Click Interactions
|
|
112
|
+
|
|
113
|
+
await fireEvent.click(attachmentBtn);
|
|
114
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(1);
|
|
115
|
+
|
|
116
|
+
await fireEvent.drag(dragBtn);
|
|
117
|
+
expect(stubs.onDrag).toHaveBeenCalledTimes(1);
|
|
118
|
+
|
|
119
|
+
await fireEvent.click(btn);
|
|
120
|
+
expect(stubs.onClick).toHaveBeenCalledTimes(1);
|
|
121
|
+
|
|
122
|
+
await fireEvent.click(flyoutBtn);
|
|
123
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(2);
|
|
124
|
+
|
|
125
|
+
await fireEvent.click(menuBtn);
|
|
126
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(3);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should have every item type accessible by keyboard', async () => {
|
|
130
|
+
const ToolbarWithAttachments = () => (
|
|
131
|
+
<MultiFlyoutContextProvider openFlyoutIds={[]} setOpenFlyoutIds={stubs.setOpenFlyoutIds}>
|
|
132
|
+
<AttachmentsProvider appBridge={STUB_WITH_NO_ASSETS} assetId={MOCK_ASSET_FIELD_ID}>
|
|
133
|
+
<Toolbar items={FULL_ITEMS} attachments={{ isEnabled: true }} />
|
|
134
|
+
</AttachmentsProvider>
|
|
135
|
+
</MultiFlyoutContextProvider>
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const user = userEvent.setup();
|
|
139
|
+
|
|
140
|
+
const { getAllByRole } = render(<ToolbarWithAttachments />);
|
|
141
|
+
|
|
142
|
+
const buttons = getAllByRole('button');
|
|
143
|
+
expect(buttons).toHaveLength(5);
|
|
144
|
+
|
|
145
|
+
const [attachmentBtn, dragBtn, btn, flyoutBtn, menuBtn] = buttons;
|
|
146
|
+
|
|
147
|
+
await user.keyboard('{Tab}');
|
|
148
|
+
|
|
149
|
+
expect(attachmentBtn).toHaveFocus();
|
|
150
|
+
await user.keyboard('{Enter}');
|
|
151
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(1);
|
|
152
|
+
|
|
153
|
+
await user.keyboard('{Tab}');
|
|
154
|
+
|
|
155
|
+
expect(dragBtn).toHaveFocus();
|
|
156
|
+
await user.keyboard('{Enter}');
|
|
157
|
+
expect(stubs.onKeyDown).toHaveBeenCalledTimes(1);
|
|
158
|
+
|
|
159
|
+
await user.keyboard('{Tab}');
|
|
160
|
+
|
|
161
|
+
expect(btn).toHaveFocus();
|
|
162
|
+
await user.keyboard('{Enter}');
|
|
163
|
+
expect(stubs.onClick).toHaveBeenCalledTimes(1);
|
|
164
|
+
|
|
165
|
+
await user.keyboard('{Tab}');
|
|
166
|
+
|
|
167
|
+
expect(flyoutBtn).toHaveFocus();
|
|
168
|
+
await user.keyboard('{Enter}');
|
|
169
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(2);
|
|
170
|
+
|
|
171
|
+
await user.keyboard('{Tab}');
|
|
172
|
+
|
|
173
|
+
expect(menuBtn).toHaveFocus();
|
|
174
|
+
await user.keyboard('{Enter}');
|
|
175
|
+
expect(stubs.setOpenFlyoutIds).toHaveBeenCalledTimes(3);
|
|
45
176
|
});
|
|
46
177
|
|
|
47
178
|
it('should open flyouts if not dragging', async () => {
|
|
@@ -58,18 +189,20 @@ describe('Toolbar', () => {
|
|
|
58
189
|
>
|
|
59
190
|
<AttachmentsProvider appBridge={STUB_WITH_NO_ASSETS} assetId={MOCK_ASSET_FIELD_ID}>
|
|
60
191
|
<Toolbar
|
|
61
|
-
items={[
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
[
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
192
|
+
items={[
|
|
193
|
+
{
|
|
194
|
+
type: 'menu',
|
|
195
|
+
items: [
|
|
196
|
+
[
|
|
197
|
+
{
|
|
198
|
+
title: 'Replace with upload',
|
|
199
|
+
icon: <div></div>,
|
|
200
|
+
onClick: vi.fn(),
|
|
201
|
+
},
|
|
202
|
+
],
|
|
70
203
|
],
|
|
71
|
-
|
|
72
|
-
}
|
|
204
|
+
},
|
|
205
|
+
]}
|
|
73
206
|
attachments={{ isEnabled: true }}
|
|
74
207
|
/>
|
|
75
208
|
</AttachmentsProvider>
|
|
@@ -98,18 +231,20 @@ describe('Toolbar', () => {
|
|
|
98
231
|
<DragPreviewContextProvider isDragPreview>
|
|
99
232
|
<AttachmentsProvider appBridge={STUB_WITH_NO_ASSETS} assetId={MOCK_ASSET_FIELD_ID}>
|
|
100
233
|
<Toolbar
|
|
101
|
-
items={[
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
[
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
234
|
+
items={[
|
|
235
|
+
{
|
|
236
|
+
type: 'menu',
|
|
237
|
+
items: [
|
|
238
|
+
[
|
|
239
|
+
{
|
|
240
|
+
title: 'Replace with upload',
|
|
241
|
+
icon: <div></div>,
|
|
242
|
+
onClick: vi.fn(),
|
|
243
|
+
},
|
|
244
|
+
],
|
|
110
245
|
],
|
|
111
|
-
|
|
112
|
-
}
|
|
246
|
+
},
|
|
247
|
+
]}
|
|
113
248
|
attachments={{ isEnabled: true }}
|
|
114
249
|
/>
|
|
115
250
|
</AttachmentsProvider>
|
|
@@ -5,9 +5,10 @@ import { AttachmentsToolbarButton } from './AttachmentsToolbarButton';
|
|
|
5
5
|
import { type ToolbarProps } from './types';
|
|
6
6
|
import { ToolbarButton } from './ToolbarButton';
|
|
7
7
|
import { DragHandleToolbarButton } from './DragHandleToolbarButton';
|
|
8
|
+
import { FlyoutToolbarButton } from './FlyoutToolbarButton';
|
|
8
9
|
import { MenuToolbarButton } from './MenuToolbarButton';
|
|
9
10
|
|
|
10
|
-
export const Toolbar = ({ items,
|
|
11
|
+
export const Toolbar = ({ items, attachments }: ToolbarProps) => (
|
|
11
12
|
<div
|
|
12
13
|
data-test-id="block-item-wrapper-toolbar"
|
|
13
14
|
className="tw-rounded-md tw-bg-base tw-border tw-border-line-strong tw-divide-x tw-divide-line-strong tw-shadow-lg tw-flex tw-flex-none tw-items-center tw-isolate"
|
|
@@ -18,14 +19,18 @@ export const Toolbar = ({ items, flyoutMenu, attachments }: ToolbarProps) => (
|
|
|
18
19
|
</ToolbarSegment>
|
|
19
20
|
)}
|
|
20
21
|
<ToolbarSegment>
|
|
21
|
-
{items.map((item
|
|
22
|
-
|
|
23
|
-
<DragHandleToolbarButton key={
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
{items.map((item) => {
|
|
23
|
+
if (item.type === 'dragHandle') {
|
|
24
|
+
return <DragHandleToolbarButton key={item.tooltip + item.type} {...item} />;
|
|
25
|
+
}
|
|
26
|
+
if (item.type === 'menu') {
|
|
27
|
+
return <MenuToolbarButton key={item.tooltip + item.type} {...item} />;
|
|
28
|
+
}
|
|
29
|
+
if (item.type === 'flyout') {
|
|
30
|
+
return <FlyoutToolbarButton key={item.tooltip + item.type} {...item} />;
|
|
31
|
+
}
|
|
32
|
+
return <ToolbarButton key={item.tooltip + item.type} {...item} />;
|
|
33
|
+
})}
|
|
29
34
|
</ToolbarSegment>
|
|
30
35
|
</div>
|
|
31
36
|
);
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { type ToolbarButtonProps } from './ToolbarButton';
|
|
4
|
-
import { type
|
|
5
|
-
import {
|
|
4
|
+
import { type DragHandleToolbarButtonProps } from './DragHandleToolbarButton';
|
|
5
|
+
import { type FlyoutToolbarButtonProps } from './FlyoutToolbarButton';
|
|
6
|
+
import { type MenuToolbarButtonProps } from './MenuToolbarButton';
|
|
6
7
|
|
|
7
8
|
export type ToolbarProps = {
|
|
8
9
|
items: ToolbarItem[];
|
|
9
|
-
flyoutMenu: { items: ToolbarFlyoutMenuItem[][] };
|
|
10
10
|
attachments: { isEnabled: boolean };
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export type
|
|
13
|
+
export type DragHandleToolbarItem = { type: 'dragHandle' } & DragHandleToolbarButtonProps;
|
|
14
|
+
export type ButtonToolbarItem = { type: 'button' } & ToolbarButtonProps;
|
|
15
|
+
export type FlyoutToolbarItem = { type: 'flyout' } & FlyoutToolbarButtonProps;
|
|
16
|
+
export type MenuToolbarItem = { type: 'menu' } & MenuToolbarButtonProps;
|
|
14
17
|
|
|
15
|
-
export type
|
|
16
|
-
|
|
17
|
-
export type FlyoutToolbarItem = ToolbarFlyoutMenuItem;
|
|
18
|
-
|
|
19
|
-
export type ToolbarItem = DraghandleToolbarItem | ButtonToolbarItem;
|
|
18
|
+
export type ToolbarItem = DragHandleToolbarItem | ButtonToolbarItem | FlyoutToolbarItem | MenuToolbarItem;
|
|
@@ -4,14 +4,13 @@ import { type ReactNode } from 'react';
|
|
|
4
4
|
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
6
|
import { type AttachmentsProvider, type withAttachmentsProvider } from '../../hooks/useAttachments';
|
|
7
|
-
import { type
|
|
7
|
+
import { type ToolbarItem } from './Toolbar';
|
|
8
8
|
|
|
9
9
|
export type BlockItemWrapperProps = {
|
|
10
10
|
children: ReactNode;
|
|
11
11
|
shouldHideWrapper?: boolean;
|
|
12
12
|
shouldHideComponent?: boolean;
|
|
13
13
|
toolbarItems: (ToolbarItem | undefined)[];
|
|
14
|
-
toolbarFlyoutItems: FlyoutToolbarItem[][];
|
|
15
14
|
isDragging?: boolean;
|
|
16
15
|
shouldFillContainer?: boolean;
|
|
17
16
|
outlineOffset?: number;
|