@topconsultnpm/sdkui-react 6.20.0-dev1.11 → 6.20.0-dev1.110
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/lib/assets/Toppy-help-center.png +0 -0
- package/lib/assets/headergradient.svg +87 -0
- package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +285 -28
- package/lib/components/NewComponents/ContextMenu/hooks.d.ts +8 -1
- package/lib/components/NewComponents/ContextMenu/hooks.js +80 -8
- package/lib/components/NewComponents/ContextMenu/index.d.ts +3 -0
- package/lib/components/NewComponents/ContextMenu/index.js +2 -0
- package/lib/components/NewComponents/ContextMenu/styles.d.ts +9 -1
- package/lib/components/NewComponents/ContextMenu/styles.js +157 -37
- package/lib/components/NewComponents/ContextMenu/types.d.ts +14 -1
- package/lib/components/NewComponents/ContextMenu/useLongPress.d.ts +21 -0
- package/lib/components/NewComponents/ContextMenu/useLongPress.js +112 -0
- package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +563 -112
- package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +21 -5
- package/lib/components/NewComponents/FloatingMenuBar/styles.js +210 -58
- package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +8 -2
- package/lib/components/base/TMAccordionNew.js +35 -14
- package/lib/components/base/TMCustomButton.js +61 -17
- package/lib/components/base/TMDataGrid.d.ts +7 -4
- package/lib/components/base/TMDataGrid.js +153 -11
- package/lib/components/base/TMDropDownMenu.js +19 -18
- package/lib/components/base/TMFileManager.d.ts +4 -3
- package/lib/components/base/TMFileManager.js +32 -24
- package/lib/components/base/TMFileManagerDataGridView.d.ts +3 -2
- package/lib/components/base/TMFileManagerDataGridView.js +1 -11
- package/lib/components/base/TMFileManagerThumbnailItems.d.ts +7 -1
- package/lib/components/base/TMFileManagerThumbnailItems.js +5 -2
- package/lib/components/base/TMFileManagerThumbnailsView.d.ts +17 -4
- package/lib/components/base/TMFileManagerThumbnailsView.js +18 -6
- package/lib/components/base/TMFileManagerUtils.d.ts +0 -12
- package/lib/components/base/TMListView.js +33 -15
- package/lib/components/base/TMPanel.d.ts +1 -1
- package/lib/components/base/TMPanel.js +1 -1
- package/lib/components/choosers/TMDistinctValues.js +2 -2
- package/lib/components/choosers/TMInvoiceRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMMetadataChooser.js +8 -1
- package/lib/components/choosers/TMOrderRetrieveFormats.js +1 -1
- package/lib/components/choosers/TMUserChooser.d.ts +0 -5
- package/lib/components/choosers/TMUserChooser.js +25 -45
- package/lib/components/editors/TMDateBox.js +18 -9
- package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
- package/lib/components/editors/TMLocalizedTextBox.js +16 -14
- package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
- package/lib/components/editors/TMMetadataTextBox.js +92 -0
- package/lib/components/editors/TMMetadataValues.js +23 -5
- package/lib/components/editors/TMTextArea.js +18 -30
- package/lib/components/editors/TMTextBox.d.ts +1 -1
- package/lib/components/editors/TMTextBox.js +6 -3
- package/lib/components/editors/TMTextExpression.js +6 -91
- package/lib/components/features/archive/TMArchive.js +2 -2
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.d.ts +15 -0
- package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +460 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.d.ts +11 -0
- package/lib/components/features/assistant/TMToppySpeechBubble.js +126 -0
- package/lib/components/features/documents/TMDcmtForm.d.ts +14 -2
- package/lib/components/features/documents/TMDcmtForm.js +457 -206
- package/lib/components/features/documents/TMDcmtPreview.js +44 -110
- package/lib/components/features/documents/TMDcmtTasks.js +9 -9
- package/lib/components/features/documents/TMMasterDetailDcmts.js +38 -53
- package/lib/components/features/documents/TMRelationViewer.d.ts +1 -1
- package/lib/components/features/documents/TMRelationViewer.js +2 -2
- package/lib/components/features/search/TMDcmtCheckoutInfoForm.d.ts +8 -0
- package/lib/components/features/search/{TMSearchResultCheckoutInfoForm.js → TMDcmtCheckoutInfoForm.js} +2 -2
- package/lib/components/features/search/TMSavedQuerySelector.js +72 -67
- package/lib/components/features/search/TMSearch.d.ts +3 -0
- package/lib/components/features/search/TMSearch.js +50 -11
- package/lib/components/features/search/TMSearchQueryPanel.d.ts +1 -0
- package/lib/components/features/search/TMSearchQueryPanel.js +29 -21
- package/lib/components/features/search/TMSearchResult.d.ts +3 -0
- package/lib/components/features/search/TMSearchResult.js +208 -250
- package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +3 -3
- package/lib/components/features/search/TMSearchResultsMenuItems.js +205 -169
- package/lib/components/features/search/TMSignSettingsForm.js +1 -1
- package/lib/components/features/search/TMSignatureInfoContent.d.ts +6 -0
- package/lib/components/features/search/TMSignatureInfoContent.js +140 -0
- package/lib/components/features/search/TMViewHistoryDcmt.js +2 -2
- package/lib/components/features/tasks/TMTaskForm.js +20 -1
- package/lib/components/features/tasks/TMTasksAgenda.d.ts +3 -1
- package/lib/components/features/tasks/TMTasksAgenda.js +48 -9
- package/lib/components/features/tasks/TMTasksCalendar.d.ts +2 -0
- package/lib/components/features/tasks/TMTasksCalendar.js +19 -7
- package/lib/components/features/tasks/TMTasksUtils.d.ts +2 -2
- package/lib/components/features/tasks/TMTasksUtils.js +43 -36
- package/lib/components/features/tasks/TMTasksView.js +28 -19
- package/lib/components/features/workflow/TMWorkflowPopup.d.ts +33 -2
- package/lib/components/features/workflow/TMWorkflowPopup.js +139 -34
- package/lib/components/features/workflow/diagram/DiagramItemComponent.d.ts +2 -0
- package/lib/components/features/workflow/diagram/DiagramItemComponent.js +12 -7
- package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
- package/lib/components/features/workflow/diagram/RecipientList.js +3 -2
- package/lib/components/features/workflow/diagram/WFDiagram.d.ts +4 -0
- package/lib/components/features/workflow/diagram/WFDiagram.js +164 -13
- package/lib/components/forms/Login/LoginValidatorService.d.ts +2 -0
- package/lib/components/forms/Login/LoginValidatorService.js +7 -2
- package/lib/components/forms/Login/TMLoginForm.js +34 -6
- package/lib/components/forms/TMChooserForm.js +1 -1
- package/lib/components/grids/TMBlogsPost.js +56 -31
- package/lib/components/grids/TMRecentsManager.js +20 -10
- package/lib/components/index.d.ts +6 -3
- package/lib/components/index.js +6 -3
- package/lib/components/query/TMQueryEditor.d.ts +2 -1
- package/lib/components/query/TMQueryEditor.js +92 -92
- package/lib/components/settings/SettingsAppearance.d.ts +2 -1
- package/lib/components/settings/SettingsAppearance.js +99 -30
- package/lib/components/sidebar/TMHeader.js +7 -7
- package/lib/components/sidebar/TMSidebar.d.ts +0 -1
- package/lib/components/sidebar/TMSidebar.js +16 -44
- package/lib/components/sidebar/TMSidebarItem.js +34 -17
- package/lib/components/viewers/TMDataListItemViewer.d.ts +2 -1
- package/lib/components/viewers/TMDataListItemViewer.js +35 -71
- package/lib/components/viewers/TMDataUserIdItemViewer.d.ts +8 -0
- package/lib/components/viewers/TMDataUserIdItemViewer.js +39 -0
- package/lib/css/tm-sdkui.css +1 -1
- package/lib/helper/SDKUI_Globals.d.ts +22 -0
- package/lib/helper/SDKUI_Globals.js +10 -1
- package/lib/helper/SDKUI_Localizator.d.ts +17 -1
- package/lib/helper/SDKUI_Localizator.js +167 -1
- package/lib/helper/TMCommandsContextMenu.d.ts +4 -2
- package/lib/helper/TMCommandsContextMenu.js +15 -4
- package/lib/helper/TMIcons.d.ts +4 -0
- package/lib/helper/TMIcons.js +13 -3
- package/lib/helper/TMPdfViewer.d.ts +8 -0
- package/lib/helper/TMPdfViewer.js +373 -0
- package/lib/helper/checkinCheckoutManager.d.ts +31 -1
- package/lib/helper/checkinCheckoutManager.js +112 -30
- package/lib/helper/devextremeCustomMessages.d.ts +30 -0
- package/lib/helper/devextremeCustomMessages.js +30 -0
- package/lib/helper/helpers.d.ts +28 -1
- package/lib/helper/helpers.js +130 -3
- package/lib/helper/index.d.ts +2 -0
- package/lib/helper/index.js +2 -0
- package/lib/helper/queryHelper.d.ts +1 -1
- package/lib/helper/queryHelper.js +33 -3
- package/lib/helper/workItemsHelper.d.ts +6 -0
- package/lib/helper/workItemsHelper.js +230 -0
- package/lib/hooks/useCheckInOutOperations.d.ts +28 -0
- package/lib/hooks/useCheckInOutOperations.js +223 -0
- package/lib/hooks/useDataListItem.d.ts +12 -0
- package/lib/hooks/useDataListItem.js +132 -0
- package/lib/hooks/useDataUserIdItem.d.ts +10 -0
- package/lib/hooks/useDataUserIdItem.js +96 -0
- package/lib/hooks/useMetadataExpression.d.ts +19 -0
- package/lib/hooks/useMetadataExpression.js +99 -0
- package/lib/hooks/useSettingsFeedback.d.ts +11 -0
- package/lib/hooks/useSettingsFeedback.js +38 -0
- package/lib/hooks/useWorkflowApprove.d.ts +4 -0
- package/lib/hooks/useWorkflowApprove.js +14 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -2
- package/lib/services/platform_services.d.ts +3 -3
- package/lib/ts/types.d.ts +61 -1
- package/lib/utils/theme.d.ts +1 -1
- package/lib/utils/theme.js +1 -1
- package/package.json +7 -4
- package/lib/components/NewComponents/Notification/Notification.d.ts +0 -4
- package/lib/components/NewComponents/Notification/Notification.js +0 -60
- package/lib/components/NewComponents/Notification/NotificationContainer.d.ts +0 -8
- package/lib/components/NewComponents/Notification/NotificationContainer.js +0 -33
- package/lib/components/NewComponents/Notification/index.d.ts +0 -2
- package/lib/components/NewComponents/Notification/index.js +0 -2
- package/lib/components/NewComponents/Notification/styles.d.ts +0 -21
- package/lib/components/NewComponents/Notification/styles.js +0 -180
- package/lib/components/NewComponents/Notification/types.d.ts +0 -18
- package/lib/components/NewComponents/Notification/types.js +0 -1
- package/lib/components/base/TMContextMenu.d.ts +0 -25
- package/lib/components/base/TMContextMenu.js +0 -109
- package/lib/components/base/TMContextMenuOLD.d.ts +0 -26
- package/lib/components/base/TMContextMenuOLD.js +0 -56
- package/lib/components/base/TMFloatingToolbar.d.ts +0 -9
- package/lib/components/base/TMFloatingToolbar.js +0 -101
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.d.ts +0 -30
- package/lib/components/features/assistant/ToppyDraggableHelpCenter.js +0 -482
- package/lib/components/features/assistant/ToppySpeechBubble.d.ts +0 -9
- package/lib/components/features/assistant/ToppySpeechBubble.js +0 -117
- package/lib/components/features/search/TMSearchResultCheckoutInfoForm.d.ts +0 -8
|
@@ -3,6 +3,10 @@ export declare const MenuContainer: import("styled-components/dist/types").IStyl
|
|
|
3
3
|
$y: number;
|
|
4
4
|
$openLeft: boolean;
|
|
5
5
|
$openUp: boolean;
|
|
6
|
+
$isPositioned: boolean;
|
|
7
|
+
$externalControl?: boolean;
|
|
8
|
+
$needsScroll?: boolean;
|
|
9
|
+
$maxHeight?: number;
|
|
6
10
|
}>> & string;
|
|
7
11
|
export declare const MenuItem: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
8
12
|
$disabled?: boolean;
|
|
@@ -12,13 +16,17 @@ export declare const MenuItem: import("styled-components/dist/types").IStyledCom
|
|
|
12
16
|
export declare const MenuItemContent: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
13
17
|
export declare const IconWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
14
18
|
export declare const MenuItemName: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>> & string;
|
|
15
|
-
export declare const RightIconButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>,
|
|
19
|
+
export declare const RightIconButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
20
|
+
ref?: ((instance: HTMLButtonElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLButtonElement> | null | undefined;
|
|
21
|
+
}>, never>, never>> & string;
|
|
16
22
|
export declare const SubmenuIndicator: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {
|
|
17
23
|
$isMobile?: boolean;
|
|
18
24
|
}>> & string;
|
|
19
25
|
export declare const Submenu: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
|
|
20
26
|
$parentRect: DOMRect;
|
|
21
27
|
$openUp?: boolean;
|
|
28
|
+
$needsScroll?: boolean;
|
|
29
|
+
$maxHeight?: number;
|
|
22
30
|
}>> & string;
|
|
23
31
|
export declare const MobileMenuHeader: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
|
|
24
32
|
export declare const BackButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, never>> & string;
|
|
@@ -25,7 +25,7 @@ export const MenuContainer = styled.div `
|
|
|
25
25
|
right: ${props => props.$openLeft ? `${window.innerWidth - props.$x}px` : 'auto'};
|
|
26
26
|
top: ${props => props.$openUp ? 'auto' : `${props.$y}px`};
|
|
27
27
|
bottom: ${props => props.$openUp ? `${window.innerHeight - props.$y}px` : 'auto'};
|
|
28
|
-
z-index:
|
|
28
|
+
z-index: 10100;
|
|
29
29
|
background: #ffffff;
|
|
30
30
|
border-radius: 12px;
|
|
31
31
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12),
|
|
@@ -36,6 +36,42 @@ export const MenuContainer = styled.div `
|
|
|
36
36
|
animation: ${fadeIn} 0.15s ease-out;
|
|
37
37
|
backdrop-filter: blur(10px);
|
|
38
38
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
39
|
+
opacity: ${props => props.$isPositioned ? 1 : 0};
|
|
40
|
+
transition: opacity 0.05s ease-in;
|
|
41
|
+
|
|
42
|
+
/* Add scrolling when menu is too tall to fit in either direction */
|
|
43
|
+
${props => props.$needsScroll && props.$maxHeight && `
|
|
44
|
+
max-height: ${props.$maxHeight}px;
|
|
45
|
+
overflow-y: auto;
|
|
46
|
+
overflow-x: hidden;
|
|
47
|
+
|
|
48
|
+
/* Smooth scrolling */
|
|
49
|
+
scroll-behavior: smooth;
|
|
50
|
+
|
|
51
|
+
/* Custom scrollbar styling */
|
|
52
|
+
&::-webkit-scrollbar {
|
|
53
|
+
width: 8px;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&::-webkit-scrollbar-track {
|
|
57
|
+
background: rgba(0, 0, 0, 0.05);
|
|
58
|
+
border-radius: 4px;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&::-webkit-scrollbar-thumb {
|
|
62
|
+
background: rgba(0, 0, 0, 0.2);
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
67
|
+
background: rgba(0, 0, 0, 0.3);
|
|
68
|
+
}
|
|
69
|
+
`}
|
|
70
|
+
|
|
71
|
+
/* Reset color inheritance from parent with !important to override panel header styles */
|
|
72
|
+
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
73
|
+
color: #1a1a1a !important;
|
|
74
|
+
}
|
|
39
75
|
|
|
40
76
|
[data-theme='dark'] & {
|
|
41
77
|
background: #2a2a2a;
|
|
@@ -43,18 +79,31 @@ export const MenuContainer = styled.div `
|
|
|
43
79
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4),
|
|
44
80
|
0 2px 8px rgba(0, 0, 0, 0.3);
|
|
45
81
|
}
|
|
82
|
+
|
|
83
|
+
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
84
|
+
color: #e0e0e0 !important;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
${props => props.$externalControl && `
|
|
88
|
+
@media (max-width: 768px) {
|
|
89
|
+
left: 75px !important;
|
|
90
|
+
right: 75px !important;
|
|
91
|
+
max-width: calc(100vw - 150px);
|
|
92
|
+
width: auto;
|
|
93
|
+
min-width: auto;
|
|
94
|
+
}
|
|
95
|
+
`}
|
|
46
96
|
`;
|
|
47
97
|
export const MenuItem = styled.div `
|
|
48
98
|
display: flex;
|
|
49
99
|
align-items: center;
|
|
50
100
|
justify-content: space-between;
|
|
51
101
|
padding: 4px 12px;
|
|
52
|
-
cursor: ${props => props.$disabled ? '
|
|
53
|
-
opacity: ${props => props.$disabled ? 0.4 : 1};
|
|
102
|
+
cursor: ${props => props.$disabled ? 'default' : 'pointer'};
|
|
54
103
|
transition: all 0.15s ease;
|
|
55
104
|
position: relative;
|
|
56
105
|
user-select: none;
|
|
57
|
-
font-size: 13px;
|
|
106
|
+
font-size: var(--base-font-size, 13px);
|
|
58
107
|
color: ${props => props.$disabled ? '#999' : '#1a1a1a'};
|
|
59
108
|
font-weight: 500;
|
|
60
109
|
${props => props.$beginGroup && `
|
|
@@ -63,12 +112,26 @@ export const MenuItem = styled.div `
|
|
|
63
112
|
padding-top: 8px;
|
|
64
113
|
`}
|
|
65
114
|
|
|
115
|
+
/* Apply opacity only to direct children except right-icon-btn */
|
|
116
|
+
& > *:not(.right-icon-btn) {
|
|
117
|
+
opacity: ${props => props.$disabled ? 0.4 : 1};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Right icon button hidden by default, shown on hover */
|
|
121
|
+
& .right-icon-btn {
|
|
122
|
+
cursor: pointer !important;
|
|
123
|
+
}
|
|
124
|
+
|
|
66
125
|
&:hover {
|
|
67
126
|
${props => !props.$disabled && `
|
|
68
127
|
background: linear-gradient(90deg, #f0f7ff 0%, #e6f2ff 100%);
|
|
69
128
|
color: #0066cc;
|
|
70
|
-
padding-left: 14px;
|
|
71
129
|
`}
|
|
130
|
+
|
|
131
|
+
/* Show right icon on hover */
|
|
132
|
+
& .right-icon-btn {
|
|
133
|
+
opacity: 1 !important;
|
|
134
|
+
}
|
|
72
135
|
}
|
|
73
136
|
|
|
74
137
|
&:active {
|
|
@@ -99,8 +162,8 @@ export const MenuItem = styled.div `
|
|
|
99
162
|
}
|
|
100
163
|
|
|
101
164
|
@media (max-width: 768px) {
|
|
102
|
-
padding:
|
|
103
|
-
font-size:
|
|
165
|
+
padding: 4px 10px;
|
|
166
|
+
font-size: calc(var(--base-font-size, 13px) * 0.92);
|
|
104
167
|
}
|
|
105
168
|
`;
|
|
106
169
|
export const MenuItemContent = styled.div `
|
|
@@ -113,7 +176,7 @@ export const IconWrapper = styled.span `
|
|
|
113
176
|
display: flex;
|
|
114
177
|
align-items: center;
|
|
115
178
|
justify-content: center;
|
|
116
|
-
font-size:
|
|
179
|
+
font-size: calc(var(--base-font-size, 13px) * 1.08);
|
|
117
180
|
width: 18px;
|
|
118
181
|
height: 18px;
|
|
119
182
|
`;
|
|
@@ -124,23 +187,23 @@ export const MenuItemName = styled.span `
|
|
|
124
187
|
overflow-wrap: break-word;
|
|
125
188
|
line-height: 1.4;
|
|
126
189
|
`;
|
|
127
|
-
export const RightIconButton = styled.button
|
|
190
|
+
export const RightIconButton = styled.button.attrs({
|
|
191
|
+
className: 'right-icon-btn'
|
|
192
|
+
}) `
|
|
128
193
|
display: flex;
|
|
129
194
|
align-items: center;
|
|
130
195
|
justify-content: center;
|
|
131
196
|
background: transparent;
|
|
132
197
|
border: none;
|
|
133
|
-
cursor: pointer;
|
|
198
|
+
cursor: pointer !important;
|
|
134
199
|
padding: 4px 8px;
|
|
135
200
|
margin-left: 8px;
|
|
136
201
|
border-radius: 6px;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
transition: all 0.15s ease;
|
|
202
|
+
font-size: calc(var(--base-font-size, 13px) * 1.08);
|
|
203
|
+
opacity: 0 !important;
|
|
204
|
+
transition: opacity 0.15s ease, background 0.15s ease, transform 0.15s ease;
|
|
141
205
|
|
|
142
206
|
&:hover {
|
|
143
|
-
opacity: 1;
|
|
144
207
|
background: rgba(0, 0, 0, 0.05);
|
|
145
208
|
transform: scale(1.1);
|
|
146
209
|
}
|
|
@@ -158,12 +221,12 @@ export const RightIconButton = styled.button `
|
|
|
158
221
|
export const SubmenuIndicator = styled.span `
|
|
159
222
|
display: flex;
|
|
160
223
|
align-items: center;
|
|
161
|
-
font-size:
|
|
224
|
+
font-size: calc(var(--base-font-size, 13px) * 0.92);
|
|
162
225
|
margin-left: 8px;
|
|
163
226
|
opacity: 0.6;
|
|
164
227
|
transition: transform 0.15s ease;
|
|
165
228
|
|
|
166
|
-
${MenuItem}:hover & {
|
|
229
|
+
${MenuItem}:hover:not([data-disabled="true"]) & {
|
|
167
230
|
${props => !props.$isMobile && `
|
|
168
231
|
transform: translateX(2px);
|
|
169
232
|
opacity: 1;
|
|
@@ -189,7 +252,7 @@ export const Submenu = styled.div `
|
|
|
189
252
|
// If openUp is true, anchor to bottom and grow upward
|
|
190
253
|
return props.$openUp ? `${globalThis.innerHeight - props.$parentRect.bottom - 8}px` : 'auto';
|
|
191
254
|
}};
|
|
192
|
-
z-index:
|
|
255
|
+
z-index: 10101;
|
|
193
256
|
background: #ffffff;
|
|
194
257
|
border-radius: 12px;
|
|
195
258
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12),
|
|
@@ -223,17 +286,89 @@ export const Submenu = styled.div `
|
|
|
223
286
|
background: transparent;
|
|
224
287
|
}
|
|
225
288
|
|
|
289
|
+
/* Reset color inheritance from parent with !important to override panel header styles */
|
|
290
|
+
& *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
291
|
+
color: #1a1a1a !important;
|
|
292
|
+
}
|
|
293
|
+
|
|
226
294
|
[data-theme='dark'] & {
|
|
227
295
|
background: #2a2a2a;
|
|
228
296
|
border-color: rgba(255, 255, 255, 0.1);
|
|
229
297
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4),
|
|
230
298
|
0 2px 8px rgba(0, 0, 0, 0.3);
|
|
231
299
|
}
|
|
300
|
+
|
|
301
|
+
[data-theme='dark'] & *:not(svg):not(.right-icon-btn):not(.right-icon-btn *) {
|
|
302
|
+
color: #e0e0e0 !important;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* Dynamic scroll handling when submenu is too tall */
|
|
306
|
+
${props => props.$needsScroll && props.$maxHeight ? `
|
|
307
|
+
max-height: ${props.$maxHeight}px;
|
|
308
|
+
overflow-y: auto;
|
|
309
|
+
overflow-x: hidden;
|
|
310
|
+
|
|
311
|
+
/* Custom scrollbar styling for submenus */
|
|
312
|
+
&::-webkit-scrollbar {
|
|
313
|
+
width: 8px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
&::-webkit-scrollbar-track {
|
|
317
|
+
background: rgba(0, 0, 0, 0.05);
|
|
318
|
+
border-radius: 4px;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
&::-webkit-scrollbar-thumb {
|
|
322
|
+
background: rgba(0, 0, 0, 0.2);
|
|
323
|
+
border-radius: 4px;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
327
|
+
background: rgba(0, 0, 0, 0.3);
|
|
328
|
+
}
|
|
329
|
+
` : `
|
|
330
|
+
/* Fallback max-height for submenus that fit */
|
|
331
|
+
max-height: calc(100vh - 40px);
|
|
332
|
+
overflow-y: auto;
|
|
333
|
+
overflow-x: hidden;
|
|
334
|
+
|
|
335
|
+
&::-webkit-scrollbar {
|
|
336
|
+
width: 8px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
&::-webkit-scrollbar-track {
|
|
340
|
+
background: rgba(0, 0, 0, 0.05);
|
|
341
|
+
border-radius: 4px;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
&::-webkit-scrollbar-thumb {
|
|
345
|
+
background: rgba(0, 0, 0, 0.2);
|
|
346
|
+
border-radius: 4px;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
350
|
+
background: rgba(0, 0, 0, 0.3);
|
|
351
|
+
}
|
|
352
|
+
`}
|
|
353
|
+
|
|
354
|
+
[data-theme='dark'] & {
|
|
355
|
+
&::-webkit-scrollbar-track {
|
|
356
|
+
background: rgba(255, 255, 255, 0.05);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
&::-webkit-scrollbar-thumb {
|
|
360
|
+
background: rgba(255, 255, 255, 0.2);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
364
|
+
background: rgba(255, 255, 255, 0.3);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
232
367
|
`;
|
|
233
368
|
export const MobileMenuHeader = styled.div `
|
|
234
369
|
display: flex;
|
|
235
370
|
align-items: center;
|
|
236
|
-
padding:
|
|
371
|
+
padding: 4px 8px;
|
|
237
372
|
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
238
373
|
margin-bottom: 8px;
|
|
239
374
|
gap: 12px;
|
|
@@ -249,37 +384,22 @@ export const BackButton = styled.button `
|
|
|
249
384
|
display: flex;
|
|
250
385
|
align-items: center;
|
|
251
386
|
justify-content: center;
|
|
252
|
-
background: #0066cc;
|
|
253
|
-
color: white;
|
|
254
387
|
border: none;
|
|
255
388
|
border-radius: 8px;
|
|
256
389
|
width: 32px;
|
|
257
390
|
height: 32px;
|
|
258
391
|
cursor: pointer;
|
|
259
|
-
font-size: 18px;
|
|
260
392
|
transition: all 0.15s ease;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
background: #0052a3;
|
|
264
|
-
transform: scale(1.05);
|
|
265
|
-
}
|
|
393
|
+
font-size: 16px;
|
|
394
|
+
transform: translateY(-2px);
|
|
266
395
|
|
|
267
396
|
&:active {
|
|
268
397
|
transform: scale(0.95);
|
|
269
398
|
}
|
|
270
|
-
|
|
271
|
-
[data-theme='dark'] & {
|
|
272
|
-
background: #4db8ff;
|
|
273
|
-
color: #1a1a1a;
|
|
274
|
-
|
|
275
|
-
&:hover {
|
|
276
|
-
background: #66c2ff;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
399
|
`;
|
|
280
400
|
export const HeaderTitle = styled.h3 `
|
|
281
401
|
margin: 0;
|
|
282
|
-
font-size:
|
|
402
|
+
font-size: calc(var(--base-font-size, 13px) * 1.23);
|
|
283
403
|
font-weight: 600;
|
|
284
404
|
color: #1a1a1a;
|
|
285
405
|
flex: 1;
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
export interface TMContextMenuItemProps {
|
|
2
|
+
id?: string;
|
|
2
3
|
name: string;
|
|
3
4
|
icon?: React.ReactNode;
|
|
4
5
|
disabled?: boolean;
|
|
5
|
-
onClick?: () => void;
|
|
6
|
+
onClick?: (data?: any) => void;
|
|
6
7
|
submenu?: TMContextMenuItemProps[];
|
|
7
8
|
visible?: boolean;
|
|
8
9
|
rightIcon?: React.ReactNode;
|
|
9
10
|
onRightIconClick?: () => void;
|
|
10
11
|
beginGroup?: boolean;
|
|
12
|
+
tooltip?: string;
|
|
13
|
+
operationType?: 'singleRow' | 'multiRow';
|
|
11
14
|
}
|
|
12
15
|
export interface TMContextMenuProps {
|
|
13
16
|
items: TMContextMenuItemProps[];
|
|
14
17
|
trigger?: 'right' | 'left';
|
|
15
18
|
children?: React.ReactNode;
|
|
19
|
+
target?: string;
|
|
20
|
+
externalControl?: {
|
|
21
|
+
visible: boolean;
|
|
22
|
+
position: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
};
|
|
26
|
+
onClose: () => void;
|
|
27
|
+
};
|
|
28
|
+
keepOpenOnClick?: boolean;
|
|
16
29
|
}
|
|
17
30
|
export interface Position {
|
|
18
31
|
x: number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface UseLongPressOptions {
|
|
2
|
+
containerRef: React.RefObject<HTMLElement>;
|
|
3
|
+
targetSelector: string | string[];
|
|
4
|
+
onLongPress: (event: {
|
|
5
|
+
clientX: number;
|
|
6
|
+
clientY: number;
|
|
7
|
+
target: HTMLElement;
|
|
8
|
+
}) => void;
|
|
9
|
+
onTouchStart?: (event: {
|
|
10
|
+
clientX: number;
|
|
11
|
+
clientY: number;
|
|
12
|
+
target: HTMLElement;
|
|
13
|
+
rowElement: HTMLElement;
|
|
14
|
+
}) => void;
|
|
15
|
+
duration?: number;
|
|
16
|
+
moveThreshold?: number;
|
|
17
|
+
hapticFeedback?: boolean;
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare function useLongPress({ containerRef, targetSelector, onLongPress, onTouchStart, duration, moveThreshold, hapticFeedback, enabled, }: UseLongPressOptions): void;
|
|
21
|
+
export declare function triggerContextMenuEvent(target: HTMLElement, clientX: number, clientY: number): void;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import { useIsIOS } from './hooks';
|
|
3
|
+
export function useLongPress({ containerRef, targetSelector, onLongPress, onTouchStart, duration = 500, moveThreshold = 10, hapticFeedback = true, enabled = true, }) {
|
|
4
|
+
const isIOS = useIsIOS();
|
|
5
|
+
const longPressTriggeredRef = useRef(false);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isIOS || !enabled || !containerRef.current)
|
|
8
|
+
return;
|
|
9
|
+
const container = containerRef.current;
|
|
10
|
+
let longPressTimeout = null;
|
|
11
|
+
let touchStartPos = null;
|
|
12
|
+
let longPressTarget = null;
|
|
13
|
+
const matchesSelector = (element) => {
|
|
14
|
+
const selectors = Array.isArray(targetSelector) ? targetSelector : [targetSelector];
|
|
15
|
+
for (const selector of selectors) {
|
|
16
|
+
const match = element.closest(selector);
|
|
17
|
+
if (match)
|
|
18
|
+
return match;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
22
|
+
const handleTouchStart = (e) => {
|
|
23
|
+
const touch = e.touches[0];
|
|
24
|
+
const target = touch.target;
|
|
25
|
+
// Check if target matches any of the specified selectors
|
|
26
|
+
const matchedElement = matchesSelector(target);
|
|
27
|
+
if (!matchedElement)
|
|
28
|
+
return;
|
|
29
|
+
touchStartPos = { x: touch.clientX, y: touch.clientY };
|
|
30
|
+
longPressTriggeredRef.current = false;
|
|
31
|
+
longPressTarget = target;
|
|
32
|
+
// Call optional onTouchStart callback
|
|
33
|
+
if (onTouchStart) {
|
|
34
|
+
onTouchStart({
|
|
35
|
+
clientX: touch.clientX,
|
|
36
|
+
clientY: touch.clientY,
|
|
37
|
+
target,
|
|
38
|
+
rowElement: matchedElement,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (longPressTimeout)
|
|
42
|
+
clearTimeout(longPressTimeout);
|
|
43
|
+
longPressTimeout = setTimeout(() => {
|
|
44
|
+
longPressTriggeredRef.current = true;
|
|
45
|
+
// Haptic feedback
|
|
46
|
+
if (hapticFeedback && 'vibrate' in navigator) {
|
|
47
|
+
navigator.vibrate(50);
|
|
48
|
+
}
|
|
49
|
+
// Call onLongPress callback
|
|
50
|
+
onLongPress({
|
|
51
|
+
clientX: touch.clientX,
|
|
52
|
+
clientY: touch.clientY,
|
|
53
|
+
target: longPressTarget,
|
|
54
|
+
});
|
|
55
|
+
longPressTimeout = null;
|
|
56
|
+
}, duration);
|
|
57
|
+
};
|
|
58
|
+
const handleTouchMove = (e) => {
|
|
59
|
+
if (!touchStartPos || !longPressTimeout)
|
|
60
|
+
return;
|
|
61
|
+
const touch = e.touches[0];
|
|
62
|
+
const dx = Math.abs(touch.clientX - touchStartPos.x);
|
|
63
|
+
const dy = Math.abs(touch.clientY - touchStartPos.y);
|
|
64
|
+
// Cancel long-press if finger moved too much
|
|
65
|
+
if (dx > moveThreshold || dy > moveThreshold) {
|
|
66
|
+
clearTimeout(longPressTimeout);
|
|
67
|
+
longPressTimeout = null;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const handleTouchEnd = () => {
|
|
71
|
+
if (longPressTimeout) {
|
|
72
|
+
clearTimeout(longPressTimeout);
|
|
73
|
+
longPressTimeout = null;
|
|
74
|
+
}
|
|
75
|
+
touchStartPos = null;
|
|
76
|
+
longPressTarget = null;
|
|
77
|
+
};
|
|
78
|
+
// Prevent click after long-press to avoid unintended actions
|
|
79
|
+
const handleClick = (e) => {
|
|
80
|
+
if (longPressTriggeredRef.current) {
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
e.stopImmediatePropagation();
|
|
84
|
+
longPressTriggeredRef.current = false;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
container.addEventListener('touchstart', handleTouchStart, { passive: true });
|
|
88
|
+
container.addEventListener('touchmove', handleTouchMove, { passive: true });
|
|
89
|
+
container.addEventListener('touchend', handleTouchEnd);
|
|
90
|
+
container.addEventListener('touchcancel', handleTouchEnd);
|
|
91
|
+
container.addEventListener('click', handleClick, { capture: true });
|
|
92
|
+
return () => {
|
|
93
|
+
if (longPressTimeout)
|
|
94
|
+
clearTimeout(longPressTimeout);
|
|
95
|
+
container.removeEventListener('touchstart', handleTouchStart);
|
|
96
|
+
container.removeEventListener('touchmove', handleTouchMove);
|
|
97
|
+
container.removeEventListener('touchend', handleTouchEnd);
|
|
98
|
+
container.removeEventListener('touchcancel', handleTouchEnd);
|
|
99
|
+
container.removeEventListener('click', handleClick, { capture: true });
|
|
100
|
+
};
|
|
101
|
+
}, [isIOS, enabled, containerRef, targetSelector, onLongPress, onTouchStart, duration, moveThreshold, hapticFeedback]);
|
|
102
|
+
}
|
|
103
|
+
export function triggerContextMenuEvent(target, clientX, clientY) {
|
|
104
|
+
const contextMenuEvent = new MouseEvent('contextmenu', {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
cancelable: true,
|
|
107
|
+
clientX,
|
|
108
|
+
clientY,
|
|
109
|
+
button: 2,
|
|
110
|
+
});
|
|
111
|
+
target.dispatchEvent(contextMenuEvent);
|
|
112
|
+
}
|