diginet-core-ui 1.3.90 → 1.3.91

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,20 +1,19 @@
1
1
  /** @jsxRuntime classic */
2
2
  /** @jsx jsx */
3
- import { jsx, css, keyframes } from '@emotion/core';
3
+ import { css, jsx } from '@emotion/core';
4
4
  import AvatarDefault from "../../assets/avatar/default.svg";
5
- import { ButtonIcon, ModalSample, Popover, Popup, Typography } from "./..";
5
+ import { ButtonIcon, Image, ModalSample, Notify, Popover, Typography } from "./..";
6
+ import OptionWrapper from "../others/option-wrapper";
6
7
  import { getGlobal } from "../../global";
7
8
  import PropTypes from 'prop-types';
8
9
  import { forwardRef, Fragment, isValidElement, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
9
- import { itemsCenter, borderNone, displayBlock, displayNone, flexCol, displayInlineFlex, overflowHidden, parseWidthHeight, pointerEventsNone, positionAbsolute, positionRelative, userSelectNone } from "../../styles/general";
10
+ import { borderNone, borderRadius, boxContent, cursorInherit, cursorPointer, displayBlock, displayFlex, displayInlineFlex, displayNone, flexCol, itemsCenter, overflowHidden, parseMinWidth, parseWidthHeight, pd, positionAbsolute, positionRelative, userSelectNone, z } from "../../styles/general";
10
11
  import { useTheme } from "../../theme";
11
- import { classNames, isMobile, randomString } from "../../utils";
12
- import { useIntersection } from "../../utils/intersectionObserver";
13
- import OptionWrapper from "../others/option-wrapper";
12
+ import { classNames, isMobile } from "../../utils";
14
13
  const {
15
14
  colors: {
16
15
  system: {
17
- white
16
+ white: systemWhite
18
17
  },
19
18
  fill: {
20
19
  tooltip: fillTooltip
@@ -22,19 +21,8 @@ const {
22
21
  text: {
23
22
  tooltip: textTooltip
24
23
  }
25
- },
26
- spacing,
27
- zIndex: zIndexCORE
24
+ }
28
25
  } = useTheme();
29
- const existed = {},
30
- urlAvatar = {};
31
- const blurKeyframe = keyframes`
32
- 0% { -webkit-filter: blur(4px);}
33
- 25% { -webkit-filter: blur(3px);}
34
- 50% { -webkit-filter: blur(2px);}
35
- 75% { -webkit-filter: blur(1px);}
36
- 100% { -webkit-filter: blur(0px);}
37
- `;
38
26
  const checkFileType = (type, matchType) => {
39
27
  if (typeof matchType === 'object' && matchType instanceof RegExp) {
40
28
  return matchType.test(type);
@@ -73,30 +61,22 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
73
61
  width,
74
62
  wrongTypeError
75
63
  }, reference) => {
64
+ if (!reference) reference = useRef(null);
76
65
  if (!defaultSrc) defaultSrc = AvatarDefault;
77
66
  const ref = useRef(null);
78
67
  const inputRef = useRef(null);
79
68
  const avatarRef = useRef(null);
80
- const popupRef = useRef(null);
81
- const [unique] = useState(randomString(6, {
82
- allowNumber: false,
83
- allowSymbol: false
84
- }));
69
+ const notifyRef = useRef(null);
85
70
  const [viewAvatar, setViewAvatar] = useState(false);
86
71
  const [viewMoreInfo, setViewMoreInfo] = useState(false);
87
72
  const [srcState, setSrcState] = useState(src);
88
- const [isInView, setIsInView] = useState(false);
89
- const [onLoaded, setOnLoaded] = useState(false);
90
- useIntersection(ref, () => {
91
- setIsInView(true);
92
- });
93
73
  const _ActionIconCSS = ActionIconCSS(actionIconWidth);
94
- const _AvatarPreviewCSS = AvatarPreviewCSS(readOnly);
95
- const _AvatarContainerCSS = AvatarContainerCSS(_AvatarPreviewCSS.name, _ActionIconCSS.name);
74
+ const _AvatarPreviewCSS = AvatarPreviewCSS(readOnly || disabled);
75
+ const _AvatarContainerCSS = AvatarContainerCSS(_ActionIconCSS.name);
96
76
  const _AvatarRootCSS = AvatarRootCSS(width, height, outlined);
97
77
  const _isMobile = isMobile.any();
98
78
  const triggerInput = e => {
99
- if (e || !existed[unique]) {
79
+ if (e || !srcState) {
100
80
  inputRef.current.click();
101
81
  } else {
102
82
  // on View
@@ -109,29 +89,22 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
109
89
  const reader = new FileReader();
110
90
  if (!checkFileType(file.type, matchType)) {
111
91
  input.target.value = '';
112
- popupRef.current.instance.show({
113
- description: wrongTypeError
114
- });
92
+ notifyRef.current.instance.show(wrongTypeError);
115
93
  return;
116
94
  }
117
95
  if (+maxSize && file.size > maxSize * 1024 ** 2) {
118
96
  input.target.value = '';
119
- popupRef.current.instance.show({
120
- description: maxSizeError
121
- });
97
+ notifyRef.current.instance.show(maxSizeError);
122
98
  return;
123
99
  }
124
100
  reader.onload = e => {
125
- urlAvatar[unique] = e.target.result;
126
- setSrcState(urlAvatar[unique]);
127
- existed[unique] = true;
101
+ setSrcState(e.target.result);
128
102
  };
129
103
  reader.readAsDataURL(file);
130
104
  !!onChange && onChange(input);
131
105
  };
132
106
  const onRemoveAvatar = () => {
133
107
  setSrcState(null);
134
- existed[unique] = false;
135
108
  inputRef.current.value = '';
136
109
  !!onRemove && onRemove();
137
110
  };
@@ -152,32 +125,6 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
152
125
  type: 'p1'
153
126
  }, getGlobal('noDataText'));
154
127
  };
155
- const renderImage = () => {
156
- const _image = jsx(Fragment, null, !onLoaded && jsx("img", {
157
- src: defaultSrc,
158
- alt: '',
159
- style: {
160
- objectFit: 'cover'
161
- }
162
- }), jsx("img", {
163
- css: blurAnimationCSS,
164
- src: srcState,
165
- alt: srcState,
166
- style: {
167
- objectFit: 'cover'
168
- },
169
- onLoad: () => setOnLoaded(true)
170
- }));
171
- if (lazyLoading) {
172
- return isInView ? _image : jsx("img", {
173
- src: defaultSrc,
174
- alt: '',
175
- style: {
176
- objectFit: 'cover'
177
- }
178
- });
179
- } else return _image;
180
- };
181
128
  const showMoreInfo = () => {
182
129
  if (hoverAble) setViewMoreInfo(true);
183
130
  };
@@ -201,22 +148,11 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
201
148
  };
202
149
  useEffect(() => {
203
150
  if (src) {
204
- if (isInView || !lazyLoading) {
205
- inputRef.current.value = '';
206
- const img = document.createElement('img');
207
- urlAvatar[unique] = src;
208
- img.src = src;
209
- img.alt = '';
210
- img.onerror = () => {
211
- setSrcState(defaultSrc);
212
- existed[unique] = false;
213
- };
214
- img.onload = () => {
215
- setSrcState(src);
216
- existed[unique] = true;
217
- };
218
- }
151
+ setSrcState(src);
219
152
  }
153
+ return () => {
154
+ setSrcState(defaultSrc);
155
+ };
220
156
  }, [src]);
221
157
  useImperativeHandle(reference, () => {
222
158
  const currentRef = ref.current || {};
@@ -230,11 +166,9 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
230
166
  });
231
167
  return useMemo(() => {
232
168
  return jsx(Fragment, null, jsx("div", {
233
- css: _AvatarContainerCSS,
234
- ref: ref,
235
- id: unique,
236
- className: classNames(disabled && 'disabled')
169
+ css: _AvatarContainerCSS
237
170
  }, jsx("div", {
171
+ ref: ref,
238
172
  css: _AvatarRootCSS,
239
173
  className: classNames('DGN-UI-Avatar', className),
240
174
  style: style,
@@ -247,14 +181,21 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
247
181
  onChange: onChangeAvatar,
248
182
  disabled: disabled
249
183
  }), jsx("div", {
184
+ ref: avatarRef,
250
185
  css: _AvatarPreviewCSS,
251
186
  onClick: _onClick,
252
- ref: avatarRef,
253
187
  onMouseEnter: _onMouseEnter,
254
188
  onMouseLeave: _onMouseLeave,
255
189
  tabIndex: "-1",
256
190
  onBlur: closeMoreInfo
257
- }, renderImage())), allowEdit && !readOnly && !disabled && jsx("span", {
191
+ }, jsx(Image, {
192
+ circular: true,
193
+ defaultSrc: defaultSrc,
194
+ src: srcState,
195
+ width: '100%',
196
+ height: '100%',
197
+ lazyLoading: lazyLoading
198
+ }))), allowEdit && !readOnly && !disabled ? jsx("span", {
258
199
  css: _ActionIconCSS
259
200
  }, jsx(ButtonIcon, {
260
201
  viewType: 'ghost',
@@ -263,7 +204,7 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
263
204
  height: actionIconHeight,
264
205
  className: 'icon-edit',
265
206
  onClick: triggerInput
266
- }), clearAble && srcState && jsx(ButtonIcon, {
207
+ }), clearAble && srcState ? jsx(ButtonIcon, {
267
208
  viewType: 'ghost',
268
209
  name: 'Delete',
269
210
  width: actionIconWidth,
@@ -273,68 +214,55 @@ const Avatar = /*#__PURE__*/memo( /*#__PURE__*/forwardRef(({
273
214
  style: {
274
215
  marginTop: '8px'
275
216
  }
276
- }))), jsx(ModalSample, {
217
+ }) : null) : null), jsx(ModalSample, {
277
218
  open: viewAvatar,
278
219
  onClose: () => setViewAvatar(false),
279
220
  width: 'max-content'
280
- }, jsx("img", {
281
- src: urlAvatar[unique],
282
- alt: "",
283
- style: {
284
- objectFit: 'cover',
285
- maxHeight: '100%',
286
- maxWidth: '100%',
287
- margin: 'auto',
288
- display: 'block'
289
- }
290
- })), hoverAble && jsx(Popover, {
221
+ }, jsx(Image, {
222
+ defaultSrc: defaultSrc,
223
+ src: srcState,
224
+ width: '100%',
225
+ height: '100%'
226
+ })), hoverAble ? jsx(Popover, {
291
227
  arrow: true,
292
228
  open: viewMoreInfo,
293
229
  pressESCToClose: false,
294
230
  bgColor: fillTooltip,
295
231
  anchor: avatarRef,
296
232
  fullScreen: false,
297
- width: 'max-content',
298
233
  direction: direction
299
234
  }, jsx("div", {
300
235
  css: MoreInfoCSS
301
- }, typeof data === 'function' ? data() : renderData())), !disabled && !readOnly && jsx(Popup, {
302
- ref: popupRef,
303
- type: 'danger'
236
+ }, typeof data === 'function' ? data() : renderData())) : null, jsx(Notify, {
237
+ ref: notifyRef,
238
+ progressing: true,
239
+ autoDisappear: true,
240
+ color: 'danger'
304
241
  }));
305
- }, [actionIconHeight, actionIconWidth, allowEdit, clearAble, data, defaultSrc, direction, disabled, height, hoverAble, lazyLoading, matchType, maxSize, maxSizeError, outlined, readOnly, width, isInView, onLoaded, srcState, viewAvatar, viewMoreInfo]);
242
+ }, [actionIconHeight, actionIconWidth, allowEdit, clearAble, data, defaultSrc, direction, disabled, height, hoverAble, lazyLoading, matchType, maxSize, maxSizeError, outlined, readOnly, width, srcState, viewAvatar, viewMoreInfo]);
306
243
  }));
