@frontify/guideline-blocks-settings 0.29.17 → 0.30.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 +16 -0
- package/dist/components/Attachments/AttachmentItem.es.js +73 -79
- package/dist/components/Attachments/AttachmentItem.es.js.map +1 -1
- package/dist/components/Attachments/Attachments.es.js +103 -96
- package/dist/components/Attachments/Attachments.es.js.map +1 -1
- package/dist/components/Attachments/AttachmentsButtonTrigger.es.js +21 -0
- package/dist/components/Attachments/AttachmentsButtonTrigger.es.js.map +1 -0
- package/dist/components/BlockItemWrapper/BlockItemWrapper.es.js +47 -43
- package/dist/components/BlockItemWrapper/BlockItemWrapper.es.js.map +1 -1
- package/dist/components/BlockItemWrapper/Toolbar/Toolbar.es.js +123 -0
- package/dist/components/BlockItemWrapper/Toolbar/Toolbar.es.js.map +1 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarAttachments.es.js +27 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarAttachments.es.js.map +1 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarAttachmentsTrigger.es.js +12 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarAttachmentsTrigger.es.js.map +1 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarSegment.es.js +6 -0
- package/dist/components/BlockItemWrapper/Toolbar/ToolbarSegment.es.js.map +1 -0
- package/dist/components/BlockItemWrapper/Toolbar/helpers.es.js +26 -0
- package/dist/components/BlockItemWrapper/Toolbar/helpers.es.js.map +1 -0
- package/dist/hooks/useAttachments.es.js +43 -20
- package/dist/hooks/useAttachments.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 +84 -15
- package/dist/index.es.js +103 -100
- package/dist/index.umd.js +3 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/components/Attachments/AttachmentItem.tsx +2 -13
- package/src/components/Attachments/Attachments.tsx +30 -15
- package/src/components/Attachments/AttachmentsButtonTrigger.tsx +22 -0
- package/src/components/Attachments/types.ts +10 -2
- package/src/components/BlockItemWrapper/BlockItemWrapper.tsx +23 -20
- package/src/components/BlockItemWrapper/Toolbar/Toolbar.spec.tsx +127 -0
- package/src/components/BlockItemWrapper/Toolbar/Toolbar.tsx +133 -0
- package/src/components/BlockItemWrapper/Toolbar/ToolbarAttachments.tsx +29 -0
- package/src/components/BlockItemWrapper/Toolbar/ToolbarAttachmentsTrigger.tsx +14 -0
- package/src/components/BlockItemWrapper/Toolbar/ToolbarSegment.tsx +9 -0
- package/src/components/BlockItemWrapper/Toolbar/helpers.ts +33 -0
- package/src/components/BlockItemWrapper/Toolbar/index.ts +4 -0
- package/src/components/BlockItemWrapper/Toolbar/types.ts +38 -0
- package/src/components/BlockItemWrapper/types.ts +11 -34
- package/src/hooks/{useAttachments.spec.ts → useAttachments.spec.tsx} +55 -4
- package/src/hooks/useAttachments.tsx +95 -0
- package/dist/components/BlockItemWrapper/Toolbar.es.js +0 -117
- package/dist/components/BlockItemWrapper/Toolbar.es.js.map +0 -1
- package/src/components/BlockItemWrapper/Toolbar.tsx +0 -133
- package/src/hooks/useAttachments.ts +0 -46
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { Attachments } from '../../Attachments';
|
|
4
|
+
import { useAttachmentsContext } from '../../../hooks';
|
|
5
|
+
|
|
6
|
+
import { type ToolbarFlyoutState } from './types';
|
|
7
|
+
|
|
8
|
+
import { ToolbarAttachmentsTrigger } from './ToolbarAttachmentsTrigger';
|
|
9
|
+
|
|
10
|
+
export const ToolbarAttachments = ({ isOpen, onOpenChange }: ToolbarFlyoutState) => {
|
|
11
|
+
const { appBridge, attachments, onAttachmentsAdd, onAttachmentDelete, onAttachmentReplace, onAttachmentsSorted } =
|
|
12
|
+
useAttachmentsContext();
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Attachments
|
|
16
|
+
onUpload={onAttachmentsAdd}
|
|
17
|
+
onDelete={onAttachmentDelete}
|
|
18
|
+
onReplaceWithBrowse={onAttachmentReplace}
|
|
19
|
+
onReplaceWithUpload={onAttachmentReplace}
|
|
20
|
+
onSorted={onAttachmentsSorted}
|
|
21
|
+
onBrowse={onAttachmentsAdd}
|
|
22
|
+
items={attachments}
|
|
23
|
+
appBridge={appBridge}
|
|
24
|
+
triggerComponent={ToolbarAttachmentsTrigger}
|
|
25
|
+
isOpen={isOpen}
|
|
26
|
+
onOpenChange={onOpenChange}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { IconCaretDown12, IconPaperclip16 } from '@frontify/fondue';
|
|
4
|
+
import { type AttachmentsTriggerProps } from '../../Attachments/types';
|
|
5
|
+
|
|
6
|
+
import { getToolbarButtonClassNames } from './helpers';
|
|
7
|
+
|
|
8
|
+
export const ToolbarAttachmentsTrigger = ({ children, isFlyoutOpen }: AttachmentsTriggerProps) => (
|
|
9
|
+
<div className={getToolbarButtonClassNames('pointer', isFlyoutOpen)}>
|
|
10
|
+
<IconPaperclip16 />
|
|
11
|
+
{children}
|
|
12
|
+
<IconCaretDown12 />
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export const ToolbarSegment = ({ children }: { children: ReactNode }) => (
|
|
6
|
+
<div className="tw-pointer-events-auto tw-flex tw-flex-shrink-0 tw-gap-px tw-px-px tw-h-[26px] tw-items-center tw-self-start">
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { FOCUS_VISIBLE_STYLE } from '@frontify/fondue';
|
|
4
|
+
|
|
5
|
+
import { joinClassNames } from '../../../utilities';
|
|
6
|
+
|
|
7
|
+
export const getToolbarButtonClassNames = (cursor: 'grab' | 'pointer', forceActiveStyle?: boolean) => {
|
|
8
|
+
const classNames = [
|
|
9
|
+
FOCUS_VISIBLE_STYLE,
|
|
10
|
+
'tw-relative tw-inline-flex tw-items-center tw-justify-center',
|
|
11
|
+
'tw-h-6 tw-p-1',
|
|
12
|
+
'tw-rounded',
|
|
13
|
+
'tw-text-xs tw-font-medium',
|
|
14
|
+
'tw-gap-0.5',
|
|
15
|
+
'focus-visible:tw-z-10',
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
if (forceActiveStyle) {
|
|
19
|
+
classNames.push(
|
|
20
|
+
'tw-bg-box-neutral-pressed',
|
|
21
|
+
'tw-text-box-neutral-inverse-pressed',
|
|
22
|
+
cursor === 'grab' ? 'tw-cursor-grabbing' : 'tw-cursor-pointer',
|
|
23
|
+
);
|
|
24
|
+
} else {
|
|
25
|
+
classNames.push(
|
|
26
|
+
'hover:tw-bg-box-neutral-hover active:tw-bg-box-neutral-pressed',
|
|
27
|
+
'tw-text-text-weak hover:tw-text-box-neutral-inverse-hover active:tw-text-box-neutral-inverse-pressed',
|
|
28
|
+
cursor === 'grab' ? 'tw-cursor-grab active:tw-cursor-grabbing' : 'tw-cursor-pointer',
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return joinClassNames(classNames);
|
|
33
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { type MenuItemStyle } from '@frontify/fondue';
|
|
4
|
+
|
|
5
|
+
export type ToolbarProps = {
|
|
6
|
+
items: ToolbarItem[];
|
|
7
|
+
flyoutMenu: ToolbarFlyoutState & { items: FlyoutToolbarItem[][] };
|
|
8
|
+
attachments: ToolbarFlyoutState & { isEnabled: boolean };
|
|
9
|
+
isDragging?: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type ToolbarFlyoutState = {
|
|
13
|
+
isOpen: boolean;
|
|
14
|
+
onOpenChange: (isOpen: boolean) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type BaseToolbarItem = {
|
|
18
|
+
icon: JSX.Element;
|
|
19
|
+
tooltip?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type DraghandleToolbarItem = BaseToolbarItem & {
|
|
23
|
+
draggableProps: Record<string, unknown>;
|
|
24
|
+
setActivatorNodeRef?: (node: HTMLElement | null) => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type ButtonToolbarItem = BaseToolbarItem & {
|
|
28
|
+
onClick: () => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type ToolbarItem = DraghandleToolbarItem | ButtonToolbarItem;
|
|
32
|
+
|
|
33
|
+
export type FlyoutToolbarItem = {
|
|
34
|
+
title: string;
|
|
35
|
+
onClick: () => void;
|
|
36
|
+
icon: JSX.Element;
|
|
37
|
+
style?: MenuItemStyle;
|
|
38
|
+
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
|
+
import { type AttachmentsProvider, type withAttachmentsProvider } from '../../hooks/useAttachments';
|
|
7
|
+
import { type FlyoutToolbarItem, type ToolbarItem } from './Toolbar';
|
|
5
8
|
|
|
6
9
|
export type BlockItemWrapperProps = {
|
|
7
10
|
children: ReactNode;
|
|
@@ -13,36 +16,10 @@ export type BlockItemWrapperProps = {
|
|
|
13
16
|
shouldFillContainer?: boolean;
|
|
14
17
|
outlineOffset?: number;
|
|
15
18
|
shouldBeShown?: boolean;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
setIsFlyoutOpen: (isOpen: boolean) => void;
|
|
23
|
-
isDragging?: boolean;
|
|
24
|
-
isFlyoutDisabled?: boolean;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type BaseToolbarItem = {
|
|
28
|
-
icon: JSX.Element;
|
|
29
|
-
tooltip?: string;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
type DraghandleToolbarItem = BaseToolbarItem & {
|
|
33
|
-
draggableProps: Record<string, unknown>;
|
|
34
|
-
setActivatorNodeRef?: (node: HTMLElement | null) => void;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
type ButtonToolbarItem = BaseToolbarItem & {
|
|
38
|
-
onClick: () => void;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export type ToolbarItem = DraghandleToolbarItem | ButtonToolbarItem;
|
|
42
|
-
|
|
43
|
-
export type FlyoutToolbarItem = {
|
|
44
|
-
title: string;
|
|
45
|
-
onClick: () => void;
|
|
46
|
-
icon: JSX.Element;
|
|
47
|
-
style?: MenuItemStyle;
|
|
19
|
+
/**
|
|
20
|
+
* When set to true the BlockItemWrapper must be a child of a {@link AttachmentsProvider} component,
|
|
21
|
+
* or the block must be wrapped with a {@link withAttachmentsProvider} HOC.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
showAttachments?: boolean;
|
|
48
25
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { AssetDummy, getAppBridgeBlockStub } from '@frontify/app-bridge';
|
|
4
|
-
import { renderHook, waitFor } from '@testing-library/react';
|
|
5
|
-
|
|
4
|
+
import { render, renderHook, waitFor } from '@testing-library/react';
|
|
6
5
|
import { describe, expect, it } from 'vitest';
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
import { AttachmentsProvider, useAttachments, useAttachmentsContext, withAttachmentsProvider } from './useAttachments';
|
|
8
8
|
|
|
9
9
|
const MOCK_SETTINGS_ID = 'attachments';
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ describe('useAttachments', () => {
|
|
|
20
20
|
});
|
|
21
21
|
const { result } = renderHook(() => useAttachments(STUB_WITH_NO_ASSETS, MOCK_SETTINGS_ID));
|
|
22
22
|
|
|
23
|
-
await result.current.
|
|
23
|
+
await result.current.onAttachmentsAdd([AssetDummy.with(1)]);
|
|
24
24
|
await waitFor(() => {
|
|
25
25
|
expect(result.current.attachments).toHaveLength(1);
|
|
26
26
|
});
|
|
@@ -77,3 +77,54 @@ describe('useAttachments', () => {
|
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
});
|
|
80
|
+
|
|
81
|
+
describe('useAttachmentsContext', () => {
|
|
82
|
+
it('should throw an error when not a child of a provider', async () => {
|
|
83
|
+
expect(() => renderHook(() => useAttachmentsContext())).toThrowError();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should return correct info', async () => {
|
|
87
|
+
const STUB_WITH_NO_ASSETS = getAppBridgeBlockStub({
|
|
88
|
+
blockId: 1,
|
|
89
|
+
blockAssets: { [MOCK_SETTINGS_ID]: [AssetDummy.with(1)] },
|
|
90
|
+
});
|
|
91
|
+
const { result } = renderHook(useAttachmentsContext, {
|
|
92
|
+
wrapper: ({ children }) => (
|
|
93
|
+
<AttachmentsProvider appBridge={STUB_WITH_NO_ASSETS} assetId={MOCK_SETTINGS_ID}>
|
|
94
|
+
{children}
|
|
95
|
+
</AttachmentsProvider>
|
|
96
|
+
),
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(result.current.appBridge).toEqual(STUB_WITH_NO_ASSETS);
|
|
100
|
+
await waitFor(() => {
|
|
101
|
+
expect(result.current.attachments).toHaveLength(1);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('withAttachmentsProvider', () => {
|
|
107
|
+
it('should provide correct info to context consumer', async () => {
|
|
108
|
+
const STUB_WITH_THREE_ASSETS = getAppBridgeBlockStub({
|
|
109
|
+
blockId: 2,
|
|
110
|
+
blockAssets: { [MOCK_SETTINGS_ID]: [AssetDummy.with(1), AssetDummy.with(2), AssetDummy.with(3)] },
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const Component = withAttachmentsProvider(() => {
|
|
114
|
+
const context = useAttachmentsContext();
|
|
115
|
+
return (
|
|
116
|
+
<ul>
|
|
117
|
+
{context.attachments.map((attachment) => (
|
|
118
|
+
<li key={attachment.id} role="list">
|
|
119
|
+
{attachment.id}
|
|
120
|
+
</li>
|
|
121
|
+
))}
|
|
122
|
+
</ul>
|
|
123
|
+
);
|
|
124
|
+
}, MOCK_SETTINGS_ID);
|
|
125
|
+
|
|
126
|
+
const { getAllByRole } = render(<Component appBridge={STUB_WITH_THREE_ASSETS} />);
|
|
127
|
+
|
|
128
|
+
await waitFor(() => expect(getAllByRole('list')).toHaveLength(3));
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { AppBridgeBlock, Asset, useBlockAssets } from '@frontify/app-bridge';
|
|
4
|
+
import { type ReactNode, createContext, useContext } from 'react';
|
|
5
|
+
|
|
6
|
+
import { type BlockProps } from '../index';
|
|
7
|
+
|
|
8
|
+
export const useAttachments = (appBridge: AppBridgeBlock, assetId: string) => {
|
|
9
|
+
const { blockAssets, updateAssetIdsFromKey } = useBlockAssets(appBridge);
|
|
10
|
+
const attachments = blockAssets?.[assetId] || [];
|
|
11
|
+
|
|
12
|
+
const onAttachmentsAdd = async (newAssets: Asset[]) => {
|
|
13
|
+
const newAssetIds = attachments.map((attachment) => attachment.id);
|
|
14
|
+
for (const asset of newAssets) {
|
|
15
|
+
newAssetIds.push(asset.id);
|
|
16
|
+
}
|
|
17
|
+
await updateAssetIdsFromKey(assetId, newAssetIds);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const onAttachmentDelete = async (assetToDelete: Asset) => {
|
|
21
|
+
const newAssetIds = attachments
|
|
22
|
+
.filter((attachment) => attachment.id !== assetToDelete.id)
|
|
23
|
+
.map((attachment) => attachment.id);
|
|
24
|
+
|
|
25
|
+
await updateAssetIdsFromKey(assetId, newAssetIds);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const onAttachmentReplace = async (attachmentToReplace: Asset, newAsset: Asset) => {
|
|
29
|
+
const newAssetIds = attachments.map((attachment) =>
|
|
30
|
+
attachment.id === attachmentToReplace.id ? newAsset.id : attachment.id,
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
await updateAssetIdsFromKey(assetId, newAssetIds);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const onAttachmentsSorted = async (assets: Asset[]) => {
|
|
37
|
+
const newAssetIds = assets.map((asset) => asset.id);
|
|
38
|
+
|
|
39
|
+
await updateAssetIdsFromKey(assetId, newAssetIds);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
onAttachmentsAdd,
|
|
44
|
+
onAttachmentDelete,
|
|
45
|
+
onAttachmentReplace,
|
|
46
|
+
onAttachmentsSorted,
|
|
47
|
+
attachments,
|
|
48
|
+
appBridge,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const AttachmentsContext = createContext<ReturnType<typeof useAttachments> | null>(null);
|
|
53
|
+
|
|
54
|
+
export const AttachmentsProvider = ({
|
|
55
|
+
appBridge,
|
|
56
|
+
children,
|
|
57
|
+
assetId,
|
|
58
|
+
}: {
|
|
59
|
+
appBridge: AppBridgeBlock;
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
assetId: string;
|
|
62
|
+
}) => {
|
|
63
|
+
const attachmentContext = useAttachments(appBridge, assetId);
|
|
64
|
+
|
|
65
|
+
return <AttachmentsContext.Provider value={attachmentContext}>{children}</AttachmentsContext.Provider>;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const useAttachmentsContext = () => {
|
|
69
|
+
const context = useContext(AttachmentsContext);
|
|
70
|
+
|
|
71
|
+
if (!context) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"No AttachmentsContext Provided. Component must be wrapped in an 'AttachmentsProvider' or the 'withAttachmentsProvider' HOC",
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return context;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Block-level HOC for cases when there is only one attachment asset field related to the block.
|
|
82
|
+
* Recommended for most cases.
|
|
83
|
+
* If finer control is required over attachments, use {@link AttachmentsProvider} component.
|
|
84
|
+
*/
|
|
85
|
+
export const withAttachmentsProvider = <T extends BlockProps>(Component: (props: T) => ReactNode, assetId: string) => {
|
|
86
|
+
const wrappedComponent = (props: T) => (
|
|
87
|
+
<AttachmentsProvider appBridge={props.appBridge} assetId={assetId}>
|
|
88
|
+
<Component {...props} />
|
|
89
|
+
</AttachmentsProvider>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
wrappedComponent.displayName = 'withAttachmentsProvider';
|
|
93
|
+
|
|
94
|
+
return wrappedComponent;
|
|
95
|
+
};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { jsx as e, jsxs as u } from "react/jsx-runtime";
|
|
2
|
-
import { LegacyTooltip as l, TooltipPosition as n, FOCUS_VISIBLE_STYLE as a, Flyout as v, IconDotsHorizontal16 as m, ActionMenu as f, MenuItemContentSize as x } from "@frontify/fondue";
|
|
3
|
-
import { DEFAULT_DRAGGING_TOOLTIP as g, DEFAULT_DRAG_TOOLTIP as y } from "./constants.es.js";
|
|
4
|
-
import { joinClassNames as c } from "../../utilities/react/joinClassNames.es.js";
|
|
5
|
-
const C = ({
|
|
6
|
-
items: d,
|
|
7
|
-
flyoutItems: s,
|
|
8
|
-
isFlyoutOpen: b,
|
|
9
|
-
setIsFlyoutOpen: w,
|
|
10
|
-
isDragging: r,
|
|
11
|
-
isFlyoutDisabled: p
|
|
12
|
-
}) => /* @__PURE__ */ e("div", { "data-test-id": "block-item-wrapper-toolbar", className: "tw-flex tw-justify-end", children: /* @__PURE__ */ u("div", { className: "tw-bg-white tw-isolate tw-text-box-selected-inverse tw-pointer-events-auto tw-flex tw-flex-shrink-0 tw-gap-[2px] tw-px-[1px] tw-spacing tw-items-center tw-h-7 tw-self-start tw-border tw-border-box-selected-inverse tw-rounded", children: [
|
|
13
|
-
d.map(
|
|
14
|
-
(t, o) => "draggableProps" in t ? /* @__PURE__ */ e(
|
|
15
|
-
l,
|
|
16
|
-
{
|
|
17
|
-
withArrow: !0,
|
|
18
|
-
hoverDelay: 0,
|
|
19
|
-
enterDelay: 300,
|
|
20
|
-
open: r,
|
|
21
|
-
position: n.Top,
|
|
22
|
-
content: /* @__PURE__ */ e("div", { children: r ? g : t.tooltip ?? y }),
|
|
23
|
-
triggerElement: /* @__PURE__ */ e(
|
|
24
|
-
"button",
|
|
25
|
-
{
|
|
26
|
-
ref: t.setActivatorNodeRef,
|
|
27
|
-
"data-test-id": "block-item-wrapper-toolbar-btn",
|
|
28
|
-
...t.draggableProps,
|
|
29
|
-
className: c([
|
|
30
|
-
a,
|
|
31
|
-
"tw-bg-base tw-relative tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10",
|
|
32
|
-
r ? "tw-cursor-grabbing tw-bg-box-selected-pressed" : "tw-cursor-grab hover:tw-bg-box-selected-hover"
|
|
33
|
-
]),
|
|
34
|
-
children: t.icon
|
|
35
|
-
}
|
|
36
|
-
)
|
|
37
|
-
},
|
|
38
|
-
o
|
|
39
|
-
) : /* @__PURE__ */ e(
|
|
40
|
-
l,
|
|
41
|
-
{
|
|
42
|
-
withArrow: !0,
|
|
43
|
-
enterDelay: 300,
|
|
44
|
-
hoverDelay: 0,
|
|
45
|
-
disabled: r,
|
|
46
|
-
position: n.Top,
|
|
47
|
-
content: /* @__PURE__ */ e("div", { children: t.tooltip ?? "" }),
|
|
48
|
-
triggerElement: /* @__PURE__ */ e(
|
|
49
|
-
"button",
|
|
50
|
-
{
|
|
51
|
-
"data-test-id": "block-item-wrapper-toolbar-btn",
|
|
52
|
-
onClick: t.onClick,
|
|
53
|
-
className: c([
|
|
54
|
-
"tw-bg-base tw-relative hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10",
|
|
55
|
-
a
|
|
56
|
-
]),
|
|
57
|
-
children: t.icon
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
},
|
|
61
|
-
o
|
|
62
|
-
)
|
|
63
|
-
),
|
|
64
|
-
s.length > 0 && /* @__PURE__ */ e("div", { className: "tw-flex tw-flex-shrink-0 tw-flex-1 tw-h-6 tw-relative", children: /* @__PURE__ */ e(
|
|
65
|
-
v,
|
|
66
|
-
{
|
|
67
|
-
isOpen: b && !r,
|
|
68
|
-
isTriggerDisabled: p,
|
|
69
|
-
legacyFooter: !1,
|
|
70
|
-
fitContent: !0,
|
|
71
|
-
hug: !1,
|
|
72
|
-
onOpenChange: w,
|
|
73
|
-
trigger: /* @__PURE__ */ e(
|
|
74
|
-
l,
|
|
75
|
-
{
|
|
76
|
-
withArrow: !0,
|
|
77
|
-
hoverDelay: 0,
|
|
78
|
-
enterDelay: 300,
|
|
79
|
-
disabled: r,
|
|
80
|
-
position: n.Top,
|
|
81
|
-
content: /* @__PURE__ */ e("div", { children: "Options" }),
|
|
82
|
-
triggerElement: /* @__PURE__ */ e(
|
|
83
|
-
"div",
|
|
84
|
-
{
|
|
85
|
-
"data-test-id": "block-item-wrapper-toolbar-flyout",
|
|
86
|
-
className: "tw-bg-base hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm tw-relative",
|
|
87
|
-
children: /* @__PURE__ */ e(m, {})
|
|
88
|
-
}
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
),
|
|
92
|
-
children: /* @__PURE__ */ e(
|
|
93
|
-
f,
|
|
94
|
-
{
|
|
95
|
-
menuBlocks: s.map((t, o) => ({
|
|
96
|
-
id: o.toString(),
|
|
97
|
-
menuItems: t.map((i, h) => ({
|
|
98
|
-
id: o.toString() + h.toString(),
|
|
99
|
-
size: x.XSmall,
|
|
100
|
-
title: i.title,
|
|
101
|
-
style: i.style,
|
|
102
|
-
onClick: () => {
|
|
103
|
-
w(!1), i.onClick();
|
|
104
|
-
},
|
|
105
|
-
initialValue: !0,
|
|
106
|
-
decorator: /* @__PURE__ */ e("div", { className: "tw-mr-2", children: i.icon })
|
|
107
|
-
}))
|
|
108
|
-
}))
|
|
109
|
-
}
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
) })
|
|
113
|
-
] }) });
|
|
114
|
-
export {
|
|
115
|
-
C as Toolbar
|
|
116
|
-
};
|
|
117
|
-
//# sourceMappingURL=Toolbar.es.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbar.es.js","sources":["../../../src/components/BlockItemWrapper/Toolbar.tsx"],"sourcesContent":["/* (c) Copyright Frontify Ltd., all rights reserved. */\n\nimport {\n ActionMenu,\n FOCUS_VISIBLE_STYLE,\n Flyout,\n IconDotsHorizontal16,\n MenuItemContentSize,\n LegacyTooltip as Tooltip,\n TooltipPosition,\n} from '@frontify/fondue';\nimport { ToolbarProps } from './types';\nimport { joinClassNames } from '../../utilities';\nimport { DEFAULT_DRAGGING_TOOLTIP, DEFAULT_DRAG_TOOLTIP } from './constants';\n\nexport const Toolbar = ({\n items,\n flyoutItems,\n isFlyoutOpen,\n setIsFlyoutOpen,\n isDragging,\n isFlyoutDisabled,\n}: ToolbarProps) => {\n return (\n <div data-test-id=\"block-item-wrapper-toolbar\" className=\"tw-flex tw-justify-end\">\n <div className=\"tw-bg-white tw-isolate tw-text-box-selected-inverse tw-pointer-events-auto tw-flex tw-flex-shrink-0 tw-gap-[2px] tw-px-[1px] tw-spacing tw-items-center tw-h-7 tw-self-start tw-border tw-border-box-selected-inverse tw-rounded\">\n {items.map((item, i) =>\n 'draggableProps' in item ? (\n <Tooltip\n key={i}\n withArrow\n hoverDelay={0}\n enterDelay={300}\n open={isDragging}\n position={TooltipPosition.Top}\n content={\n <div>\n {isDragging ? DEFAULT_DRAGGING_TOOLTIP : item.tooltip ?? DEFAULT_DRAG_TOOLTIP}\n </div>\n }\n triggerElement={\n <button\n ref={item.setActivatorNodeRef}\n data-test-id=\"block-item-wrapper-toolbar-btn\"\n {...item.draggableProps}\n className={joinClassNames([\n FOCUS_VISIBLE_STYLE,\n 'tw-bg-base tw-relative tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10',\n isDragging\n ? 'tw-cursor-grabbing tw-bg-box-selected-pressed'\n : 'tw-cursor-grab hover:tw-bg-box-selected-hover',\n ])}\n >\n {item.icon}\n </button>\n }\n />\n ) : (\n <Tooltip\n key={i}\n withArrow\n enterDelay={300}\n hoverDelay={0}\n disabled={isDragging}\n position={TooltipPosition.Top}\n content={<div>{item.tooltip ?? ''}</div>}\n triggerElement={\n <button\n data-test-id=\"block-item-wrapper-toolbar-btn\"\n onClick={item.onClick}\n className={joinClassNames([\n 'tw-bg-base tw-relative hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10',\n FOCUS_VISIBLE_STYLE,\n ])}\n >\n {item.icon}\n </button>\n }\n />\n ),\n )}\n {flyoutItems.length > 0 && (\n <div className=\"tw-flex tw-flex-shrink-0 tw-flex-1 tw-h-6 tw-relative\">\n <Flyout\n isOpen={isFlyoutOpen && !isDragging}\n isTriggerDisabled={isFlyoutDisabled}\n legacyFooter={false}\n fitContent\n hug={false}\n onOpenChange={setIsFlyoutOpen}\n trigger={\n <Tooltip\n withArrow\n hoverDelay={0}\n enterDelay={300}\n disabled={isDragging}\n position={TooltipPosition.Top}\n content={<div>Options</div>}\n triggerElement={\n <div\n data-test-id=\"block-item-wrapper-toolbar-flyout\"\n className=\"tw-bg-base hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm tw-relative\"\n >\n <IconDotsHorizontal16 />\n </div>\n }\n />\n }\n >\n <ActionMenu\n menuBlocks={flyoutItems.map((block, blockIndex) => ({\n id: blockIndex.toString(),\n menuItems: block.map((item, itemIndex) => ({\n id: blockIndex.toString() + itemIndex.toString(),\n size: MenuItemContentSize.XSmall,\n title: item.title,\n style: item.style,\n onClick: () => {\n setIsFlyoutOpen(false);\n item.onClick();\n },\n initialValue: true,\n decorator: <div className=\"tw-mr-2\">{item.icon}</div>,\n })),\n }))}\n />\n </Flyout>\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["Toolbar","items","flyoutItems","isFlyoutOpen","setIsFlyoutOpen","isDragging","isFlyoutDisabled","jsx","jsxs","item","i","Tooltip","TooltipPosition","DEFAULT_DRAGGING_TOOLTIP","DEFAULT_DRAG_TOOLTIP","joinClassNames","FOCUS_VISIBLE_STYLE","Flyout","IconDotsHorizontal16","ActionMenu","block","blockIndex","itemIndex","MenuItemContentSize"],"mappings":"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"}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
/* (c) Copyright Frontify Ltd., all rights reserved. */
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ActionMenu,
|
|
5
|
-
FOCUS_VISIBLE_STYLE,
|
|
6
|
-
Flyout,
|
|
7
|
-
IconDotsHorizontal16,
|
|
8
|
-
MenuItemContentSize,
|
|
9
|
-
LegacyTooltip as Tooltip,
|
|
10
|
-
TooltipPosition,
|
|
11
|
-
} from '@frontify/fondue';
|
|
12
|
-
import { ToolbarProps } from './types';
|
|
13
|
-
import { joinClassNames } from '../../utilities';
|
|
14
|
-
import { DEFAULT_DRAGGING_TOOLTIP, DEFAULT_DRAG_TOOLTIP } from './constants';
|
|
15
|
-
|
|
16
|
-
export const Toolbar = ({
|
|
17
|
-
items,
|
|
18
|
-
flyoutItems,
|
|
19
|
-
isFlyoutOpen,
|
|
20
|
-
setIsFlyoutOpen,
|
|
21
|
-
isDragging,
|
|
22
|
-
isFlyoutDisabled,
|
|
23
|
-
}: ToolbarProps) => {
|
|
24
|
-
return (
|
|
25
|
-
<div data-test-id="block-item-wrapper-toolbar" className="tw-flex tw-justify-end">
|
|
26
|
-
<div className="tw-bg-white tw-isolate tw-text-box-selected-inverse tw-pointer-events-auto tw-flex tw-flex-shrink-0 tw-gap-[2px] tw-px-[1px] tw-spacing tw-items-center tw-h-7 tw-self-start tw-border tw-border-box-selected-inverse tw-rounded">
|
|
27
|
-
{items.map((item, i) =>
|
|
28
|
-
'draggableProps' in item ? (
|
|
29
|
-
<Tooltip
|
|
30
|
-
key={i}
|
|
31
|
-
withArrow
|
|
32
|
-
hoverDelay={0}
|
|
33
|
-
enterDelay={300}
|
|
34
|
-
open={isDragging}
|
|
35
|
-
position={TooltipPosition.Top}
|
|
36
|
-
content={
|
|
37
|
-
<div>
|
|
38
|
-
{isDragging ? DEFAULT_DRAGGING_TOOLTIP : item.tooltip ?? DEFAULT_DRAG_TOOLTIP}
|
|
39
|
-
</div>
|
|
40
|
-
}
|
|
41
|
-
triggerElement={
|
|
42
|
-
<button
|
|
43
|
-
ref={item.setActivatorNodeRef}
|
|
44
|
-
data-test-id="block-item-wrapper-toolbar-btn"
|
|
45
|
-
{...item.draggableProps}
|
|
46
|
-
className={joinClassNames([
|
|
47
|
-
FOCUS_VISIBLE_STYLE,
|
|
48
|
-
'tw-bg-base tw-relative tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10',
|
|
49
|
-
isDragging
|
|
50
|
-
? 'tw-cursor-grabbing tw-bg-box-selected-pressed'
|
|
51
|
-
: 'tw-cursor-grab hover:tw-bg-box-selected-hover',
|
|
52
|
-
])}
|
|
53
|
-
>
|
|
54
|
-
{item.icon}
|
|
55
|
-
</button>
|
|
56
|
-
}
|
|
57
|
-
/>
|
|
58
|
-
) : (
|
|
59
|
-
<Tooltip
|
|
60
|
-
key={i}
|
|
61
|
-
withArrow
|
|
62
|
-
enterDelay={300}
|
|
63
|
-
hoverDelay={0}
|
|
64
|
-
disabled={isDragging}
|
|
65
|
-
position={TooltipPosition.Top}
|
|
66
|
-
content={<div>{item.tooltip ?? ''}</div>}
|
|
67
|
-
triggerElement={
|
|
68
|
-
<button
|
|
69
|
-
data-test-id="block-item-wrapper-toolbar-btn"
|
|
70
|
-
onClick={item.onClick}
|
|
71
|
-
className={joinClassNames([
|
|
72
|
-
'tw-bg-base tw-relative hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm focus-visible:tw-z-10',
|
|
73
|
-
FOCUS_VISIBLE_STYLE,
|
|
74
|
-
])}
|
|
75
|
-
>
|
|
76
|
-
{item.icon}
|
|
77
|
-
</button>
|
|
78
|
-
}
|
|
79
|
-
/>
|
|
80
|
-
),
|
|
81
|
-
)}
|
|
82
|
-
{flyoutItems.length > 0 && (
|
|
83
|
-
<div className="tw-flex tw-flex-shrink-0 tw-flex-1 tw-h-6 tw-relative">
|
|
84
|
-
<Flyout
|
|
85
|
-
isOpen={isFlyoutOpen && !isDragging}
|
|
86
|
-
isTriggerDisabled={isFlyoutDisabled}
|
|
87
|
-
legacyFooter={false}
|
|
88
|
-
fitContent
|
|
89
|
-
hug={false}
|
|
90
|
-
onOpenChange={setIsFlyoutOpen}
|
|
91
|
-
trigger={
|
|
92
|
-
<Tooltip
|
|
93
|
-
withArrow
|
|
94
|
-
hoverDelay={0}
|
|
95
|
-
enterDelay={300}
|
|
96
|
-
disabled={isDragging}
|
|
97
|
-
position={TooltipPosition.Top}
|
|
98
|
-
content={<div>Options</div>}
|
|
99
|
-
triggerElement={
|
|
100
|
-
<div
|
|
101
|
-
data-test-id="block-item-wrapper-toolbar-flyout"
|
|
102
|
-
className="tw-bg-base hover:tw-bg-box-selected-hover active:tw-bg-box-selected-pressed tw-cursor-pointer tw-inline-flex tw-items-center tw-justify-center tw-w-6 tw-h-6 tw-rounded-sm tw-relative"
|
|
103
|
-
>
|
|
104
|
-
<IconDotsHorizontal16 />
|
|
105
|
-
</div>
|
|
106
|
-
}
|
|
107
|
-
/>
|
|
108
|
-
}
|
|
109
|
-
>
|
|
110
|
-
<ActionMenu
|
|
111
|
-
menuBlocks={flyoutItems.map((block, blockIndex) => ({
|
|
112
|
-
id: blockIndex.toString(),
|
|
113
|
-
menuItems: block.map((item, itemIndex) => ({
|
|
114
|
-
id: blockIndex.toString() + itemIndex.toString(),
|
|
115
|
-
size: MenuItemContentSize.XSmall,
|
|
116
|
-
title: item.title,
|
|
117
|
-
style: item.style,
|
|
118
|
-
onClick: () => {
|
|
119
|
-
setIsFlyoutOpen(false);
|
|
120
|
-
item.onClick();
|
|
121
|
-
},
|
|
122
|
-
initialValue: true,
|
|
123
|
-
decorator: <div className="tw-mr-2">{item.icon}</div>,
|
|
124
|
-
})),
|
|
125
|
-
}))}
|
|
126
|
-
/>
|
|
127
|
-
</Flyout>
|
|
128
|
-
</div>
|
|
129
|
-
)}
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
132
|
-
);
|
|
133
|
-
};
|