@snack-uikit/toaster 0.8.13 → 0.8.14-preview-b5e187d5.0

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.
Files changed (102) hide show
  1. package/dist/cjs/components/ToastSystemEvent/styles.module.css +3 -3
  2. package/dist/cjs/components/ToastUpload/ToastUpload.d.ts +19 -0
  3. package/dist/cjs/components/ToastUpload/ToastUpload.js +109 -0
  4. package/dist/cjs/components/ToastUpload/ToastUploadToaster.d.ts +3 -0
  5. package/dist/cjs/components/ToastUpload/ToastUploadToaster.js +16 -0
  6. package/dist/cjs/components/ToastUpload/components/ButtonAction/ButtonAction.d.ts +3 -0
  7. package/dist/cjs/components/ToastUpload/components/ButtonAction/ButtonAction.js +32 -0
  8. package/dist/cjs/components/ToastUpload/components/ButtonAction/index.d.ts +1 -0
  9. package/dist/cjs/components/ToastUpload/components/ButtonAction/index.js +25 -0
  10. package/dist/cjs/components/ToastUpload/components/ButtonAction/styles.module.css +30 -0
  11. package/dist/cjs/components/ToastUpload/components/FileItem/FileItem.d.ts +5 -0
  12. package/dist/cjs/components/ToastUpload/components/FileItem/FileItem.js +81 -0
  13. package/dist/cjs/components/ToastUpload/components/FileItem/index.d.ts +1 -0
  14. package/dist/cjs/components/ToastUpload/components/FileItem/index.js +25 -0
  15. package/dist/cjs/components/ToastUpload/components/FileItem/styles.module.css +85 -0
  16. package/dist/cjs/components/ToastUpload/components/LoadingStatus/LoadingStatus.d.ts +6 -0
  17. package/dist/cjs/components/ToastUpload/components/LoadingStatus/LoadingStatus.js +42 -0
  18. package/dist/cjs/components/ToastUpload/components/LoadingStatus/index.d.ts +1 -0
  19. package/dist/cjs/components/ToastUpload/components/LoadingStatus/index.js +25 -0
  20. package/dist/cjs/components/ToastUpload/components/LoadingStatus/styles.module.css +3 -0
  21. package/dist/cjs/components/ToastUpload/constants.d.ts +16 -0
  22. package/dist/cjs/components/ToastUpload/constants.js +26 -0
  23. package/dist/cjs/components/ToastUpload/index.d.ts +1 -0
  24. package/dist/cjs/components/ToastUpload/index.js +25 -0
  25. package/dist/cjs/components/ToastUpload/styles.module.css +103 -0
  26. package/dist/cjs/components/ToastUpload/types.d.ts +31 -0
  27. package/dist/cjs/components/ToastUpload/types.js +5 -0
  28. package/dist/cjs/components/ToastUpload/utils/formatPercent.d.ts +1 -0
  29. package/dist/cjs/components/ToastUpload/utils/formatPercent.js +8 -0
  30. package/dist/cjs/components/ToastUpload/utils/index.d.ts +1 -0
  31. package/dist/cjs/components/ToastUpload/utils/index.js +25 -0
  32. package/dist/cjs/components/ToasterContainer/styles.module.css +9 -9
  33. package/dist/cjs/components/index.d.ts +1 -0
  34. package/dist/cjs/components/index.js +2 -1
  35. package/dist/cjs/constants.d.ts +2 -4
  36. package/dist/cjs/constants.js +10 -2
  37. package/dist/cjs/helperComponents/ButtonAction/styles.module.css +2 -2
  38. package/dist/cjs/helpers.js +41 -1
  39. package/dist/cjs/types.d.ts +9 -1
  40. package/dist/esm/components/ToastSystemEvent/styles.module.css +3 -3
  41. package/dist/esm/components/ToastUpload/ToastUpload.d.ts +19 -0
  42. package/dist/esm/components/ToastUpload/ToastUpload.js +34 -0
  43. package/dist/esm/components/ToastUpload/ToastUploadToaster.d.ts +3 -0
  44. package/dist/esm/components/ToastUpload/ToastUploadToaster.js +7 -0
  45. package/dist/esm/components/ToastUpload/components/ButtonAction/ButtonAction.d.ts +3 -0
  46. package/dist/esm/components/ToastUpload/components/ButtonAction/ButtonAction.js +18 -0
  47. package/dist/esm/components/ToastUpload/components/ButtonAction/index.d.ts +1 -0
  48. package/dist/esm/components/ToastUpload/components/ButtonAction/index.js +1 -0
  49. package/dist/esm/components/ToastUpload/components/ButtonAction/styles.module.css +30 -0
  50. package/dist/esm/components/ToastUpload/components/FileItem/FileItem.d.ts +5 -0
  51. package/dist/esm/components/ToastUpload/components/FileItem/FileItem.js +22 -0
  52. package/dist/esm/components/ToastUpload/components/FileItem/index.d.ts +1 -0
  53. package/dist/esm/components/ToastUpload/components/FileItem/index.js +1 -0
  54. package/dist/esm/components/ToastUpload/components/FileItem/styles.module.css +85 -0
  55. package/dist/esm/components/ToastUpload/components/LoadingStatus/LoadingStatus.d.ts +6 -0
  56. package/dist/esm/components/ToastUpload/components/LoadingStatus/LoadingStatus.js +16 -0
  57. package/dist/esm/components/ToastUpload/components/LoadingStatus/index.d.ts +1 -0
  58. package/dist/esm/components/ToastUpload/components/LoadingStatus/index.js +1 -0
  59. package/dist/esm/components/ToastUpload/components/LoadingStatus/styles.module.css +3 -0
  60. package/dist/esm/components/ToastUpload/constants.d.ts +16 -0
  61. package/dist/esm/components/ToastUpload/constants.js +20 -0
  62. package/dist/esm/components/ToastUpload/index.d.ts +1 -0
  63. package/dist/esm/components/ToastUpload/index.js +1 -0
  64. package/dist/esm/components/ToastUpload/styles.module.css +103 -0
  65. package/dist/esm/components/ToastUpload/types.d.ts +31 -0
  66. package/dist/esm/components/ToastUpload/types.js +1 -0
  67. package/dist/esm/components/ToastUpload/utils/formatPercent.d.ts +1 -0
  68. package/dist/esm/components/ToastUpload/utils/formatPercent.js +1 -0
  69. package/dist/esm/components/ToastUpload/utils/index.d.ts +1 -0
  70. package/dist/esm/components/ToastUpload/utils/index.js +1 -0
  71. package/dist/esm/components/ToasterContainer/styles.module.css +9 -9
  72. package/dist/esm/components/index.d.ts +1 -0
  73. package/dist/esm/components/index.js +1 -0
  74. package/dist/esm/constants.d.ts +2 -4
  75. package/dist/esm/constants.js +8 -0
  76. package/dist/esm/helperComponents/ButtonAction/styles.module.css +2 -2
  77. package/dist/esm/helpers.js +38 -0
  78. package/dist/esm/types.d.ts +9 -1
  79. package/package.json +6 -5
  80. package/src/components/ToastSystemEvent/styles.module.scss +2 -2
  81. package/src/components/ToastUpload/ToastUpload.tsx +108 -0
  82. package/src/components/ToastUpload/ToastUploadToaster.tsx +11 -0
  83. package/src/components/ToastUpload/components/ButtonAction/ButtonAction.tsx +10 -0
  84. package/src/components/ToastUpload/components/ButtonAction/index.ts +1 -0
  85. package/src/components/ToastUpload/components/ButtonAction/styles.module.scss +45 -0
  86. package/src/components/ToastUpload/components/FileItem/FileItem.tsx +74 -0
  87. package/src/components/ToastUpload/components/FileItem/index.ts +1 -0
  88. package/src/components/ToastUpload/components/FileItem/styles.module.scss +93 -0
  89. package/src/components/ToastUpload/components/LoadingStatus/LoadingStatus.tsx +38 -0
  90. package/src/components/ToastUpload/components/LoadingStatus/index.ts +1 -0
  91. package/src/components/ToastUpload/components/LoadingStatus/styles.module.scss +8 -0
  92. package/src/components/ToastUpload/constants.ts +26 -0
  93. package/src/components/ToastUpload/index.ts +1 -0
  94. package/src/components/ToastUpload/styles.module.scss +113 -0
  95. package/src/components/ToastUpload/types.ts +39 -0
  96. package/src/components/ToastUpload/utils/formatPercent.ts +1 -0
  97. package/src/components/ToastUpload/utils/index.ts +1 -0
  98. package/src/components/ToasterContainer/styles.module.scss +1 -1
  99. package/src/components/index.ts +1 -0
  100. package/src/constants.ts +9 -1
  101. package/src/helpers.tsx +35 -0
  102. package/src/types.ts +7 -1
