diginet-core-ui 1.3.33 → 1.3.34

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.
@@ -1,13 +1,27 @@
1
1
  /** @jsxRuntime classic */
2
2
 
3
3
  /** @jsx jsx */
4
- import { Fragment, memo, useRef, forwardRef, useState, useEffect, useMemo } from 'react';
4
+ import { Fragment, memo, useRef, forwardRef, useState, useEffect, useMemo, useImperativeHandle } from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { jsx, css } from '@emotion/core';
7
- import { Account } from '../../icons';
7
+ import OptionWrapper from '../others/option-wrapper';
8
8
  import { ButtonIcon, ModalSample, Popover, Popup, Typography } from '../';
9
9
  import { randomString } from '../../utils';
10
10
  import { getGlobal } from '../../global';
11
+ import { alignCenter, borderNone, displayBlock, inlineFlex, overflowHidden, pointerEventsNone, positionAbsolute, positionRelative, userSelectNone } from '../../styles/general';
12
+ import isMobile from '../../utils/isMobile';
13
+ import { color as colors } from '../../styles/colors';
14
+ const {
15
+ system: {
16
+ white
17
+ },
18
+ fill: {
19
+ tooltip: fillTooltip
20
+ },
21
+ text: {
22
+ tooltip: textTooltip
23
+ }
24
+ } = colors;
11
25
  const existed = {},
12
26
  urlAvatar = {},
13
27
  popupHandler = {};
@@ -64,26 +78,6 @@ const getDirection = direction => {
64
78
  }
65
79
  };
66
80
 
67
- const isMobile = {
68
- iOS: function () {
69
- return navigator.userAgent.match(/iPhone|iPad|iPod/i);
70
- },
71
- Android: function () {
72
- return navigator.userAgent.match(/Android/i);
73
- },
74
- BlackBerry: function () {
75
- return navigator.userAgent.match(/BlackBerry/i);
76
- },
77
- Opera: function () {
78
- return navigator.userAgent.match(/Opera Mini/i);
79
- },
80
- Windows: function () {
81
- return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
82
- },
83
- any: function () {
84
- return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows();
85
- }
86
- };
87
81
  const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
88
82
  refs,
89
83
  src,
@@ -107,11 +101,8 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
107
101
  readOnly,
108
102
  disabled,
109
103
  ...props