307
244
  const ActionIconCSS = actionIconWidth => css`
245
+ ${displayFlex};
308
246
  ${flexCol};
309
247
  ${positionAbsolute};
248
+ ${parseMinWidth(actionIconWidth)};
310
249
  right: ${-actionIconWidth}px;
311
- min-width: ${actionIconWidth}px;
312
250
  transition: opacity 0.5s;
313
251
  opacity: 0;
314
- z-index: ${zIndexCORE(2)};
252
+ ${z(2)};
315
253
  `;
316
- const AvatarPreviewCSS = readOnly => css`
254
+ const AvatarPreviewCSS = isDisabled => css`
317
255
  ${displayBlock};
318
256
  ${positionRelative};
319
257
  ${overflowHidden};
320
- width: 100%;
321
- height: 100%;
322
- border-radius: 50%;
323
- cursor: ${readOnly ? 'initial' : 'pointer'};
258
+ ${parseWidthHeight('100%')};
259
+ ${borderRadius('50%')};
260
+ ${isDisabled ? cursorInherit : cursorPointer};
324
261
  `;
325
- const AvatarContainerCSS = (AvatarPreviewCSSName, ActionIconCSSName) => css`
262
+ const AvatarContainerCSS = ActionIconCSSName => css`
326
263
  ${displayInlineFlex};
327
264
  ${positionRelative};
328
265
  ${itemsCenter};
329
- &.disabled {
330
- .css-${AvatarPreviewCSSName} {
331
- ${pointerEventsNone}
332
- cursor: inherit;
333
- }
334
- .css-${ActionIconCSSName} {
335
- display: none !important;
336
- }
337
- }
338
266
  &:hover {
339
267
  .css-${ActionIconCSSName} {
340
268
  opacity: 1;
@@ -347,25 +275,18 @@ const AvatarRootCSS = (width, height, outlined) => css`
347
275
  ${overflowHidden};