@@ -0,0 +1,108 @@
1
+ import cn from 'classnames';
2
+ import { MouseEvent } from 'react';
3
+ import { ToastContentProps as RtToastContentProps } from 'react-toastify';
4
+
5
+ import { ChevronDownSVG, ChevronUpSVG, CrossSVG } from '@snack-uikit/icons';
6
+ import { ProgressBar } from '@snack-uikit/progress-bar';
7
+ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
8
+
9
+ import { ButtonAction } from './components/ButtonAction';
10
+ import { FileItem } from './components/FileItem';
11
+ import { LoadingStatus } from './components/LoadingStatus';
12
+ import { progressBarAppearanceByStatus } from './constants';
13
+ import styles from './styles.module.scss';
14
+ import { ToastUploadStatus, UploadActions, UploadItem } from './types';
15
+ import { formatPercent } from './utils';
16
+
17
+ export type ToastUploadProps = Partial<RtToastContentProps> &
18
+ WithSupportProps<{
19
+ status: ToastUploadStatus;
20
+ title: string;
21
+ description: string;
22
+ totalProgressCounter: string;
23
+ totalProgressPercentage: number;
24
+ onCloseClick?(e: MouseEvent<HTMLButtonElement>, close?: () => void): void;
25
+ closable?: boolean;
26
+ className?: string;
27
+ items: UploadItem[];
28
+ collapsed: boolean;
29
+ onCollapsed: (collapsed: boolean) => void;
30
+ generalActions: UploadActions;
31
+ }>;
32
+
33
+ export function ToastUpload({
34
+ status,
35
+ title,
36
+ description,
37
+ totalProgressCounter,
38
+ totalProgressPercentage,
39
+ closeToast,
40
+ onCloseClick,
41
+ closable,
42
+ className,
43
+ items,
44
+ collapsed,
45
+ onCollapsed,
46
+ generalActions,
47
+ ...rest
48
+ }: ToastUploadProps) {
49
+ const handleCloseClick = (e: MouseEvent<HTMLButtonElement>) => {
50
+ e.stopPropagation();
51
+ onCloseClick ? onCloseClick(e, closeToast) : closeToast?.();
52
+ };
53
+
54
+ const handleCollapseClick = (e: MouseEvent<HTMLButtonElement>) => {
55
+ e.stopPropagation();
56
+ onCollapsed(!collapsed);
57
+ };
58
+
59
+ return (
60
+ <div className={cn(styles.container, className)} {...extractSupportProps(rest)}>
61
+ <div className={styles.titleLine}>
62
+ <div className={styles.titleLineBody}>
63
+ <div className={styles.title}>{title}</div>
64
+
65
+ <ButtonAction onClick={handleCollapseClick}>{collapsed ? <ChevronUpSVG /> : <ChevronDownSVG />}</ButtonAction>
66
+
67
+ {closable && (
68
+ <ButtonAction type='button' className={styles.buttonAction} onClick={handleCloseClick}>
69
+ <CrossSVG />
70
+ </ButtonAction>
71
+ )}
72
+ </div>
73
+
74
+ <div className={styles.generalProgress}>
75
+ <div className={styles.statusLine}>
76
+ <div className={styles.statusWrap}>
77
+ <LoadingStatus status={status} actions={generalActions} />
78
+
79
+ <span className={styles.description} data-status={status}>
80
+ {description}
81
+ </span>
82
+ </div>
83
+
84
+ <span className={styles.totalCounter}>{totalProgressCounter}</span>
85
+
86
+ <span className={styles.totalPercentage}>{formatPercent(totalProgressPercentage)}</span>
87
+ </div>
88
+
89
+ {!collapsed && (
90
+ <ProgressBar
91
+ progress={totalProgressPercentage}
92
+ size='xs'
93
+ appearance={progressBarAppearanceByStatus[status]}
94
+ />
95
+ )}
96
+ </div>
97
+ </div>
98
+
99
+ {collapsed && (
100
+ <div className={styles.list}>
101
+ {items.map(item => (
102
+ <FileItem key={item.id} item={item} />
103
+ ))}
104
+ </div>
105
+ )}
106
+ </div>
107
+ );
108
+ }
@@ -0,0 +1,11 @@
1
+ import { useState } from 'react';
2
+
3
+ import { ToastUpload, ToastUploadProps } from './ToastUpload';
4
+
5
+ export type ToastUploadToasterProps = Omit<ToastUploadProps, 'collapsed' | 'onCollapsed'>;
6
+
7
+ export function ToastUploadForToaster(props: ToastUploadToasterProps) {
8
+ const [collapsed, setCollapsed] = useState(true);
9
+
10
+ return <ToastUpload {...props} collapsed={collapsed} onCollapsed={setCollapsed} />;
11
+ }
@@ -0,0 +1,10 @@
1
+ import cn from 'classnames';
2
+ import { ButtonHTMLAttributes } from 'react';
3
+
4
+ import styles from './styles.module.scss';
5
+
6
+ export type ButtonActionProps = ButtonHTMLAttributes<HTMLButtonElement>;
7
+
8
+ export function ButtonAction({ className, ...props }: ButtonActionProps) {
9
+ return <button type='button' className={cn(styles.buttonAction, className)} {...props}></button>;
10
+ }
@@ -0,0 +1 @@
1
+ export * from './ButtonAction';
@@ -0,0 +1,45 @@
1
+ /* stylelint-disable scss/operator-no-newline-after */
2
+
3
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterSystemEvent';
4
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterUpload';
5
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
6
+ @use '@snack-uikit/figma-tokens/build/scss/styles-theme-variables';
7
+
8
+ .buttonAction {
9
+ cursor: pointer;
10
+
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+
15
+ box-sizing: border-box;
16
+ margin: 0;
17
+ padding: 0;
18
+
19
+ color: styles-theme-variables.$sys-invert-neutral-text-light;
20
+
21
+ background-color: transparent;
22
+ border: none;
23
+
24
+ svg {
25
+ width: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
26
+ height: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
27
+ }
28
+
29
+ &:hover {
30
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
31
+ }
32
+
33
+ &:focus,
34
+ &:active {
35
+ color: styles-theme-variables.$sys-invert-neutral-accent-pressed;
36
+ }
37
+
38
+ &:focus-visible {
39
+ @include styles-theme-variables.outline-var(styles-tokens-element.$container-focused-s);
40
+
41
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
42
+ outline-color: styles-theme-variables.$sys-available-on-complementary;
43
+ outline-offset: styles-theme-variables.$spacing-state-focus-offset;
44
+ }
45
+ }
@@ -0,0 +1,74 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import { CrossSVG } from '@snack-uikit/icons';
4
+ import { Link } from '@snack-uikit/link';
5
+ import { ProgressBar } from '@snack-uikit/progress-bar';
6
+
7
+ import { progressBarAppearanceByStatus } from '../../constants';
8
+ import { UploadItem } from '../../types';
9
+ import { formatPercent } from '../../utils';
10
+ import { ButtonAction } from '../ButtonAction';
11
+ import { LoadingStatus } from '../LoadingStatus';
12
+ import styles from './styles.module.scss';
13
+
14
+ export type FileItemProps = { item: UploadItem };
15
+
16
+ export function FileItem({ item: initItem }: FileItemProps) {
17
+ const [item, setItem] = useState(initItem);
18
+
19
+ const showLink = item.status === 'uploaded' && item.link;
20
+
21
+ useEffect(() => {
22
+ if (initItem.subscribeToState) {
23
+ return initItem.subscribeToState(newValue => setItem(prev => ({ ...prev, ...newValue })));
24
+ }
25
+
26
+ return setItem(initItem);
27
+ }, [initItem]);
28
+
29
+ return (
30
+ <div className={styles.fileLine} key={item.id}>
31
+ <div className={styles.fileHeadLine}>
32
+ <span className={styles.fileTitle}>{item.title}</span>
33
+
34
+ {showLink && (
35
+ <Link
36
+ text={item.link?.text}
37
+ href={item.link?.href}
38
+ size='m'
39
+ truncateVariant='end'
40
+ onClick={item.link?.onClick}
41
+ appearance='invert-neutral'
42
+ textMode='accent'
43
+ />
44
+ )}
45
+
46
+ {!showLink && (
47
+ <ButtonAction onClick={item.actions.onCancel}>
48
+ <CrossSVG />
49
+ </ButtonAction>
50
+ )}
51
+ </div>
52
+
53
+ <ProgressBar progress={item.progress} size='xs' appearance={progressBarAppearanceByStatus[item.status]} />
54
+
55
+ <div className={styles.fileStatusLine}>
56
+ <div className={styles.fileStatusWrap}>
57
+ <LoadingStatus status={item.status} actions={item.actions} />
58
+
59
+ <span className={styles.fileStatusDescription} data-status={item.status}>
60
+ {item.statusLabel}
61
+ </span>
62
+ </div>
63
+
64
+ <span className={styles.fileSize} data-status={item.status}>
65
+ {item.size}
66
+ </span>
67
+
68
+ <span className={styles.fileStatusPercentage} data-status={item.status}>
69
+ {formatPercent(item.progress)}
70
+ </span>
71
+ </div>
72
+ </div>
73
+ );
74
+ }
@@ -0,0 +1 @@
1
+ export * from './FileItem';
@@ -0,0 +1,93 @@
1
+ /* stylelint-disable scss/operator-no-newline-after */
2
+
3
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterSystemEvent';
4
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterUpload';
5
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
6
+ @use '@snack-uikit/figma-tokens/build/scss/styles-theme-variables';
7
+
8
+ .fileLine {
9
+ @include styles-theme-variables.composite-var(
10
+ styles-tokens-toaster-toasterUpload.$toaster-upload-file-line-container
11
+ );
12
+
13
+ display: flex;
14
+ flex-direction: column;
15
+ }
16
+
17
+ .fileHeadLine {
18
+ @include styles-theme-variables.composite-var(
19
+ styles-tokens-toaster-toasterUpload.$toaster-upload-file-line-headline
20
+ );
21
+
22
+ display: flex;
23
+ align-items: center;
24
+ }
25
+
26
+ .fileTitle {
27
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-s);
28
+
29
+ flex-grow: 1;
30
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
31
+ }
32
+
33
+
34
+ .fileStatusLine {
35
+ @include styles-theme-variables.composite-var(
36
+ styles-tokens-toaster-toasterUpload.$toaster-upload-status-line-container
37
+ );
38
+
39
+ display: flex;
40
+ align-items: center;
41
+ }
42
+
43
+ .fileStatusWrap {
44
+ @include styles-theme-variables.composite-var(
45
+ styles-tokens-toaster-toasterUpload.$toaster-upload-status-line-status-wrap
46
+ );
47
+
48
+ display: flex;
49
+ flex-grow: 1;
50
+ align-items: center;
51
+ }
52
+
53
+ .fileStatusDescription {
54
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-s);
55
+
56
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
57
+
58
+ &[data-status='loading'] {
59
+ color: styles-theme-variables.$sys-invert-neutral-text-disabled;
60
+ }
61
+
62
+ &[data-status='uploaded'] {
63
+ color: styles-theme-variables.$sys-invert-neutral-text-disabled;
64
+ }
65
+ }
66
+
67
+ .fileSize {
68
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-s);
69
+
70
+ color: styles-theme-variables.$sys-invert-neutral-text-disabled;
71
+
72
+ &[data-status='loading'] {
73
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
74
+ }
75
+
76
+ &[data-status='uploaded'] {
77
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
78
+ }
79
+ }
80
+
81
+ .fileStatusPercentage {
82
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-s);
83
+
84
+ color: styles-theme-variables.$sys-invert-neutral-text-disabled;
85
+
86
+ &[data-status='loading'] {
87
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
88
+ }
89
+
90
+ &[data-status='uploaded'] {
91
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
92
+ }
93
+ }
@@ -0,0 +1,38 @@
1
+ import { CheckFilledSVG, PauseSVG, PlaySVG, UpdateSVG } from '@snack-uikit/icons';
2
+
3
+ import { ToastUploadStatus, UploadActions } from '../../types';
4
+ import { ButtonAction } from '../ButtonAction';
5
+ import styles from './styles.module.scss';
6
+
7
+ export type LoadingStatusProps = {
8
+ status: ToastUploadStatus;
9
+ actions: UploadActions;
10
+ };
11
+
12
+ export function LoadingStatus({ status, actions }: LoadingStatusProps) {
13
+ if (status === 'loading') {
14
+ return (
15
+ <ButtonAction onClick={actions.onPause}>
16
+ <PauseSVG />
17
+ </ButtonAction>
18
+ );
19
+ }
20
+
21
+ if (status === 'pause') {
22
+ return (
23
+ <ButtonAction onClick={actions.onContinue}>
24
+ <PlaySVG />
25
+ </ButtonAction>
26
+ );
27
+ }
28
+
29
+ if (status === 'uploaded') {
30
+ return <CheckFilledSVG className={styles.successIcon} />;
31
+ }
32
+
33
+ return (
34
+ <ButtonAction onClick={actions.onRetry}>
35
+ <UpdateSVG />
36
+ </ButtonAction>
37
+ );
38
+ }
@@ -0,0 +1 @@
1
+ export * from './LoadingStatus';
@@ -0,0 +1,8 @@
1
+ /* stylelint-disable scss/operator-no-newline-after */
2
+
3
+ @use '@snack-uikit/figma-tokens/build/scss/styles-theme-variables';
4
+
5
+
6
+ .successIcon {
7
+ color: styles-theme-variables.$sys-green-accent-default;
8
+ }
@@ -0,0 +1,26 @@
1
+ import { ProgressBarProps } from '@snack-uikit/progress-bar';
2
+
3
+ import { ToastUploadStatus } from './types';
4
+
5
+ export const TOAST_UPLOAD_STATUS = {
6
+ Loading: 'loading',
7
+ Pause: 'pause',
8
+ Error: 'error',
9
+ Uploaded: 'uploaded',
10
+ ErrorUploaded: 'errorUploaded',
11
+ } as const;
12
+
13
+ export const TOAST_UPLOAD_ITEM_STATUS = {
14
+ Loading: 'loading',
15
+ Pause: 'pause',
16
+ Error: 'error',
17
+ Uploaded: 'uploaded',
18
+ } as const;
19
+
20
+ export const progressBarAppearanceByStatus: Record<ToastUploadStatus, ProgressBarProps['appearance']> = {
21
+ pause: 'neutral',
22
+ loading: 'green',
23
+ uploaded: 'green',
24
+ errorUploaded: 'red',
25
+ error: 'red',
26
+ };
@@ -0,0 +1 @@
1
+ export * from './ToastUpload';
@@ -0,0 +1,113 @@
1
+ /* stylelint-disable scss/operator-no-newline-after */
2
+
3
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterSystemEvent';
4
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-toaster-toasterUpload';
5
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
6
+ @use '@snack-uikit/figma-tokens/build/scss/styles-theme-variables';
7
+
8
+ .container {
9
+ @include styles-theme-variables.composite-var(styles-tokens-toaster-toasterUpload.$toaster-upload-toast-container);
10
+
11
+ cursor: default;
12
+
13
+ position: relative;
14
+
15
+ overflow: hidden;
16
+ display: flex;
17
+ flex-direction: column;
18
+
19
+ box-sizing: border-box;
20
+ width: calc(
21
+ styles-tokens-toaster-toasterSystemEvent.$size-toaster-toast-system-event-container -
22
+ (2 * styles-tokens-toaster-toasterUpload.$space-toaster-toast-system-event-container-padding)
23
+ );
24
+ max-width: 100%;
25
+ max-height: 386px;
26
+ padding: styles-tokens-toaster-toasterUpload.$space-toaster-toast-system-event-container-padding 0;
27
+
28
+ background-color: styles-theme-variables.$sys-invert-neutral-background;
29
+ }
30
+
31
+ .titleLine {
32
+ display: flex;
33
+ flex-direction: column;
34
+ padding: 0 styles-tokens-toaster-toasterUpload.$space-toaster-toast-system-event-container-padding;
35
+ }
36
+
37
+ .titleLineBody {
38
+ @include styles-theme-variables.composite-var(styles-tokens-toaster-toasterUpload.$toaster-upload-title-line-body);
39
+
40
+ display: flex;
41
+ align-items: center;
42
+ }
43
+
44
+ .title {
45
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-title-s);
46
+
47
+ flex-grow: 1;
48
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
49
+ }
50
+
51
+ .generalProgress {
52
+ @include styles-theme-variables.composite-var(
53
+ styles-tokens-toaster-toasterUpload.$toaster-upload-title-line-general-progress
54
+ );
55
+
56
+ display: flex;
57
+ flex-direction: column;
58
+ align-self: stretch;
59
+ }
60
+
61
+ .statusLine {
62
+ @include styles-theme-variables.composite-var(
63
+ styles-tokens-toaster-toasterUpload.$toaster-upload-status-line-container
64
+ );
65
+
66
+ display: flex;
67
+ align-items: center;
68
+ }
69
+
70
+ .statusWrap {
71
+ @include styles-theme-variables.composite-var(
72
+ styles-tokens-toaster-toasterUpload.$toaster-upload-status-line-status-wrap
73
+ );
74
+
75
+ display: flex;
76
+ flex-grow: 1;
77
+ align-items: center;
78
+ }
79
+
80
+ .description {
81
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-m);
82
+
83
+ color: styles-theme-variables.$sys-invert-neutral-text-main;
84
+
85
+ &[data-status='loading'] {
86
+ color: styles-theme-variables.$sys-invert-neutral-text-light;
87
+ }
88
+
89
+ &[data-status='uploaded'] {
90
+ color: styles-theme-variables.$sys-invert-neutral-text-light;
91
+ }
92
+ }
93
+
94
+ .totalCounter {
95
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-m);
96
+
97
+ color: styles-theme-variables.$sys-invert-neutral-text-support;
98
+ }
99
+
100
+ .totalPercentage {
101
+ @include styles-theme-variables.composite-var(styles-theme-variables.$sans-body-m);
102
+
103
+ color: styles-theme-variables.$sys-invert-neutral-text-support;
104
+ }
105
+
106
+ .list {
107
+ overflow: scroll;
108
+ display: flex;
109
+ flex-direction: column;
110
+
111
+ max-height: 280px;
112
+ padding: 0 styles-tokens-toaster-toasterUpload.$space-toaster-toast-system-event-container-padding;
113
+ }
@@ -0,0 +1,39 @@
1
+ import { MouseEvent } from 'react';
2
+
3
+ import { ProgressBarProps } from '@snack-uikit/progress-bar';
4
+ import { ValueOf } from '@snack-uikit/utils';
5
+
6
+ import { TOAST_UPLOAD_ITEM_STATUS, TOAST_UPLOAD_STATUS } from './constants';
7
+
8
+ export type ToastUploadStatus = ValueOf<typeof TOAST_UPLOAD_STATUS>;
9
+
10
+ export type ToastUploadItemStatus = ValueOf<typeof TOAST_UPLOAD_ITEM_STATUS>;
11
+
12
+ export type ToastUploadStateSubscription<T> = (subscription: (newValue: T) => void) => () => void;
13
+ export type WithStateSubscription<T> = {
14
+ subscribeToState?: ToastUploadStateSubscription<Partial<T>>;
15
+ } & T;
16
+
17
+ export type ToastUploadItemLink = {
18
+ text: string;
19
+ href: string;
20
+ onClick?(e: MouseEvent<HTMLAnchorElement>): void;
21
+ };
22
+
23
+ export type UploadActions = {
24
+ onCancel?: () => void;
25
+ onPause?: () => void;
26
+ onRetry?: () => void;
27
+ onContinue?: () => void;
28
+ };
29
+
30
+ export type UploadItem = WithStateSubscription<{
31
+ id: string;
32
+ title: string;
33
+ status: ToastUploadItemStatus;
34
+ statusLabel: string;
35
+ progress: ProgressBarProps['progress'];
36
+ size: string;
37
+ actions: UploadActions;
38
+ link?: ToastUploadItemLink;
39
+ }>;
@@ -0,0 +1 @@
1
+ export const formatPercent = (value: number) => `${value}%`;
@@ -0,0 +1 @@
1
+ export * from './formatPercent';
@@ -61,7 +61,7 @@
61
61
  }
