@fibery/ui-kit 1.29.1 → 1.29.4
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/package.json +4 -4
- package/src/actions-menu/actions-menu-confirmation.tsx +70 -0
- package/src/actions-menu/actions-menu-item.tsx +3 -1
- package/src/actions-menu/actions-menu-sub-command-menu.tsx +104 -141
- package/src/actions-menu/actions-menu-sub-menu.tsx +3 -1
- package/src/actions-menu/actions-menu.tsx +6 -1
- package/src/actions-menu/context-actions-menu.tsx +5 -1
- package/src/actions-menu/contexts/actions-menu-context.tsx +6 -2
- package/src/button/button-base.tsx +1 -1
- package/src/button/button.tsx +1 -1
- package/src/design-system.ts +83 -25
- package/src/dropdown-menu/index.tsx +7 -2
- package/src/emoji-picker/primitives/footer.tsx +1 -1
- package/src/icons/ast/Abort.ts +8 -0
- package/src/icons/ast/AiAvatar.ts +1 -1
- package/src/icons/ast/Database.ts +1 -1
- package/src/icons/ast/DatabaseStroke.ts +8 -0
- package/src/icons/ast/ExtensionComments.ts +1 -1
- package/src/icons/ast/FieldUnit.ts +8 -0
- package/src/icons/ast/InfoCircle.ts +8 -0
- package/src/icons/ast/IntegrationsIntegrationDiscourseColor.ts +8 -0
- package/src/icons/ast/IntegrationsIntegrationIntercomColor.ts +8 -0
- package/src/icons/ast/IntegrationsIntegrationSlackColor.ts +8 -0
- package/src/icons/ast/IntegrationsIntegrationZendeskColor.ts +8 -0
- package/src/icons/ast/Key.ts +8 -0
- package/src/icons/ast/MoveBottom.ts +8 -0
- package/src/icons/ast/MoveLeft.ts +8 -0
- package/src/icons/ast/MoveRight.ts +8 -0
- package/src/icons/ast/MoveTop.ts +8 -0
- package/src/icons/ast/Pin.ts +8 -0
- package/src/icons/ast/RicheditorCommentCreate.ts +1 -1
- package/src/icons/ast/SendArrow.ts +8 -0
- package/src/icons/ast/UnitsAvatar.ts +8 -0
- package/src/icons/ast/UnitsCollection.ts +8 -0
- package/src/icons/ast/UnitsCounter.ts +8 -0
- package/src/icons/ast/UnitsDbBadgeAbbr.ts +8 -0
- package/src/icons/ast/UnitsDbBadgeFull.ts +8 -0
- package/src/icons/ast/UnitsDbIcon.ts +8 -0
- package/src/icons/ast/UnitsField.ts +8 -0
- package/src/icons/ast/UnitsInput.ts +8 -0
- package/src/icons/ast/UnitsProgressBar.ts +8 -0
- package/src/icons/ast/UnitsRichText.ts +8 -0
- package/src/icons/ast/UnitsSnippet.ts +8 -0
- package/src/icons/ast/index.tsx +26 -0
- package/src/icons/react/Abort.tsx +12 -0
- package/src/icons/react/DatabaseStroke.tsx +12 -0
- package/src/icons/react/FieldUnit.tsx +12 -0
- package/src/icons/react/InfoCircle.tsx +12 -0
- package/src/icons/react/IntegrationsIntegrationDiscourseColor.tsx +12 -0
- package/src/icons/react/IntegrationsIntegrationIntercomColor.tsx +12 -0
- package/src/icons/react/IntegrationsIntegrationSlackColor.tsx +12 -0
- package/src/icons/react/IntegrationsIntegrationZendeskColor.tsx +12 -0
- package/src/icons/react/Key.tsx +12 -0
- package/src/icons/react/MoveBottom.tsx +12 -0
- package/src/icons/react/MoveLeft.tsx +12 -0
- package/src/icons/react/MoveRight.tsx +12 -0
- package/src/icons/react/MoveTop.tsx +12 -0
- package/src/icons/react/Pin.tsx +12 -0
- package/src/icons/react/SendArrow.tsx +12 -0
- package/src/icons/react/UnitsAvatar.tsx +12 -0
- package/src/icons/react/UnitsCollection.tsx +12 -0
- package/src/icons/react/UnitsCounter.tsx +12 -0
- package/src/icons/react/UnitsDbBadgeAbbr.tsx +12 -0
- package/src/icons/react/UnitsDbBadgeFull.tsx +12 -0
- package/src/icons/react/UnitsDbIcon.tsx +12 -0
- package/src/icons/react/UnitsField.tsx +12 -0
- package/src/icons/react/UnitsInput.tsx +12 -0
- package/src/icons/react/UnitsProgressBar.tsx +12 -0
- package/src/icons/react/UnitsRichText.tsx +12 -0
- package/src/icons/react/UnitsSnippet.tsx +12 -0
- package/src/icons/react/index.tsx +26 -0
- package/src/item.tsx +1 -1
- package/src/select/custom-select-partials/menu.tsx +1 -1
- package/src/select/select-in-popover.tsx +58 -11
- package/src/theme-settings.ts +10 -8
- package/src/toggle.tsx +3 -1
- package/src/tooltip.tsx +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fibery/ui-kit",
|
|
3
|
-
"version": "1.29.
|
|
3
|
+
"version": "1.29.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"files": [
|
|
6
6
|
"src/antd/styles.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"chroma-js": "2.1.2",
|
|
55
55
|
"chrono-node": "^2.7.5",
|
|
56
56
|
"classnames": "2.3.1",
|
|
57
|
-
"cmdk": "0.
|
|
57
|
+
"cmdk": "1.0.0",
|
|
58
58
|
"color-hash": "1.0.3",
|
|
59
59
|
"d3-shape": "1.3.7",
|
|
60
60
|
"date-fns": "2.29.2",
|
|
@@ -110,8 +110,8 @@
|
|
|
110
110
|
"svgo": "2.8.0",
|
|
111
111
|
"typescript": "5.4.3",
|
|
112
112
|
"unist-util-reduce": "0.2.2",
|
|
113
|
-
"@fibery/
|
|
114
|
-
"@fibery/
|
|
113
|
+
"@fibery/babel-preset": "7.4.0",
|
|
114
|
+
"@fibery/eslint-config": "8.6.0"
|
|
115
115
|
},
|
|
116
116
|
"jest": {
|
|
117
117
|
"testEnvironment": "jsdom",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {css} from "@linaria/core";
|
|
2
|
+
import {AntModal} from "../antd/ant-modal";
|
|
3
|
+
import {border, space, themeVars} from "../design-system";
|
|
4
|
+
import {ActionsPanel} from "../actions-panel";
|
|
5
|
+
import {Button} from "../button";
|
|
6
|
+
import {useActionsMenuContext} from "./contexts/actions-menu-context";
|
|
7
|
+
|
|
8
|
+
const modalClass = css`
|
|
9
|
+
& .ant-modal-content {
|
|
10
|
+
box-shadow: ${themeVars.shadowModal};
|
|
11
|
+
margin-left: ${space.s6}px;
|
|
12
|
+
margin-right: ${space.s6}px;
|
|
13
|
+
background-color: ${themeVars.modalContentBg};
|
|
14
|
+
border-radius: ${border.radius6}px;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export type ActionsMenuConfirmationProps = {
|
|
19
|
+
message: string;
|
|
20
|
+
onCancel?: () => void;
|
|
21
|
+
onConfirm: () => void;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const ActionsMenuConfirmation: React.FC<ActionsMenuConfirmationProps> = ({message, onCancel, onConfirm}) => {
|
|
25
|
+
const {showConfirmation} = useActionsMenuContext();
|
|
26
|
+
|
|
27
|
+
// TODO: use radix dialog
|
|
28
|
+
return (
|
|
29
|
+
<AntModal
|
|
30
|
+
zIndex={1001} // ant vs radix -- round 1
|
|
31
|
+
open={true}
|
|
32
|
+
closable={false}
|
|
33
|
+
footer={null}
|
|
34
|
+
maskStyle={{backgroundColor: themeVars.modalBg}}
|
|
35
|
+
className={modalClass}
|
|
36
|
+
maskClosable
|
|
37
|
+
onCancel={() => showConfirmation(null)}
|
|
38
|
+
>
|
|
39
|
+
{message}
|
|
40
|
+
|
|
41
|
+
<div
|
|
42
|
+
className={css`
|
|
43
|
+
margin-top: ${space.s24}px;
|
|
44
|
+
display: flex;
|
|
45
|
+
gap: ${space.s6}px;
|
|
46
|
+
`}
|
|
47
|
+
>
|
|
48
|
+
<ActionsPanel inline>
|
|
49
|
+
<Button
|
|
50
|
+
primary
|
|
51
|
+
onClick={() => {
|
|
52
|
+
onConfirm();
|
|
53
|
+
showConfirmation(null);
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
Proceed
|
|
57
|
+
</Button>
|
|
58
|
+
<Button
|
|
59
|
+
onClick={() => {
|
|
60
|
+
showConfirmation(null);
|
|
61
|
+
onCancel?.();
|
|
62
|
+
}}
|
|
63
|
+
>
|
|
64
|
+
Cancel
|
|
65
|
+
</Button>
|
|
66
|
+
</ActionsPanel>
|
|
67
|
+
</div>
|
|
68
|
+
</AntModal>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -40,6 +40,8 @@ const dangerousItemCss = css`
|
|
|
40
40
|
&[data-highlighted] {
|
|
41
41
|
color: ${themeVars.danger};
|
|
42
42
|
background-color: ${themeVars.colorBgActionsMenuItemDangerHover};
|
|
43
|
+
|
|
44
|
+
--actions-menu-item-icon-color: ${themeVars.danger};
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
`;
|
|
@@ -94,7 +96,7 @@ const RightCorner = ({shortcut, loading, checked}: {shortcut?: string; loading?:
|
|
|
94
96
|
const LeftCorner = ({Icon}: {Icon: FunctionComponent<IconBaseProps> | void}) => {
|
|
95
97
|
return Icon ? (
|
|
96
98
|
<div className={cornerCss}>
|
|
97
|
-
<Icon color={themeVars.iconColor} iconSize={18} />
|
|
99
|
+
<Icon color={`var(--actions-menu-item-icon-color, ${themeVars.iconColor})`} iconSize={18} />
|
|
98
100
|
</div>
|
|
99
101
|
) : null;
|
|
100
102
|
};
|
|
@@ -1,59 +1,41 @@
|
|
|
1
|
+
import {composeEventHandlers} from "@fibery/react/src/compose-event-handlers";
|
|
2
|
+
import {createContext} from "@fibery/react/src/create-context";
|
|
3
|
+
import {stopPropagation} from "@fibery/react/src/stop-propagation";
|
|
1
4
|
import {css, cx} from "@linaria/core";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
import React, {RefObject, useEffect, useMemo, useRef, useState} from "react";
|
|
6
|
+
import {
|
|
7
|
+
CommandMenuEmpty,
|
|
8
|
+
CommandMenuGroup,
|
|
9
|
+
CommandMenuInput,
|
|
10
|
+
CommandMenuItem,
|
|
11
|
+
CommandMenuList,
|
|
12
|
+
CommandMenuRoot,
|
|
13
|
+
} from "../command-menu";
|
|
6
14
|
import {ActionsMenuSubMenu} from "./actions-menu-sub-menu";
|
|
7
|
-
import {
|
|
8
|
-
import {useRef, useState} from "react";
|
|
9
|
-
import {stopPropagation} from "@fibery/react/src/stop-propagation";
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* Probably commands menu deserves to be extracted to a separate primitive component not connected to ActionsMenu
|
|
13
|
-
* but for now we don't have other use cases for it so no idea how a primitive should look like
|
|
14
|
-
*
|
|
15
|
-
* Feel free to extract it to a separate one
|
|
16
|
-
*
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const inputContainerCss = css`
|
|
20
|
-
display: flex;
|
|
21
|
-
padding: ${space.s8}px ${space.s12}px;
|
|
22
|
-
align-items: center;
|
|
23
|
-
border-bottom: 1px solid ${themeVars.separatorColor};
|
|
24
|
-
|
|
25
|
-
& input {
|
|
26
|
-
min-width: 120px;
|
|
27
|
-
width: 100%;
|
|
28
|
-
color: ${themeVars.textColor};
|
|
29
|
-
background-color: ${themeVars.transparent};
|
|
30
|
-
margin-left: ${space.s8}px;
|
|
31
|
-
font-size: 13px;
|
|
32
|
-
border: none;
|
|
33
|
-
outline: none;
|
|
34
|
-
resize: none;
|
|
35
|
-
}
|
|
15
|
+
import {useActionsMenuContext} from "./contexts/actions-menu-context";
|
|
36
16
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
17
|
+
const [ActionsMenuSubCommandMenuProvider, useActionsMenuSubCommandMenuCtx] = createContext<{
|
|
18
|
+
subMenuOpenRef: RefObject<boolean>;
|
|
19
|
+
subMenuTriggerRef: RefObject<HTMLDivElement>;
|
|
20
|
+
}>("ActionsMenuSubCommandMenu");
|
|
41
21
|
|
|
42
22
|
type ActionsMenuSubCommandMenuProps = React.PropsWithChildren<{
|
|
43
23
|
trigger?: React.ReactNode;
|
|
44
24
|
disabled?: boolean;
|
|
45
|
-
filter?: React.ComponentPropsWithoutRef<typeof CommandRoot>["filter"];
|
|
46
25
|
}>;
|
|
47
|
-
export const ActionsMenuSubCommandMenu: React.FC<ActionsMenuSubCommandMenuProps> = ({
|
|
48
|
-
disabled,
|
|
49
|
-
trigger,
|
|
50
|
-
filter,
|
|
51
|
-
children,
|
|
52
|
-
}) => {
|
|
26
|
+
export const ActionsMenuSubCommandMenu: React.FC<ActionsMenuSubCommandMenuProps> = ({disabled, trigger, children}) => {
|
|
53
27
|
const [open, onOpenChange] = useState(false);
|
|
54
28
|
const triggerRef = useRef(null);
|
|
55
29
|
const openRef = useRef(false);
|
|
56
30
|
|
|
31
|
+
const ctx = useMemo(
|
|
32
|
+
() => ({
|
|
33
|
+
subMenuOpenRef: openRef,
|
|
34
|
+
subMenuTriggerRef: triggerRef,
|
|
35
|
+
}),
|
|
36
|
+
[]
|
|
37
|
+
);
|
|
38
|
+
|
|
57
39
|
return (
|
|
58
40
|
<ActionsMenuSubMenu
|
|
59
41
|
disabled={disabled}
|
|
@@ -64,126 +46,107 @@ export const ActionsMenuSubCommandMenu: React.FC<ActionsMenuSubCommandMenuProps>
|
|
|
64
46
|
}}
|
|
65
47
|
trigger={trigger}
|
|
66
48
|
triggerRef={triggerRef}
|
|
49
|
+
contentClassName={css`
|
|
50
|
+
&:is(&) {
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
max-height: 400px; // we use fixed height instead of --radix-dropdown-menu-content-available-height because it doesn't restore well after filtering if submenu was opened near the bottom of viewport. https://the.fibery.io/SoftDev/bug/It's-impossible-to-place-cursor-in-search-input-in-Existing-views-and-Convert-to-popup-10357/comment=14877
|
|
55
|
+
}
|
|
56
|
+
`}
|
|
67
57
|
>
|
|
68
|
-
<
|
|
69
|
-
filter={filter}
|
|
70
|
-
onClick={stopPropagation}
|
|
71
|
-
onBlur={(e) => {
|
|
72
|
-
/**
|
|
73
|
-
* Submenu Trigger tries to steal the focus from input on every onPointerMove
|
|
74
|
-
* to avoid this we lock focus on input and do not let it move to back to triger while menu is still open
|
|
75
|
-
*
|
|
76
|
-
* We use openRef here because react state will be updated only on next render
|
|
77
|
-
*/
|
|
78
|
-
if (openRef.current && e.target.hasAttribute("cmdk-input") && e.relatedTarget === triggerRef.current) {
|
|
79
|
-
e.target.focus();
|
|
80
|
-
}
|
|
81
|
-
}}
|
|
82
|
-
>
|
|
83
|
-
{children}
|
|
84
|
-
</CommandRoot>
|
|
58
|
+
<ActionsMenuSubCommandMenuProvider value={ctx}>{children}</ActionsMenuSubCommandMenuProvider>
|
|
85
59
|
</ActionsMenuSubMenu>
|
|
86
60
|
);
|
|
87
61
|
};
|
|
88
62
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
placeholder,
|
|
95
|
-
autoFocus = true,
|
|
63
|
+
export const ActionsMenuSubCommandMenuRoot: React.FC<React.ComponentPropsWithoutRef<typeof CommandMenuRoot>> = ({
|
|
64
|
+
className,
|
|
65
|
+
onClick,
|
|
66
|
+
onBlur,
|
|
67
|
+
...props
|
|
96
68
|
}) => {
|
|
69
|
+
const {subMenuOpenRef, subMenuTriggerRef} = useActionsMenuSubCommandMenuCtx();
|
|
70
|
+
|
|
97
71
|
return (
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if ((e.target as HTMLInputElement).value.length > 0) {
|
|
104
|
-
e.stopPropagation();
|
|
72
|
+
<CommandMenuRoot
|
|
73
|
+
className={cx(
|
|
74
|
+
css`
|
|
75
|
+
&:is(&) {
|
|
76
|
+
width: 250px;
|
|
105
77
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
78
|
+
`,
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
onClick={composeEventHandlers(onClick, stopPropagation)}
|
|
82
|
+
onBlur={composeEventHandlers(onBlur, (e) => {
|
|
83
|
+
/**
|
|
84
|
+
* Submenu Trigger tries to steal the focus from input on every onPointerMove
|
|
85
|
+
* to avoid this we lock focus on input and do not let it move to back to triger while menu is still open
|
|
86
|
+
*
|
|
87
|
+
* setTimeout is needed for firefox https://the.fibery.io/SoftDev/bug/Automatically-place-the-cursor-in-the-search-input-in-the-list-of-spaces-in-'Move-to'-option-10524
|
|
88
|
+
*
|
|
89
|
+
* We use subMenuOpenRef here because react state will be updated only on next render. Alternatively we can try to use flushSync
|
|
90
|
+
*/
|
|
91
|
+
if (
|
|
92
|
+
subMenuOpenRef.current &&
|
|
93
|
+
e.target.hasAttribute("cmdk-input") &&
|
|
94
|
+
e.relatedTarget === subMenuTriggerRef.current
|
|
95
|
+
) {
|
|
96
|
+
setTimeout(() => e.target.focus(), 0);
|
|
97
|
+
}
|
|
98
|
+
})}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
111
101
|
);
|
|
112
102
|
};
|
|
113
103
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
`;
|
|
122
|
-
|
|
123
|
-
const commandItemCss = css`
|
|
124
|
-
display: flex;
|
|
125
|
-
align-items: center;
|
|
126
|
-
gap: ${space.s6}px;
|
|
127
|
-
padding: 0 ${space.s12}px;
|
|
128
|
-
cursor: pointer;
|
|
129
|
-
min-height: ${layout.menuItemHeight}px;
|
|
130
|
-
margin: 0 ${space.s4}px;
|
|
104
|
+
type ActionsMenuSubCommandMenuInputProps = React.ComponentPropsWithoutRef<typeof CommandMenuInput>;
|
|
105
|
+
export const ActionsMenuSubCommandMenuInput: React.FC<ActionsMenuSubCommandMenuInputProps> = ({
|
|
106
|
+
autoFocus = true,
|
|
107
|
+
onKeyDown,
|
|
108
|
+
...otherProps
|
|
109
|
+
}) => {
|
|
110
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
131
111
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const commandItemTitleCss = css`
|
|
139
|
-
white-space: nowrap;
|
|
140
|
-
text-overflow: ellipsis;
|
|
141
|
-
overflow: hidden;
|
|
142
|
-
`;
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
// html autofocus doesn't work reliably in Context Menu
|
|
114
|
+
if (autoFocus) {
|
|
115
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
116
|
+
}
|
|
117
|
+
}, [autoFocus]);
|
|
143
118
|
|
|
144
|
-
|
|
145
|
-
|
|
119
|
+
return (
|
|
120
|
+
<CommandMenuInput
|
|
121
|
+
ref={inputRef}
|
|
122
|
+
onKeyDown={(e) => {
|
|
123
|
+
// prevent submenu from closing if input is not empty
|
|
124
|
+
if ((e.target as HTMLInputElement).value.length > 0 && e.key === "ArrowLeft") {
|
|
125
|
+
e.stopPropagation();
|
|
126
|
+
}
|
|
127
|
+
onKeyDown?.(e);
|
|
128
|
+
}}
|
|
129
|
+
autoFocus={autoFocus}
|
|
130
|
+
{...otherProps}
|
|
131
|
+
/>
|
|
132
|
+
);
|
|
146
133
|
};
|
|
147
134
|
|
|
148
|
-
export const
|
|
135
|
+
export const ActionsMenuSubCommandMenuList = CommandMenuList;
|
|
136
|
+
|
|
137
|
+
export const ActionsMenuSubCommandMenuItem: React.FC<React.ComponentPropsWithoutRef<typeof CommandMenuItem>> = ({
|
|
149
138
|
onSelect,
|
|
150
|
-
icon,
|
|
151
|
-
children,
|
|
152
|
-
className,
|
|
153
139
|
...props
|
|
154
140
|
}) => {
|
|
155
141
|
const {close} = useActionsMenuContext();
|
|
156
|
-
const [showTitle, setShowTitle] = useState(false);
|
|
157
|
-
|
|
158
142
|
const onSelectItem = (value: string) => {
|
|
159
143
|
onSelect?.(value);
|
|
160
144
|
close();
|
|
161
145
|
};
|
|
162
146
|
|
|
163
|
-
return
|
|
164
|
-
<CommandItem className={cx(commandItemCss, className)} onSelect={onSelectItem} {...props}>
|
|
165
|
-
{icon}
|
|
166
|
-
<span
|
|
167
|
-
title={showTitle ? (children as string) : ""}
|
|
168
|
-
onMouseEnter={(e) => {
|
|
169
|
-
const target = e.target as HTMLElement;
|
|
170
|
-
if (typeof children === "string" && target.offsetWidth < target.scrollWidth) {
|
|
171
|
-
setShowTitle(true);
|
|
172
|
-
}
|
|
173
|
-
}}
|
|
174
|
-
className={commandItemTitleCss}
|
|
175
|
-
>
|
|
176
|
-
{children}
|
|
177
|
-
</span>
|
|
178
|
-
</CommandItem>
|
|
179
|
-
);
|
|
147
|
+
return <CommandMenuItem onSelect={onSelectItem} {...props}></CommandMenuItem>;
|
|
180
148
|
};
|
|
181
149
|
|
|
182
|
-
export const ActionsMenuSubCommandMenuEmpty =
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
align-items: center;
|
|
186
|
-
padding: 0 ${space.s12}px;
|
|
187
|
-
min-height: ${layout.itemHeight}px;
|
|
188
|
-
color: ${themeVars.accentTextColor};
|
|
189
|
-
`;
|
|
150
|
+
export const ActionsMenuSubCommandMenuEmpty = CommandMenuEmpty;
|
|
151
|
+
|
|
152
|
+
export const ActionsMenuSubCommandMenuGroup = CommandMenuGroup;
|
|
@@ -22,6 +22,7 @@ type Props = React.PropsWithChildren<{
|
|
|
22
22
|
open?: boolean;
|
|
23
23
|
onOpenChange?: (v: boolean) => void;
|
|
24
24
|
disabled?: boolean;
|
|
25
|
+
contentClassName?: string;
|
|
25
26
|
}>;
|
|
26
27
|
|
|
27
28
|
export const ActionsMenuSubMenu: React.FC<Props> = ({
|
|
@@ -31,6 +32,7 @@ export const ActionsMenuSubMenu: React.FC<Props> = ({
|
|
|
31
32
|
triggerRef,
|
|
32
33
|
children,
|
|
33
34
|
disabled = false,
|
|
35
|
+
contentClassName,
|
|
34
36
|
}) => {
|
|
35
37
|
const {MenuPrimitive} = useActionsMenuContext();
|
|
36
38
|
|
|
@@ -51,7 +53,7 @@ export const ActionsMenuSubMenu: React.FC<Props> = ({
|
|
|
51
53
|
/>
|
|
52
54
|
</div>
|
|
53
55
|
</MenuPrimitive.SubTrigger>
|
|
54
|
-
<MenuPrimitive.SubContent>{children}</MenuPrimitive.SubContent>
|
|
56
|
+
<MenuPrimitive.SubContent className={contentClassName}>{children}</MenuPrimitive.SubContent>
|
|
55
57
|
</MenuPrimitive.Sub>
|
|
56
58
|
);
|
|
57
59
|
};
|
|
@@ -5,6 +5,8 @@ import {ActionsMenuContextProvider} from "./contexts/actions-menu-context";
|
|
|
5
5
|
import {ActionsMenuDangerousRowsProvider} from "./contexts/actions-menu-dangerous-rows";
|
|
6
6
|
import {ActionsMenuProps} from "./actions-menu-props";
|
|
7
7
|
import {preventDefault} from "@fibery/react/src/prevent-default";
|
|
8
|
+
import {useState} from "react";
|
|
9
|
+
import {ActionsMenuConfirmation, ActionsMenuConfirmationProps} from "./actions-menu-confirmation";
|
|
8
10
|
|
|
9
11
|
export const preventDefaultAndStopPropagation = (event: React.MouseEvent) => {
|
|
10
12
|
event.preventDefault();
|
|
@@ -35,9 +37,10 @@ export const ActionsMenu = ({
|
|
|
35
37
|
sticky,
|
|
36
38
|
}: ActionsMenuProps): JSX.Element => {
|
|
37
39
|
const [isOpen = false, setOpen] = useControllableState({value: open, onChange: onOpenChange});
|
|
40
|
+
const [confirmation, setConfirmation] = useState<ActionsMenuConfirmationProps | null>(null);
|
|
38
41
|
|
|
39
42
|
return (
|
|
40
|
-
<ActionsMenuContextProvider setOpen={setOpen} MenuPrimitive={DropdownMenu}>
|
|
43
|
+
<ActionsMenuContextProvider setOpen={setOpen} showConfirmation={setConfirmation} MenuPrimitive={DropdownMenu}>
|
|
41
44
|
<DropdownMenu.Root open={isOpen} onOpenChange={setOpen} modal={modal || false}>
|
|
42
45
|
<DropdownMenu.Trigger
|
|
43
46
|
// backward compatibility for dropdown styles
|
|
@@ -63,6 +66,8 @@ export const ActionsMenu = ({
|
|
|
63
66
|
<ActionsMenuDangerousRowsProvider open={isOpen}>{children}</ActionsMenuDangerousRowsProvider>
|
|
64
67
|
</DropdownMenu.Content>
|
|
65
68
|
</DropdownMenu.Root>
|
|
69
|
+
|
|
70
|
+
{confirmation ? <ActionsMenuConfirmation {...confirmation} /> : null}
|
|
66
71
|
</ActionsMenuContextProvider>
|
|
67
72
|
);
|
|
68
73
|
};
|
|
@@ -5,6 +5,8 @@ import * as ContextMenu from "../context-menu";
|
|
|
5
5
|
import {ActionsMenuDangerousRowsProvider} from "./contexts/actions-menu-dangerous-rows";
|
|
6
6
|
import {ActionsMenuProps} from "./actions-menu-props";
|
|
7
7
|
import {preventDefault} from "@fibery/react/src/prevent-default";
|
|
8
|
+
import {ActionsMenuConfirmation, ActionsMenuConfirmationProps} from "./actions-menu-confirmation";
|
|
9
|
+
import {useState} from "react";
|
|
8
10
|
|
|
9
11
|
export const ContextActionsMenu = ({
|
|
10
12
|
open,
|
|
@@ -15,9 +17,10 @@ export const ContextActionsMenu = ({
|
|
|
15
17
|
autoFocusOnClose = true,
|
|
16
18
|
}: ActionsMenuProps): JSX.Element => {
|
|
17
19
|
const [isOpen = false, setOpen] = useControllableState({value: open, onChange: onOpenChange});
|
|
20
|
+
const [confirmation, setConfirmation] = useState<ActionsMenuConfirmationProps | null>(null);
|
|
18
21
|
|
|
19
22
|
return (
|
|
20
|
-
<ActionsMenuContextProvider setOpen={setOpen} MenuPrimitive={ContextMenu}>
|
|
23
|
+
<ActionsMenuContextProvider setOpen={setOpen} showConfirmation={setConfirmation} MenuPrimitive={ContextMenu}>
|
|
21
24
|
<ContextMenu.Root onOpenChange={onOpenChange}>
|
|
22
25
|
<ContextMenu.Trigger disabled={disabled} asChild>
|
|
23
26
|
{trigger}
|
|
@@ -28,6 +31,7 @@ export const ContextActionsMenu = ({
|
|
|
28
31
|
</ContextMenu.Content>
|
|
29
32
|
</ContextMenu.Portal>
|
|
30
33
|
</ContextMenu.Root>
|
|
34
|
+
{confirmation ? <ActionsMenuConfirmation {...confirmation} /> : null}
|
|
31
35
|
</ActionsMenuContextProvider>
|
|
32
36
|
);
|
|
33
37
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {createContext} from "@fibery/react/src/create-context";
|
|
2
2
|
import {useMemo} from "react";
|
|
3
|
+
import {ActionsMenuConfirmationProps} from "../actions-menu-confirmation";
|
|
3
4
|
|
|
4
5
|
type MenuPrimitive = {
|
|
5
6
|
Item: React.ElementType;
|
|
@@ -13,6 +14,7 @@ type MenuPrimitive = {
|
|
|
13
14
|
|
|
14
15
|
type ActionsMenuContext = {
|
|
15
16
|
close: () => void;
|
|
17
|
+
showConfirmation: (args: ActionsMenuConfirmationProps | null) => void;
|
|
16
18
|
MenuPrimitive: MenuPrimitive;
|
|
17
19
|
};
|
|
18
20
|
|
|
@@ -20,16 +22,18 @@ const [Provider, useContext] = createContext<ActionsMenuContext>("ActionsMenuCon
|
|
|
20
22
|
|
|
21
23
|
type Props = React.PropsWithChildren<{
|
|
22
24
|
setOpen: (value: boolean) => void;
|
|
25
|
+
showConfirmation: (args: ActionsMenuConfirmationProps | null) => void;
|
|
23
26
|
MenuPrimitive: MenuPrimitive;
|
|
24
27
|
}>;
|
|
25
28
|
|
|
26
|
-
export const ActionsMenuContextProvider: React.FC<Props> = ({setOpen, MenuPrimitive, children}) => {
|
|
29
|
+
export const ActionsMenuContextProvider: React.FC<Props> = ({setOpen, showConfirmation, MenuPrimitive, children}) => {
|
|
27
30
|
const context = useMemo<ActionsMenuContext>(
|
|
28
31
|
() => ({
|
|
29
32
|
close: () => setOpen(false),
|
|
30
33
|
MenuPrimitive,
|
|
34
|
+
showConfirmation,
|
|
31
35
|
}),
|
|
32
|
-
[
|
|
36
|
+
[MenuPrimitive, showConfirmation, setOpen]
|
|
33
37
|
);
|
|
34
38
|
|
|
35
39
|
return <Provider value={context}>{children}</Provider>;
|
|
@@ -105,7 +105,7 @@ type StyledProps = {
|
|
|
105
105
|
borderWidth: number;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
-
const StyledButtonBase = styled.button<StyledProps>`
|
|
108
|
+
export const StyledButtonBase = styled.button<StyledProps>`
|
|
109
109
|
display: block;
|
|
110
110
|
box-sizing: border-box;
|
|
111
111
|
font-weight: ${fontWeight.medium};
|
package/src/button/button.tsx
CHANGED