348
276
  ${userSelectNone};
349
277
  ${borderNone};
278
+ ${boxContent};
350
279
  ${parseWidthHeight(width, height)};
351
- border: ${typeof outlined === 'boolean' && outlined ? `1px solid ${white}` : outlined};
352
- border-radius: 50%;
353
- box-sizing: content-box;
280
+ ${borderRadius('50%')};
281
+ border: ${typeof outlined === 'boolean' && outlined ? `1px solid ${systemWhite}` : outlined};
354
282
  input {
355
283
  ${displayNone};
356
284
  }
357
- img {
358
- width: 100%;
359
- height: 100%;
360
- }
361
285
  `;
362
286
  const MoreInfoCSS = css`
363
287
  ${displayBlock};
364
288
  ${positionRelative};
365
- padding: ${spacing([2])};
366
- `;
367
- const blurAnimationCSS = css`
368
- animation: ${blurKeyframe} 1s ease;
289
+ ${pd([2])};
369
290
  `;
370
291
  Avatar.defaultProps = {
371
292
  actionIconHeight: 24,
@@ -321,14 +321,14 @@ ButtonIcon.propTypes = {
321
321
  onClick: PropTypes.func,
322
322
  /** Name of [icon](https://core.diginet.com.vn/ui/?path=/story/icon-basic). */
323
323
  name: PropTypes.string,
324
- /**
325
- * The size of the component.
326
- *
327
- * * tiny (button 24px, icon 16px)
328
- * * small (button 32px, icon 20px)
329
- * * medium (button 40px, icon 24px)
330
- * * large (button 48px, icon 32px)
331
- * * giant (button 56px, icon 40px)
324
+ /**
325
+ * The size of the component.
326
+ *
327
+ * * tiny (button 24px, icon 16px)
328
+ * * small (button 32px, icon 20px)
329
+ * * medium (button 40px, icon 24px)
330
+ * * large (button 48px, icon 32px)
331
+ * * giant (button 56px, icon 40px)
332
332
  * */
333
333
  size: PropTypes.oneOf(['tiny', 'small', 'medium', 'large', 'giant', 'extraGiant']),
334
334
  /** Style inline of component. */
@@ -339,19 +339,19 @@ ButtonIcon.propTypes = {
339
339
  viewType: PropTypes.oneOf(['text', 'outlined', 'filled', 'ghost']),
340
340
  /** Width of the component. */
341
341
  width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
342
- /**
343
- * ref methods (ref.current.instance.*method*)
344
- *
345
- * * option(): Gets all UI component properties
346
- * * Returns value - object
347
- * * option(optionName): Gets the value of a single property
348
- * * @param {optionName} - string
349
- * * Returns value - any
350
- * * option(optionName, optionValue): Updates the value of a single property
351
- * * @param {optionName} - string
352
- * * @param {optionValue} - any
353
- * * option(options): Updates the values of several properties
354
- * * @param {options} - object
342
+ /**
343
+ * ref methods (ref.current.instance.*method*)
344
+ *
345
+ * * option(): Gets all UI component properties
346
+ * * Returns value - object
347
+ * * option(optionName): Gets the value of a single property
348
+ * * @param {optionName} - string
349
+ * * Returns value - any
350
+ * * option(optionName, optionValue): Updates the value of a single property
351
+ * * @param {optionName} - string
352
+ * * @param {optionValue} - any
353
+ * * option(options): Updates the values of several properties
354
+ * * @param {options} - object
355
355
  */
356
356
  reference: ref
357
357
  };