110
- }, ref) => {
111
- if (!ref) {
112
- ref = useRef(null);
113
- }
114
-
104
+ }, reference) => {
105
+ const ref = useRef(null);
115
106
  const inputRef = useRef(null);
116
107
  const avatarRef = useRef(null);
117
108
  const [unique] = useState(randomString(6, {
@@ -120,6 +111,11 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
120
111
  }));
121
112
  const [viewAvatar, setViewAvatar] = useState(false);
122
113
  const [viewMoreInfo, setViewMoreInfo] = useState(false);
114
+ const [srcState, setSrcState] = useState(src);
115
+
116
+ const _isMobile = isMobile.any();
117
+
118
+ if (!defaultSrc) defaultSrc = require('../../assets/avatar/default.svg');
123
119
 
124
120
  if (width && !height) {
125
121
  height = width;
@@ -129,75 +125,71 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
129
125
  width = height;
130
126
  }
131
127
 
132
- const iconDefault = `<svg width="${width}" height="${height}" viewBox="0 0 24 24" fill="none">
133
- <path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.47998 2 2 6.48 2 12C2 17.52 6.47998 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM12 5C13.66 5 15 6.34 15 8C15 9.66 13.66 11 12 11C10.34 11 9 9.66 9 8C9 6.34 10.34 5 12 5ZM6 15.98C7.28998 17.92 9.5 19.2 12 19.2C14.5 19.2 16.71 17.92 18 15.98C17.97 13.99 13.99 12.9 12 12.9C10 12.9 6.03003 13.99 6 15.98Z" fill="#7F828E"></path>
134
- </svg>`;
135
128
  const ActionIcon = css`
136
- position: absolute;
137
- right: -36px;
138
- transition: opacity 0.5s;
139
- opacity: 0;
140
- .icon-delete {
141
- display: none;
142
- }
143
- `;
129
+ ${positionAbsolute}
130
+ right: -36px;
131
+ transition: opacity 0.5s;
132
+ opacity: 0;
133
+ .icon-delete {
134
+ display: flex;
135
+ }
136
+ `;
144
137
  const AvatarPreview = css`
145
- display: block;
146
- position: relative;
138
+ ${displayBlock}
139
+ ${positionRelative}
140
+ ${overflowHidden}
147
141
  width: 100%;
148
- height: 100%;
149
- border-radius: 50%;
150
- overflow: hidden;
151
- cursor: ${readOnly ? 'initial' : 'pointer'};
152
- `;
142
+ height: 100%;
143
+ border-radius: 50%;
144
+ cursor: ${readOnly ? 'initial' : 'pointer'};
145
+ `;
153
146
  const AvatarContainer = css`
154
- display: inline-flex;
155
- position: relative;
156
- align-items: center;
147
+ ${inlineFlex}
148
+ ${positionRelative}
149
+ ${alignCenter}
157
150
  &.disabled {
158
- .css-${AvatarPreview.name} {
159
- pointer-events: none;
160
- cursor: inherit;
161
- }
162
- .css-${ActionIcon.name} {
163
- display: none !important;
164
- }
165
- }
166
- &:hover {
167
- .css-${ActionIcon.name} {
168
- opacity: 1;
169
- }
170
- }
171
- `;
151
+ .css-${AvatarPreview.name} {
152
+ ${pointerEventsNone}
153
+ cursor: inherit;
154
+ }
155
+ .css-${ActionIcon.name} {
156
+ display: none !important;
157
+ }
158
+ }
159
+ &:hover {
160
+ .css-${ActionIcon.name} {
161
+ opacity: 1;
162
+ }
163
+ }
164
+ `;
172
165
  const AvatarRoot = css`
173
- display: block;
174
- position: relative;
166
+ ${displayBlock}
167
+ ${positionRelative}
168
+ ${overflowHidden}
169
+ ${userSelectNone}
170
+ ${borderNone}
175
171
  border-radius: 50%;
