@trtc/calls-uikit-react 4.4.2 → 4.4.3-beta.2
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/README-zh_CN.md +6 -0
- package/README.md +6 -0
- package/package.json +3 -4
- package/src/TUICallService/CallService/UIKitModal.ts +0 -5
- package/src/TUICallService/CallService/index.ts +1 -1
- package/src/TUICallService/locales/en.ts +1 -2
- package/src/TUICallService/locales/ja_JP.ts +1 -2
- package/src/TUICallService/locales/zh-cn.ts +1 -2
- package/src/TUICallService/utils/validate/validateStatus.ts +26 -0
- package/src/index.ts +1 -1
- package/tuicall-uikit-react.es.js +655 -663
- package/tuicall-uikit-react.umd.js +9 -9
- package/types/TUICallService/locales/en.d.ts +0 -1
- package/types/TUICallService/locales/ja_JP.d.ts +0 -1
- package/types/TUICallService/locales/zh-cn.d.ts +0 -1
- package/types/TUICallService/utils/validate/validateStatus.d.ts +5 -0
- package/src/Components/components/common/UIKitModal/UIKitModal.tsx +0 -250
- package/src/Components/components/common/UIKitModal/UIKitModalState.ts +0 -177
- package/src/Components/components/common/UIKitModal/index.module.scss +0 -176
- package/src/Components/components/common/UIKitModal/index.ts +0 -3
- package/types/Components/components/common/UIKitModal/UIKitModal.d.ts +0 -21
- package/types/Components/components/common/UIKitModal/UIKitModalState.d.ts +0 -27
- package/types/Components/components/common/UIKitModal/index.d.ts +0 -3
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
|
-
import { createPortal } from 'react-dom';
|
|
3
|
-
import ReactDOM from 'react-dom/client';
|
|
4
|
-
import type { ReactNode } from 'react';
|
|
5
|
-
import { uikitModalState } from './UIKitModalState';
|
|
6
|
-
import { IS_PC } from '../../../../TUICallService/utils/env';
|
|
7
|
-
import { t } from '../../../../TUICallService';
|
|
8
|
-
import styles from './index.module.scss';
|
|
9
|
-
|
|
10
|
-
// Types
|
|
11
|
-
export interface UIKitModalConfig {
|
|
12
|
-
id: number;
|
|
13
|
-
title: string;
|
|
14
|
-
content: string | ReactNode;
|
|
15
|
-
type: 'info' | 'warning' | 'error' | 'success';
|
|
16
|
-
onConfirm?: () => void;
|
|
17
|
-
onCancel?: () => void;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type UIKitModalOptions = UIKitModalConfig;
|
|
21
|
-
|
|
22
|
-
// Constants
|
|
23
|
-
let root: ReactDOM.Root | null = null;
|
|
24
|
-
let container: HTMLDivElement | null = null;
|
|
25
|
-
let resolvePromise: ((value: { action: string }) => void) | null = null;
|
|
26
|
-
|
|
27
|
-
const URL_REGEX = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/i;
|
|
28
|
-
const FULL_URL_REGEX = /(https?:\/\/[^\s]+)/g;
|
|
29
|
-
|
|
30
|
-
function escapeHtml(text: string): string {
|
|
31
|
-
const div = document.createElement('div');
|
|
32
|
-
div.textContent = text;
|
|
33
|
-
return div.innerHTML;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function processAnchorTags(content: string): string {
|
|
37
|
-
const parser = new DOMParser();
|
|
38
|
-
const doc = parser.parseFromString(content, 'text/html');
|
|
39
|
-
const anchors = doc.querySelectorAll('a');
|
|
40
|
-
anchors.forEach((anchor) => {
|
|
41
|
-
const href = anchor.getAttribute('href');
|
|
42
|
-
if (href) {
|
|
43
|
-
anchor.setAttribute('target', '_blank');
|
|
44
|
-
anchor.setAttribute('rel', 'noopener noreferrer');
|
|
45
|
-
anchor.classList.add(styles['uikit-modal-link']);
|
|
46
|
-
const originalText = anchor.textContent || '';
|
|
47
|
-
anchor.innerHTML = `<span style="padding: 0 0.2em; display: inline-block; color: var(--text-color-link)">${originalText}</span>`;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
return doc.body.innerHTML;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const TypeIcons: Record<string, () => JSX.Element> = {
|
|
54
|
-
success: () => <span style={{ color: 'green', marginRight: '6px' }}>✓</span>,
|
|
55
|
-
info: () => <span style={{ color: '#1890ff', marginRight: '6px' }}>ℹ</span>,
|
|
56
|
-
error: () => <span style={{ color: 'red', marginRight: '6px' }}>✕</span>,
|
|
57
|
-
warning: () => <span style={{ color: '#faad14', marginRight: '6px' }}>⚠</span>,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const isLocalEnvironment = (): boolean => {
|
|
61
|
-
const { hostname: host, href } = window.location;
|
|
62
|
-
if (host === 'localhost' || host === '127.0.0.1' || host.startsWith('192.168.')) {
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
if (href.startsWith('https://web.sdk.qcloud.com/trtc/livekit')) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const cleanup = () => {
|
|
72
|
-
if (root) {
|
|
73
|
-
root.unmount();
|
|
74
|
-
root = null;
|
|
75
|
-
}
|
|
76
|
-
if (container && container.parentNode) {
|
|
77
|
-
container.parentNode.removeChild(container);
|
|
78
|
-
container = null;
|
|
79
|
-
}
|
|
80
|
-
resolvePromise = null;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
interface UIKitModalComponentProps extends UIKitModalOptions {
|
|
84
|
-
visible: boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function UIKitModalComponent(props: UIKitModalComponentProps) {
|
|
88
|
-
const {
|
|
89
|
-
type = 'info',
|
|
90
|
-
title = '',
|
|
91
|
-
content = '',
|
|
92
|
-
visible = false,
|
|
93
|
-
onConfirm,
|
|
94
|
-
onCancel,
|
|
95
|
-
} = props;
|
|
96
|
-
|
|
97
|
-
const cancelText = t('reject');
|
|
98
|
-
const confirmText = t('accept');
|
|
99
|
-
|
|
100
|
-
const modalContainerClass = IS_PC
|
|
101
|
-
? `${styles['uikit-modal-default']} ${styles['uikit-modal-container']}`
|
|
102
|
-
: `${styles['uikit-modal-default']} ${styles['uikit-modal-container']} ${styles['uikit-modal-container-mobile']}`;
|
|
103
|
-
|
|
104
|
-
const processedContent = useMemo(() => {
|
|
105
|
-
if (!content || typeof content !== 'string') {
|
|
106
|
-
return content;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (URL_REGEX.test(content.trim())) {
|
|
110
|
-
const url = content.trim();
|
|
111
|
-
const href = url.startsWith('http') ? url : `https://${url}`;
|
|
112
|
-
return `<a href="${escapeHtml(href)}" target="_blank" rel="noopener noreferrer" class="${styles['uikit-modal-link']}">${escapeHtml(url)}</a>`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (content.includes('<a ') || content.includes('<a>')) {
|
|
116
|
-
return processAnchorTags(content);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (FULL_URL_REGEX.test(content)) {
|
|
120
|
-
return escapeHtml(content).replace(FULL_URL_REGEX, url => `<a href="${url}" target="_blank" rel="noopener noreferrer" class="${styles['uikit-modal-link']}">${url}</a>`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return escapeHtml(content);
|
|
124
|
-
}, [content]);
|
|
125
|
-
|
|
126
|
-
const TypeIcon = TypeIcons[type] || TypeIcons.info;
|
|
127
|
-
|
|
128
|
-
if (!visible) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const modalContent = (
|
|
133
|
-
<div
|
|
134
|
-
className={styles['uikit-modal-mask']}
|
|
135
|
-
onClick={onConfirm}
|
|
136
|
-
>
|
|
137
|
-
<div
|
|
138
|
-
className={modalContainerClass}
|
|
139
|
-
onClick={e => e.stopPropagation()}
|
|
140
|
-
>
|
|
141
|
-
<div className={styles['uikit-modal-header']}>
|
|
142
|
-
<TypeIcon />
|
|
143
|
-
<span className={styles['uikit-modal-title']}>{title}</span>
|
|
144
|
-
</div>
|
|
145
|
-
<div
|
|
146
|
-
className={styles['uikit-modal-body']}
|
|
147
|
-
dangerouslySetInnerHTML={typeof processedContent === 'string' ? { __html: processedContent } : undefined}
|
|
148
|
-
>
|
|
149
|
-
{typeof processedContent !== 'string' ? processedContent : null}
|
|
150
|
-
</div>
|
|
151
|
-
<div className={styles['uikit-modal-footer']}>
|
|
152
|
-
<button
|
|
153
|
-
className={`${styles['uikit-modal-btn']} ${styles['uikit-modal-btn-cancel']}`}
|
|
154
|
-
onClick={onCancel}
|
|
155
|
-
>
|
|
156
|
-
{cancelText || 'Cancel'}
|
|
157
|
-
</button>
|
|
158
|
-
<button
|
|
159
|
-
className={`${styles['uikit-modal-btn']} ${styles['uikit-modal-btn-confirm']}`}
|
|
160
|
-
onClick={onConfirm}
|
|
161
|
-
>
|
|
162
|
-
{confirmText || 'Confirm'}
|
|
163
|
-
</button>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
return createPortal(modalContent, document.body);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
interface UIKitModalWrapperProps {
|
|
173
|
-
options: UIKitModalOptions;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function UIKitModalWrapper(props: UIKitModalWrapperProps) {
|
|
177
|
-
const { options } = props;
|
|
178
|
-
const [visible, setVisible] = useState(true);
|
|
179
|
-
|
|
180
|
-
const handleAction = useCallback((action: 'confirm' | 'cancel') => {
|
|
181
|
-
const { closeModal } = uikitModalState.getState();
|
|
182
|
-
setVisible(false);
|
|
183
|
-
closeModal(action);
|
|
184
|
-
if (resolvePromise) {
|
|
185
|
-
resolvePromise({ action });
|
|
186
|
-
}
|
|
187
|
-
setTimeout(cleanup, 100);
|
|
188
|
-
}, []);
|
|
189
|
-
|
|
190
|
-
const handleConfirm = useCallback(() => {
|
|
191
|
-
options.onConfirm?.();
|
|
192
|
-
handleAction('confirm');
|
|
193
|
-
}, [options, handleAction]);
|
|
194
|
-
|
|
195
|
-
const handleCancel = useCallback(() => {
|
|
196
|
-
options.onCancel?.();
|
|
197
|
-
handleAction('cancel');
|
|
198
|
-
}, [options, handleAction]);
|
|
199
|
-
|
|
200
|
-
useEffect(() => {
|
|
201
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
202
|
-
if (e.key === 'Escape') {
|
|
203
|
-
handleCancel();
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
207
|
-
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
208
|
-
}, [handleCancel]);
|
|
209
|
-
|
|
210
|
-
return (
|
|
211
|
-
<UIKitModalComponent
|
|
212
|
-
{...options}
|
|
213
|
-
visible={visible}
|
|
214
|
-
onConfirm={handleConfirm}
|
|
215
|
-
onCancel={handleCancel}
|
|
216
|
-
/>
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const createUIKitModal = (options: UIKitModalOptions): Promise<{ action: string }> => new Promise((resolve) => {
|
|
221
|
-
cleanup();
|
|
222
|
-
|
|
223
|
-
const { openModal } = uikitModalState.getState();
|
|
224
|
-
|
|
225
|
-
openModal({
|
|
226
|
-
id: options.id,
|
|
227
|
-
title: options.title,
|
|
228
|
-
content: options.content,
|
|
229
|
-
type: options.type,
|
|
230
|
-
...(options.onConfirm && { onConfirm: options.onConfirm }),
|
|
231
|
-
...(options.onCancel && { onCancel: options.onCancel }),
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
if (!isLocalEnvironment()) {
|
|
235
|
-
resolve({ action: 'confirm' });
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
resolvePromise = resolve;
|
|
240
|
-
|
|
241
|
-
container = document.createElement('div');
|
|
242
|
-
container.id = 'uikit-modal-root';
|
|
243
|
-
document.body.appendChild(container);
|
|
244
|
-
root = ReactDOM.createRoot(container);
|
|
245
|
-
root.render(React.createElement(UIKitModalWrapper, { options }));
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
export const UIKitModal = {
|
|
249
|
-
openModal: (config: UIKitModalOptions) => createUIKitModal(config),
|
|
250
|
-
};
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import { TUICallKitAPI } from '../../../../TUICallService/index';
|
|
3
|
-
|
|
4
|
-
// Types
|
|
5
|
-
export interface UIKitModalConfig {
|
|
6
|
-
id: number;
|
|
7
|
-
title: string;
|
|
8
|
-
content: string | ReactNode;
|
|
9
|
-
type: 'info' | 'warning' | 'error' | 'success';
|
|
10
|
-
onConfirm?: () => void;
|
|
11
|
-
onCancel?: () => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type UIKitModalOptions = UIKitModalConfig;
|
|
15
|
-
|
|
16
|
-
interface AnalyticsData {
|
|
17
|
-
eventType: number;
|
|
18
|
-
modalId: number;
|
|
19
|
-
title: string;
|
|
20
|
-
type: string;
|
|
21
|
-
content: string | ReactNode;
|
|
22
|
-
timestamp: number;
|
|
23
|
-
stayDuration?: number;
|
|
24
|
-
closeReasonCode?: number;
|
|
25
|
-
sessionId?: string;
|
|
26
|
-
platformCode?: number;
|
|
27
|
-
userAgent?: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
interface UIKitModalState {
|
|
31
|
-
modalData: UIKitModalConfig | null;
|
|
32
|
-
activeModalId: number | null;
|
|
33
|
-
modalOpenTime: number | null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface UIKitModalActions {
|
|
37
|
-
openModal: (config: UIKitModalConfig) => void;
|
|
38
|
-
closeModal: (action?: 'confirm' | 'cancel' | 'mask' | 'timeout') => void;
|
|
39
|
-
getState: () => UIKitModalState & UIKitModalActions;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getPlatformInfo() {
|
|
43
|
-
const ua = navigator.userAgent;
|
|
44
|
-
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
|
|
45
|
-
return {
|
|
46
|
-
userAgent: ua,
|
|
47
|
-
platformCode: isMobile ? 2 : 1,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function getSessionId(): string {
|
|
52
|
-
let sessionId = sessionStorage.getItem('uikit_session_id');
|
|
53
|
-
if (!sessionId) {
|
|
54
|
-
sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
55
|
-
sessionStorage.setItem('uikit_session_id', sessionId);
|
|
56
|
-
}
|
|
57
|
-
return sessionId;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function reportAnalytics(data: AnalyticsData) {
|
|
61
|
-
try {
|
|
62
|
-
// IM report
|
|
63
|
-
const tim = TUICallKitAPI.getTim();
|
|
64
|
-
if (tim && typeof tim.callExperimentalAPI === 'function') {
|
|
65
|
-
const reportData = {
|
|
66
|
-
id: data.modalId,
|
|
67
|
-
title: data.title,
|
|
68
|
-
type: data.type,
|
|
69
|
-
content: data.content,
|
|
70
|
-
};
|
|
71
|
-
tim.callExperimentalAPI('reportModalView', JSON.stringify(reportData));
|
|
72
|
-
}
|
|
73
|
-
} catch (_error) {
|
|
74
|
-
console.info('[UIKitModal]', data);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const createUIKitModalStore = () => {
|
|
79
|
-
let state: UIKitModalState = {
|
|
80
|
-
modalData: null,
|
|
81
|
-
activeModalId: null,
|
|
82
|
-
modalOpenTime: null,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const listeners: Set<() => void> = new Set();
|
|
86
|
-
|
|
87
|
-
const notify = () => {
|
|
88
|
-
listeners.forEach(listener => listener());
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const openModal = (config: UIKitModalConfig) => {
|
|
92
|
-
const now = Date.now();
|
|
93
|
-
const { userAgent, platformCode } = getPlatformInfo();
|
|
94
|
-
|
|
95
|
-
state = {
|
|
96
|
-
modalData: config,
|
|
97
|
-
activeModalId: config.id,
|
|
98
|
-
modalOpenTime: now,
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
reportAnalytics({
|
|
102
|
-
eventType: 1,
|
|
103
|
-
modalId: config.id,
|
|
104
|
-
title: config.title,
|
|
105
|
-
type: config.type,
|
|
106
|
-
content: config.content,
|
|
107
|
-
timestamp: now,
|
|
108
|
-
sessionId: getSessionId(),
|
|
109
|
-
platformCode,
|
|
110
|
-
userAgent,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
notify();
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const closeModal = (action: 'confirm' | 'cancel' | 'mask' | 'timeout' = 'confirm') => {
|
|
117
|
-
const { activeModalId, modalOpenTime, modalData } = state;
|
|
118
|
-
|
|
119
|
-
if (activeModalId === null || !modalOpenTime || !modalData) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const now = Date.now();
|
|
124
|
-
const stayDuration = now - modalOpenTime;
|
|
125
|
-
const { userAgent, platformCode } = getPlatformInfo();
|
|
126
|
-
|
|
127
|
-
const closeReasonCodeMap: Record<string, number> = {
|
|
128
|
-
confirm: 1,
|
|
129
|
-
cancel: 2,
|
|
130
|
-
timeout: 3,
|
|
131
|
-
mask: 2,
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
reportAnalytics({
|
|
135
|
-
eventType: 2,
|
|
136
|
-
modalId: activeModalId,
|
|
137
|
-
title: modalData.title,
|
|
138
|
-
type: modalData.type,
|
|
139
|
-
content: modalData.content,
|
|
140
|
-
timestamp: now,
|
|
141
|
-
stayDuration,
|
|
142
|
-
closeReasonCode: closeReasonCodeMap[action],
|
|
143
|
-
sessionId: getSessionId(),
|
|
144
|
-
platformCode,
|
|
145
|
-
userAgent,
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
state = {
|
|
149
|
-
modalData: null,
|
|
150
|
-
activeModalId: null,
|
|
151
|
-
modalOpenTime: null,
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
notify();
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const getState = (): UIKitModalState & UIKitModalActions => ({
|
|
158
|
-
...state,
|
|
159
|
-
openModal,
|
|
160
|
-
closeModal,
|
|
161
|
-
getState,
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
getState,
|
|
166
|
-
openModal,
|
|
167
|
-
closeModal,
|
|
168
|
-
subscribe: (listener: () => void) => {
|
|
169
|
-
listeners.add(listener);
|
|
170
|
-
return () => listeners.delete(listener);
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
export const uikitModalState = createUIKitModalStore();
|
|
176
|
-
|
|
177
|
-
export default uikitModalState;
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
.uikit-modal-mask {
|
|
2
|
-
position: fixed;
|
|
3
|
-
top: 0;
|
|
4
|
-
left: 0;
|
|
5
|
-
width: 100vw;
|
|
6
|
-
height: 100vh;
|
|
7
|
-
background: rgba(0, 0, 0, 0.6);
|
|
8
|
-
z-index: 9999;
|
|
9
|
-
display: flex;
|
|
10
|
-
align-items: center;
|
|
11
|
-
justify-content: center;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.uikit-modal-default {
|
|
15
|
-
width: 480px;
|
|
16
|
-
max-width: calc(100% - 40px);
|
|
17
|
-
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.uikit-modal-container {
|
|
21
|
-
box-sizing: border-box;
|
|
22
|
-
background: #fff;
|
|
23
|
-
position: relative;
|
|
24
|
-
display: flex;
|
|
25
|
-
flex-direction: column;
|
|
26
|
-
overflow: hidden;
|
|
27
|
-
padding: 24px;
|
|
28
|
-
border-radius: 20px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.uikit-modal-header {
|
|
32
|
-
display: flex;
|
|
33
|
-
justify-content: space-between;
|
|
34
|
-
align-items: center;
|
|
35
|
-
padding-bottom: 20px;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.uikit-modal-type-icon {
|
|
39
|
-
margin-right: 6px;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.uikit-modal-close-icon {
|
|
43
|
-
cursor: pointer;
|
|
44
|
-
color: #333;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.uikit-modal-title {
|
|
48
|
-
font-size: 16px;
|
|
49
|
-
line-height: 24px;
|
|
50
|
-
font-weight: 600;
|
|
51
|
-
color: #333;
|
|
52
|
-
flex: 1;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.uikit-modal-body {
|
|
56
|
-
flex: 1;
|
|
57
|
-
display: block;
|
|
58
|
-
font-size: 14px;
|
|
59
|
-
font-weight: 400;
|
|
60
|
-
line-height: 22px;
|
|
61
|
-
color: #333;
|
|
62
|
-
word-break: break-word;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.uikit-modal-link {
|
|
66
|
-
color: #006eff;
|
|
67
|
-
text-decoration: none;
|
|
68
|
-
transition: all 0.2s ease;
|
|
69
|
-
cursor: pointer;
|
|
70
|
-
border-bottom: 1px solid transparent;
|
|
71
|
-
margin: 0 0.2em;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
.uikit-modal-footer {
|
|
75
|
-
padding-top: 20px;
|
|
76
|
-
box-sizing: border-box;
|
|
77
|
-
display: flex;
|
|
78
|
-
justify-content: flex-end;
|
|
79
|
-
gap: 12px;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.uikit-modal-btn {
|
|
83
|
-
min-width: 88px;
|
|
84
|
-
height: 32px;
|
|
85
|
-
padding: 0 16px;
|
|
86
|
-
border-radius: 20px;
|
|
87
|
-
font-size: 14px;
|
|
88
|
-
font-weight: 500;
|
|
89
|
-
cursor: pointer;
|
|
90
|
-
transition: all 0.2s ease;
|
|
91
|
-
border: none;
|
|
92
|
-
outline: none;
|
|
93
|
-
white-space: nowrap;
|
|
94
|
-
|
|
95
|
-
&:active {
|
|
96
|
-
transform: scale(0.98);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.uikit-modal-btn-cancel {
|
|
101
|
-
background: #f0f2f9;
|
|
102
|
-
color: #333;
|
|
103
|
-
|
|
104
|
-
&:hover {
|
|
105
|
-
background: #e5e7ed;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.uikit-modal-btn-confirm {
|
|
110
|
-
background: #1c66e5;
|
|
111
|
-
color: #fff;
|
|
112
|
-
|
|
113
|
-
&:hover {
|
|
114
|
-
background: #1557cc;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.uikit-modal-header:empty,
|
|
119
|
-
.uikit-modal-body:empty,
|
|
120
|
-
.uikit-modal-footer:empty {
|
|
121
|
-
padding: 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.uikit-modal-container-mobile {
|
|
125
|
-
border-radius: 12px;
|
|
126
|
-
max-width: calc(100% - 32px);
|
|
127
|
-
padding: 0;
|
|
128
|
-
|
|
129
|
-
.uikit-modal-header {
|
|
130
|
-
padding: 20px 20px 16px;
|
|
131
|
-
justify-content: flex-start;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.uikit-modal-body {
|
|
135
|
-
padding: 0 20px 20px;
|
|
136
|
-
justify-content: flex-start;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.uikit-modal-footer {
|
|
140
|
-
padding: 0;
|
|
141
|
-
border-top: 0.5px solid #e5e5e5;
|
|
142
|
-
gap: 0;
|
|
143
|
-
|
|
144
|
-
.uikit-modal-btn {
|
|
145
|
-
flex: 1;
|
|
146
|
-
border-radius: 0;
|
|
147
|
-
height: 56px;
|
|
148
|
-
min-width: auto;
|
|
149
|
-
background: #fff;
|
|
150
|
-
font-size: 17px;
|
|
151
|
-
|
|
152
|
-
&:active {
|
|
153
|
-
transform: none;
|
|
154
|
-
background: #f5f5f5;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
&:hover {
|
|
158
|
-
background: #fff;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.uikit-modal-btn-cancel {
|
|
163
|
-
color: #666;
|
|
164
|
-
|
|
165
|
-
&:first-child:last-child {
|
|
166
|
-
border-radius: 0 0 12px 12px;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.uikit-modal-btn-confirm {
|
|
171
|
-
color: #1c66e5;
|
|
172
|
-
border-left: 0.5px solid #e5e5e5;
|
|
173
|
-
font-weight: 600;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { ReactNode } from 'react';
|
|
3
|
-
export interface UIKitModalConfig {
|
|
4
|
-
id: number;
|
|
5
|
-
title: string;
|
|
6
|
-
content: string | ReactNode;
|
|
7
|
-
type: 'info' | 'warning' | 'error' | 'success';
|
|
8
|
-
onConfirm?: () => void;
|
|
9
|
-
onCancel?: () => void;
|
|
10
|
-
}
|
|
11
|
-
export type UIKitModalOptions = UIKitModalConfig;
|
|
12
|
-
interface UIKitModalComponentProps extends UIKitModalOptions {
|
|
13
|
-
visible: boolean;
|
|
14
|
-
}
|
|
15
|
-
export declare function UIKitModalComponent(props: UIKitModalComponentProps): React.ReactPortal;
|
|
16
|
-
export declare const UIKitModal: {
|
|
17
|
-
openModal: (config: UIKitModalOptions) => Promise<{
|
|
18
|
-
action: string;
|
|
19
|
-
}>;
|
|
20
|
-
};
|
|
21
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
export interface UIKitModalConfig {
|
|
3
|
-
id: number;
|
|
4
|
-
title: string;
|
|
5
|
-
content: string | ReactNode;
|
|
6
|
-
type: 'info' | 'warning' | 'error' | 'success';
|
|
7
|
-
onConfirm?: () => void;
|
|
8
|
-
onCancel?: () => void;
|
|
9
|
-
}
|
|
10
|
-
export type UIKitModalOptions = UIKitModalConfig;
|
|
11
|
-
interface UIKitModalState {
|
|
12
|
-
modalData: UIKitModalConfig | null;
|
|
13
|
-
activeModalId: number | null;
|
|
14
|
-
modalOpenTime: number | null;
|
|
15
|
-
}
|
|
16
|
-
interface UIKitModalActions {
|
|
17
|
-
openModal: (config: UIKitModalConfig) => void;
|
|
18
|
-
closeModal: (action?: 'confirm' | 'cancel' | 'mask' | 'timeout') => void;
|
|
19
|
-
getState: () => UIKitModalState & UIKitModalActions;
|
|
20
|
-
}
|
|
21
|
-
export declare const uikitModalState: {
|
|
22
|
-
getState: () => UIKitModalState & UIKitModalActions;
|
|
23
|
-
openModal: (config: UIKitModalConfig) => void;
|
|
24
|
-
closeModal: (action?: "confirm" | "cancel" | "mask" | "timeout") => void;
|
|
25
|
-
subscribe: (listener: () => void) => () => boolean;
|
|
26
|
-
};
|
|
27
|
-
export default uikitModalState;
|