62
62
 
63
63
  .containerWithCloseAllButton {
64
- margin-bottom: calc(styles-theme-variables.$size-toaster-button-close-column + styles-theme-variables.$space-toaster-system-event-gap);
64
+ margin-bottom: calc(styles-theme-variables.$size-toaster-button-close-column + styles-theme-variables.$space-toaster-toast-system-event-gap);
65
65
  }
66
66
 
67
67
  @media only screen and (max-width: 480px) {
@@ -1,3 +1,4 @@
1
1
  export * from './ToastSystemEvent';
2
2
  export * from './ToastUserAction';
3
3
  export * from './ToasterContainer';
4
+ export * from './ToastUpload';
package/src/constants.ts CHANGED
@@ -4,6 +4,7 @@ import { ToasterType } from './types';
4
4
  export const TOASTER_TYPE = {
5
5
  SystemEvent: 'system-event',
6
6
  UserAction: 'user-action',
7
+ Upload: 'upload',
7
8
  } as const;
8
9
 
9
10
  export const TOASTER_CONTAINER_DEFAULT_PROPS: Record<ToasterType, ToasterContainerProps> = {
@@ -19,11 +20,18 @@ export const TOASTER_CONTAINER_DEFAULT_PROPS: Record<ToasterType, ToasterContain
19
20
  displayCloseAllButton: false,
20
21
  type: TOASTER_TYPE.UserAction,
21
22
  },
23
+ [TOASTER_TYPE.Upload]: {
24
+ limit: 5,
25
+ position: 'bottom-right',
26
+ displayCloseAllButton: true,
27
+ type: TOASTER_TYPE.SystemEvent,
28
+ },
22
29
  };
23
30
 
24
- export const AUTO_CLOSE_TIME = {
31
+ export const AUTO_CLOSE_TIME: Record<ToasterType, number | false> = {
25
32
  [TOASTER_TYPE.SystemEvent]: 5000,
26
33
  [TOASTER_TYPE.UserAction]: 2000,
34
+ [TOASTER_TYPE.Upload]: false,
27
35
  };
28
36
 
29
37
  export const TOASTER_ROOT_ID = 'toaster-root';