176
- width: ${isNaN(width) ? width : width + 'px'};
177
- height: ${isNaN(height) ? height : height + 'px'};
178
- overflow: hidden;
179
- box-sizing: content-box;
180
- user-select: none;
181
- border: none;
182
- input {
183
- display: none;
184
- }
185
- img {
186
- background-image: url(${require('../../assets/avatar/default.svg')});
187
- background-size: cover;
188
- width: 100%;
189
- height: 100%;
190
- }
191
- `;
172
+ width: ${isNaN(width) ? width : width + 'px'};
173
+ height: ${isNaN(height) ? height : height + 'px'};
174
+ box-sizing: content-box;
175
+ border: ${typeof outlined === 'boolean' && outlined ? `1px solid ${white}` : outlined};
176
+ input {
177
+ display: none;
178
+ }
179
+ img {
180
+ width: 100%;
181
+ height: 100%;
182
+ }
183
+ `;
192
184
  const MoreInfo = css`
193
- display: block;
194
- position: relative;
185
+ ${displayBlock}
186
+ ${positionRelative}
195
187
  padding: 8px;
196
- `;
188
+ `;
197
189
 
198
190
  const triggerInput = e => {
199
- if (!e || !existed[unique]) {
200
- ref.current.querySelector('input').click();
191
+ if (e || !existed[unique]) {
192
+ inputRef.current.click();
201
193
  } else {
202
194
  // on View
203
195
  setViewAvatar(true);
@@ -208,7 +200,7 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
208
200
  if (typeof matchType === 'object' && matchType instanceof RegExp) {
209
201
  return matchType.test(type);
210
202
  } else if (typeof matchType === 'object' && Array.isArray(matchType)) {
211
- const pattern = new RegExp('^image\/(' + matchType.join('|') + ')', 'i');
203
+ const pattern = new RegExp('^image/(' + matchType.join('|') + ')', 'i');
212
204
  return pattern.test(type);
213
205
  } else {
214
206
  return new RegExp(matchType).test(type);
@@ -233,18 +225,8 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
233
225
  }
234
226
 
235
227
  reader.onload = e => {
236
- const img = document.createElement('img');
237
228
  urlAvatar[unique] = e.target.result;
238
- img.src = urlAvatar[unique];
239
- img.alt = '';
240
- img.style.cssText = 'object-fit: cover';
241
- ref.current.querySelector(`.css-${AvatarPreview.name}`).innerHTML = '';
242
- ref.current.querySelector(`.css-${AvatarPreview.name}`).appendChild(img);
243
-
244
- if (!readOnly && clearAble) {
245
- ref.current.querySelector(`.icon-delete`).style.display = 'flex';
246
- }
247
-
229
+ setSrcState(urlAvatar[unique]);
248
230
  existed[unique] = true;
249
231
  };
250
232
 
@@ -253,39 +235,29 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
253
235
  };
254
236
 
255
237
  const onRemoveAvatar = () => {
256
- if (defaultSrc) {
257
- ref.current.querySelector('img').src = defaultSrc;
258
- } else {
259
- ref.current.querySelector(`.css-${AvatarPreview.name}`).innerHTML = iconDefault;
260
- }
261
-
238
+ setSrcState(null);
262
239
  existed[unique] = false;
263
240
  inputRef.current.value = '';
264
-
265
- if (!readOnly && clearAble) {
266
- ref.current.querySelector(`.icon-delete`).style.display = null;
267
- }
268
-
269
241
  !!onRemove && onRemove();
270
242
  };
271
243
 
272
244
  const renderData = () => {
273
- const info = Object.keys(data);
245
+ const info = Object.keys(data || {});
274
246
 
275
247
  if (info.length) {
276
248
  return info.map((key, index) => {
277
249
  return jsx(Typography, {
278
250
  key: index,
279
- color: 'white',
251
+ color: textTooltip,
280
252
  type: 'p1'
281
253
  }, key + ': ' + data[key]);
282
254
  });
283
255
  }
284
256
 
285
257
  return jsx(Typography, {
286
- color: 'white',
258
+ color: textTooltip,
287
259
  type: 'p1'
288
- }, "Kh\xF4ng c\xF3 d\u1EEF li\u1EC7u");
260
+ }, getGlobal('noDataText'));
289
261
  };
290
262
 
291
263
  const showMoreInfo = () => {
@@ -296,95 +268,58 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
296
268
  if (hoverAble) setViewMoreInfo(false);
297
269
  };
298
270
 
271
+ const _onClick = () => {
272
+ if (disabled) return;
273
+
274
+ if (readOnly) {
275
+ if (_isMobile) showMoreInfo();
276
+ } else triggerInput();
277
+ };
278
+
279
+ const _onMouseEnter = () => {
280
+ if (!_isMobile) showMoreInfo();
281
+ };
282
+
283
+ const _onMouseLeave = () => {
284
+ if (!_isMobile) closeMoreInfo();
285
+ };
286
+
299
287
  useEffect(() => {
300
288
  if (refs) refs(ref);
301
289
  }, []);
302
- useEffect(() => {
303
- if (outlined) {
304
- ref.current.querySelector(`.css-${AvatarRoot.name}`).style.border = typeof outlined === 'boolean' ? '1px solid #FFF' : outlined;
305
- return () => {
306
- if (ref.current) {
307
- ref.current.querySelector(`.css-${AvatarRoot.name}`).style.border = null;
308
- }
309
- };
310
- }
311
- }, [outlined]);
312
- useEffect(() => {
313
- if (!readOnly && clearAble && src) {
314
- ref.current.querySelector(`.icon-delete`).style.display = 'flex';
315
- }
316
- }, [clearAble]); // useEffect(() => {
317
- // if (hoverAble) {
318
- // avatarRef.current.addEventListener('mouseenter', showMoreInfo);
319
- // avatarRef.current.addEventListener('mouseleave', closeMoreInfo);
320
- // }
321
- // return () => {
322
- // if (hoverAble && avatarRef.current) {
323
- // avatarRef.current.removeEventListener('mouseenter', showMoreInfo);
324
- // avatarRef.current.removeEventListener('mouseleave', closeMoreInfo);
325
- // }
326
- // };
327
- // }, [hoverAble])
328
-
329
290
  useEffect(() => {
330
291
  if (src) {
331
- existed[unique] = true;
332
292
  inputRef.current.value = '';
333
293
  const img = document.createElement('img');
334
294
  urlAvatar[unique] = src;
335
295
  img.src = src;
336
296
  img.alt = '';
297
+ setSrcState(src);
298
+ existed[unique] = true;
337
299
 
338
300
  img.onerror = e => {
339
- if (defaultSrc) {
340
- e.target.src = defaultSrc;
341
- } else {
342
- if (ref.current) ref.current.querySelector(`.css-${AvatarPreview.name}`).innerHTML = iconDefault;
343
- }
344
- };
345
-
346
- img.style.cssText = 'object-fit: cover';
347
- ref.current.querySelector(`.css-${AvatarPreview.name}`).innerHTML = '';
348
- ref.current.querySelector(`.css-${AvatarPreview.name}`).appendChild(img);
349
-
350
- if (!readOnly && clearAble) {
351
- ref.current.querySelector(`.icon-delete`).style.display = 'flex';
352
- }
353
-
354
- return () => {
301
+ setSrcState(null);
355
302
  existed[unique] = false;
356
-
357
- if (ref.current) {
358
- if (defaultSrc) {
359
- ref.current.querySelector('img').src = defaultSrc;
360
- } else {
361
- ref.current.querySelector(`.css-${AvatarPreview.name}`).innerHTML = iconDefault;
362
- }
363
-
364
- if (!readOnly && clearAble && ref.current.querySelector(`.icon-delete`)) {
365
- ref.current.querySelector(`.icon-delete`).style.display = null;
366
- }
367
- }
368
303
  };
369
304
  }
370
305
  }, [src]);
371
- useEffect(() => {
372
- if (disabled) {
373
- ref.current.classList.add('disabled');
374
- return () => {
375
- if (ref.current) {
376
- ref.current.classList.remove('disabled');
377
- }
378
- };
379
- }
380
- }, [disabled]);
306
+ useImperativeHandle(reference, () => {
307
+ const currentRef = ref.current || {};
308
+ const _instance = {}; // methods
309
+
310
+ _instance.__proto__ = {}; // hidden methods
311
+
312
+ currentRef.instance = _instance;
313
+ return currentRef;
314
+ });
381
315
  const AvatarView = useMemo(() => jsx("div", {
382
316
  css: AvatarContainer,
383
317
  ref: ref,
384
- id: unique
318
+ id: unique,
319
+ className: disabled ? 'disabled' : ''
385
320
  }, jsx("div", {
386
321
  css: AvatarRoot,
387
- className: ['DGN-UI-Avatar', className].join(' ').trim(),
322
+ className: ['DGN-UI-Avatar', className].join(' ').trim().replace(/\s+/g, ' '),
388
323
  ...props
389
324
  }, jsx("input", {
390
325
  ref: inputRef,
@@ -394,22 +329,18 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
394
329
  onChange: onChangeAvatar
395
330
  }), jsx("div", {
396
331
  css: AvatarPreview,
397
- onClick: readOnly ? isMobile.any() ? showMoreInfo : null : triggerInput,
332
+ onClick: _onClick,
398
333
  ref: avatarRef,
399
- onMouseEnter: isMobile.any() ? null : showMoreInfo,
400
- onMouseLeave: isMobile.any() ? null : closeMoreInfo,
334
+ onMouseEnter: _onMouseEnter,
335
+ onMouseLeave: _onMouseLeave,
401
336
  tabIndex: "-1",
402
337
  onBlur: closeMoreInfo
403
- }, defaultSrc ? jsx("img", {
404
- src: defaultSrc,
405
- alt: defaultSrc,
338
+ }, jsx("img", {
339
+ src: srcState || defaultSrc,
340
+ alt: srcState || defaultSrc,
406
341
  style: {
407
342
  objectFit: 'cover'
408
343
  }
409
- }) : jsx(Account, {
410
- width: width,
411
- height: height,
412
- viewBox: true
413
344
  }))), !readOnly && !disabled && jsx("span", {
414
345
  css: ActionIcon
415
346
  }, jsx(ButtonIcon, {
@@ -418,8 +349,8 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
418
349
  width: actionIconWidth,
419
350
  height: actionIconHeight,
420
351
  className: 'icon-edit',
421
- onClick: () => triggerInput()
422
- }), clearAble && jsx(ButtonIcon, {
352
+ onClick: triggerInput
353
+ }), clearAble && srcState && jsx(ButtonIcon, {
423
354
  viewType: 'ghost',
424
355
  name: 'Delete',
425
356
  width: actionIconWidth,
@@ -429,7 +360,7 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
429
360
  style: {
430
361
  marginTop: '8px'
431
362
  }
432
- }))), [width, height, readOnly, disabled, clearAble, maxSize, matchType, hoverAble]);
363
+ }))), [width, height, readOnly, disabled, clearAble, maxSize, matchType, hoverAble, outlined, srcState]);
433
364
  const ModalView = useMemo(() => jsx(ModalSample, {
434
365
  open: viewAvatar,
435
366
  onClose: () => setViewAvatar(false),
@@ -446,9 +377,10 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
446
377
  }
447
378
  })), [viewAvatar]);
448
379
  const MoreInfoView = useMemo(() => jsx(Popover, {
380
+ arrow: true,
449
381
  open: viewMoreInfo,
450
382
  pressESCToClose: false,
451
- bgColor: '#000',
383
+ bgColor: fillTooltip,
452
384
  anchor: avatarRef,
453
385
  fullScreen: false,
454
386
  width: 'max-content',
@@ -473,8 +405,6 @@ Avatar.defaultProps = {
473
405
  outlined: false,
474
406
  width: 48,
475
407
  height: 48,
476
- actionIconWidth: '100%',
477
- actionIconHeight: '100%',
478
408
  className: '',
479
409
  direction: 'down',
480
410
  maxSizeError: `File ${getGlobal(['errorDefault', 'maxSize'])}`,
@@ -528,18 +458,18 @@ Avatar.propTypes = {
528
458
  /** source of file (http:// or https://) */
529
459
  src: PropTypes.string,
530
460
 
531
- /**
532
- * it is used to display the default if there is no src<br />
533
- * if undefined, will display icons available in the icons store
461
+ /**
462
+ * it is used to display the default if there is no src<br />
463
+ * if undefined, will display icons available in the icons store
534
464
  */
535
465
  defaultSrc: PropTypes.string,
536
466
 
537
467
  /** the direction to display more info */
538
468
  direction: PropTypes.oneOf(['top', 'down', 'left', 'right']),
539
469
 
540
- /**
541
- * data to display when hoverAble is true<br />
542
- * data is an object or function return a jsx element
470
+ /**
471
+ * data to display when hoverAble is true<br />
472
+ * data is an object or function return a jsx element
543
473
  */
544
474
  data: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
545
475
 
@@ -553,6 +483,25 @@ Avatar.propTypes = {
553
483
  onChange: PropTypes.func,
554
484
 
555
485
  /** any props else */
556
- props: PropTypes.any
486
+ props: PropTypes.any,
487
+
488
+ /**
489
+ * ref methods
490
+ *
491
+ * * option(): Gets all UI component properties
492
+ * * Returns value - object
493
+ * * option(optionName): Gets the value of a single property
494
+ * * @param {optionName} - string
495
+ * * Returns value - any
496
+ * * option(optionName, optionValue): Updates the value of a single property
497
+ * * @param {optionName} - string
498
+ * * @param {optionValue} - any
499
+ * * option(options): Updates the values of several properties
500
+ * * @param {options} - object
501
+ */
502
+ reference: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
503
+ current: PropTypes.instanceOf(Element)
504
+ })])
557
505
  };
558
- export default Avatar;
506
+ export { Avatar };
507
+ export default OptionWrapper(Avatar);