wini-web-components 2.8.5 → 2.8.8

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 (128) hide show
  1. package/dist/index.js.js +9 -9
  2. package/dist/index.js.mjs +745 -895
  3. package/package.json +3 -5
  4. package/dist/component/button/button.d.ts +0 -22
  5. package/dist/component/button/button.d.ts.map +0 -1
  6. package/dist/component/calendar/calendar.d.ts +0 -31
  7. package/dist/component/calendar/calendar.d.ts.map +0 -1
  8. package/dist/component/carousel/carousel.d.ts +0 -32
  9. package/dist/component/carousel/carousel.d.ts.map +0 -1
  10. package/dist/component/checkbox/checkbox.d.ts +0 -25
  11. package/dist/component/checkbox/checkbox.d.ts.map +0 -1
  12. package/dist/component/ck-editor/ckeditor.d.ts +0 -36
  13. package/dist/component/ck-editor/ckeditor.d.ts.map +0 -1
  14. package/dist/component/component-status.d.ts +0 -8
  15. package/dist/component/component-status.d.ts.map +0 -1
  16. package/dist/component/date-time-picker/date-time-picker.d.ts +0 -36
  17. package/dist/component/date-time-picker/date-time-picker.d.ts.map +0 -1
  18. package/dist/component/dialog/dialog.d.ts +0 -18
  19. package/dist/component/dialog/dialog.d.ts.map +0 -1
  20. package/dist/component/import-file/import-file.d.ts +0 -34
  21. package/dist/component/import-file/import-file.d.ts.map +0 -1
  22. package/dist/component/infinite-scroll/infinite-scroll.d.ts +0 -18
  23. package/dist/component/infinite-scroll/infinite-scroll.d.ts.map +0 -1
  24. package/dist/component/input-multi-select/input-multi-select.d.ts +0 -22
  25. package/dist/component/input-multi-select/input-multi-select.d.ts.map +0 -1
  26. package/dist/component/input-otp/input-otp.d.ts +0 -23
  27. package/dist/component/input-otp/input-otp.d.ts.map +0 -1
  28. package/dist/component/number-picker/number-picker.d.ts +0 -24
  29. package/dist/component/number-picker/number-picker.d.ts.map +0 -1
  30. package/dist/component/pagination/pagination.d.ts +0 -14
  31. package/dist/component/pagination/pagination.d.ts.map +0 -1
  32. package/dist/component/popup/popup.d.ts +0 -40
  33. package/dist/component/popup/popup.d.ts.map +0 -1
  34. package/dist/component/progress-bar/progress-bar.d.ts +0 -16
  35. package/dist/component/progress-bar/progress-bar.d.ts.map +0 -1
  36. package/dist/component/progress-circle/progress-circle.d.ts +0 -13
  37. package/dist/component/progress-circle/progress-circle.d.ts.map +0 -1
  38. package/dist/component/radio-button/radio-button.d.ts +0 -21
  39. package/dist/component/radio-button/radio-button.d.ts.map +0 -1
  40. package/dist/component/rating/rating.d.ts +0 -24
  41. package/dist/component/rating/rating.d.ts.map +0 -1
  42. package/dist/component/select1/select1.d.ts +0 -32
  43. package/dist/component/select1/select1.d.ts.map +0 -1
  44. package/dist/component/switch/switch.d.ts +0 -24
  45. package/dist/component/switch/switch.d.ts.map +0 -1
  46. package/dist/component/table/table.d.ts +0 -51
  47. package/dist/component/table/table.d.ts.map +0 -1
  48. package/dist/component/tag/tag.d.ts +0 -23
  49. package/dist/component/tag/tag.d.ts.map +0 -1
  50. package/dist/component/text/text.d.ts +0 -16
  51. package/dist/component/text/text.d.ts.map +0 -1
  52. package/dist/component/text-area/text-area.d.ts +0 -28
  53. package/dist/component/text-area/text-area.d.ts.map +0 -1
  54. package/dist/component/text-field/text-field.d.ts +0 -37
  55. package/dist/component/text-field/text-field.d.ts.map +0 -1
  56. package/dist/component/toast-noti/toast-noti.d.ts +0 -5
  57. package/dist/component/toast-noti/toast-noti.d.ts.map +0 -1
  58. package/dist/component/wini-icon/winicon.d.ts +0 -27
  59. package/dist/component/wini-icon/winicon.d.ts.map +0 -1
  60. package/dist/form/login/view.d.ts +0 -41
  61. package/dist/form/login/view.d.ts.map +0 -1
  62. package/dist/index.d.ts +0 -34
  63. package/dist/index.d.ts.map +0 -1
  64. package/dist/language/i18n.d.ts +0 -3
  65. package/dist/language/i18n.d.ts.map +0 -1
  66. package/src/component/button/button.module.css +0 -210
  67. package/src/component/button/button.tsx +0 -57
  68. package/src/component/calendar/calendar.module.css +0 -153
  69. package/src/component/calendar/calendar.tsx +0 -389
  70. package/src/component/carousel/carousel.css +0 -622
  71. package/src/component/carousel/carousel.tsx +0 -91
  72. package/src/component/checkbox/checkbox.module.css +0 -48
  73. package/src/component/checkbox/checkbox.tsx +0 -80
  74. package/src/component/ck-editor/ck-editor.css +0 -206
  75. package/src/component/ck-editor/ckeditor.tsx +0 -522
  76. package/src/component/component-status.tsx +0 -53
  77. package/src/component/date-time-picker/date-time-picker.module.css +0 -94
  78. package/src/component/date-time-picker/date-time-picker.tsx +0 -663
  79. package/src/component/dialog/dialog.module.css +0 -111
  80. package/src/component/dialog/dialog.tsx +0 -109
  81. package/src/component/import-file/import-file.module.css +0 -83
  82. package/src/component/import-file/import-file.tsx +0 -174
  83. package/src/component/infinite-scroll/infinite-scroll.module.css +0 -34
  84. package/src/component/infinite-scroll/infinite-scroll.tsx +0 -35
  85. package/src/component/input-multi-select/input-multi-select.module.css +0 -121
  86. package/src/component/input-multi-select/input-multi-select.tsx +0 -263
  87. package/src/component/input-otp/input-otp.module.css +0 -41
  88. package/src/component/input-otp/input-otp.tsx +0 -110
  89. package/src/component/number-picker/number-picker.module.css +0 -137
  90. package/src/component/number-picker/number-picker.tsx +0 -107
  91. package/src/component/pagination/pagination.module.css +0 -48
  92. package/src/component/pagination/pagination.tsx +0 -88
  93. package/src/component/popup/popup.css +0 -136
  94. package/src/component/popup/popup.tsx +0 -125
  95. package/src/component/progress-bar/progress-bar.module.css +0 -42
  96. package/src/component/progress-bar/progress-bar.tsx +0 -33
  97. package/src/component/progress-circle/progress-circle.css +0 -0
  98. package/src/component/progress-circle/progress-circle.tsx +0 -25
  99. package/src/component/radio-button/radio-button.module.css +0 -51
  100. package/src/component/radio-button/radio-button.tsx +0 -60
  101. package/src/component/rating/rating.module.css +0 -11
  102. package/src/component/rating/rating.tsx +0 -65
  103. package/src/component/select1/select1.module.css +0 -108
  104. package/src/component/select1/select1.tsx +0 -271
  105. package/src/component/switch/switch.module.css +0 -53
  106. package/src/component/switch/switch.tsx +0 -68
  107. package/src/component/table/table.css +0 -74
  108. package/src/component/table/table.tsx +0 -108
  109. package/src/component/tag/tag.module.css +0 -108
  110. package/src/component/tag/tag.tsx +0 -31
  111. package/src/component/text/text.css +0 -27
  112. package/src/component/text/text.tsx +0 -24
  113. package/src/component/text-area/text-area.module.css +0 -57
  114. package/src/component/text-area/text-area.tsx +0 -65
  115. package/src/component/text-field/text-field.module.css +0 -71
  116. package/src/component/text-field/text-field.tsx +0 -102
  117. package/src/component/toast-noti/toast-noti.css +0 -866
  118. package/src/component/toast-noti/toast-noti.tsx +0 -22
  119. package/src/component/wini-icon/winicon.module.css +0 -110
  120. package/src/component/wini-icon/winicon.tsx +0 -9424
  121. package/src/form/login/view.module.css +0 -80
  122. package/src/form/login/view.tsx +0 -138
  123. package/src/index.tsx +0 -66
  124. package/src/language/i18n.tsx +0 -143
  125. package/src/skin/layout.css +0 -649
  126. package/src/skin/root.css +0 -294
  127. package/src/skin/typography.css +0 -314
  128. package/src/vite-env.d.ts +0 -1
@@ -1,111 +0,0 @@
1
- .dialog-overlay {
2
- position: fixed;
3
- top: 0;
4
- left: 0;
5
- width: 100dvw;
6
- height: 100dvh;
7
- background-color: rgba(0, 0, 0, 0.5);
8
- display: flex;
9
- justify-content: center;
10
- align-items: center;
11
- z-index: 100;
12
- }
13
-
14
- .dialog-container {
15
- position: relative;
16
- background-color: var(--neutral-absolute-background-color);
17
- padding: 2.4rem;
18
- border-radius: 8px;
19
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
20
- gap: 2.4rem;
21
- overflow: visible;
22
- }
23
-
24
- .dialog-container button {
25
- outline: none;
26
- padding: 0;
27
- border: none;
28
- }
29
-
30
- .dialog-body {
31
- gap: 1.6rem;
32
- }
33
-
34
- .dialog-body>div:last-child {
35
- width: 100%;
36
- align-items: inherit;
37
- gap: 8px;
38
- }
39
-
40
- .dialog-body>div:last-child>* {
41
- width: 100%;
42
- }
43
-
44
- .dialog-body>.dialog-status {
45
- width: 5.6rem;
46
- height: 5.6rem;
47
- border-radius: 50%;
48
- align-items: center;
49
- justify-content: center;
50
- }
51
-
52
- .dialog-footer {
53
- gap: 8px;
54
- justify-content: end;
55
- width: 100%;
56
- }
57
-
58
- .dialog-footer>.dialog-action {
59
- height: 4rem;
60
- justify-content: center;
61
- padding: 0 1.6rem;
62
- border-radius: 0.8rem;
63
- background-color: var(--neutral-main-background-color);
64
- }
65
-
66
- .dialog-footer>.dialog-action>* {
67
- color: var(--neutral-text-subtitle-color);
68
- }
69
-
70
- .dialog-footer>.dialog-submit>* {
71
- color: var(--neutral-text-title-reverse-color);
72
- }
73
-
74
- /*
75
- INFOR = 1
76
- ERROR = 2
77
- WARNING = 3
78
- SUCCSESS = 4
79
- */
80
-
81
- .dialog-container[dialog-type="1"] .dialog-status {
82
- background-color: var(--infor-background);
83
- }
84
-
85
- .dialog-container[dialog-type="2"] .dialog-status {
86
- background-color: var(--error-background);
87
- }
88
-
89
- .dialog-container[dialog-type="3"] .dialog-status {
90
- background-color: var(--warning-background);
91
- }
92
-
93
- .dialog-container[dialog-type="4"] .dialog-status {
94
- background-color: var(--success-background);
95
- }
96
-
97
- .dialog-container[dialog-type="1"] .dialog-footer>.dialog-submit {
98
- background-color: var(--infor-main-color);
99
- }
100
-
101
- .dialog-container[dialog-type="2"] .dialog-footer>.dialog-submit {
102
- background-color: var(--error-main-color);
103
- }
104
-
105
- .dialog-container[dialog-type="3"] .dialog-footer>.dialog-submit {
106
- background-color: var(--warning-main-color);
107
- }
108
-
109
- .dialog-container[dialog-type="4"] .dialog-footer>.dialog-submit {
110
- background-color: var(--success-main-color);
111
- }
@@ -1,109 +0,0 @@
1
- import React, { createRef } from 'react'
2
- import ReactDOM from 'react-dom'
3
- import styles from './dialog.module.css'
4
- import { ComponentStatus, getStatusIcon, Text } from '../../index'
5
- import { useTranslation, WithTranslation } from 'react-i18next';
6
-
7
- export enum DialogAlignment {
8
- start = 'start',
9
- center = 'center',
10
- end = 'end'
11
- }
12
-
13
- interface DialogState {
14
- readonly open?: boolean,
15
- title: string,
16
- status: ComponentStatus,
17
- content: string,
18
- onSubmit: Function,
19
- onCancel?: Function,
20
- submitTitle?: string,
21
- cancelTitle?: string,
22
- alignment?: DialogAlignment,
23
- }
24
-
25
- class TDialog extends React.Component<WithTranslation, DialogState> {
26
- constructor(props: WithTranslation) {
27
- super(props);
28
- this.state = {
29
- open: false,
30
- title: '',
31
- status: ComponentStatus.INFOR,
32
- content: '',
33
- onSubmit: () => { }
34
- }
35
- }
36
- showDialogNoti(data: DialogState) {
37
- this.setState({ open: true, ...data })
38
- }
39
-
40
- closeDialog() {
41
- this.setState({ open: false })
42
- }
43
-
44
- render() {
45
- const { t } = this.props;
46
- return (
47
- <>
48
- {this.state.open &&
49
- ReactDOM.createPortal(
50
- <div className={styles['dialog-overlay']}>
51
- <div className={`${styles['dialog-container']} col`} style={{ width: '41.4rem', alignItems: this.state.alignment }} dialog-type={this.state.status} onClick={e => e.stopPropagation()} >
52
- <div className={`${styles['dialog-body']} col`} style={{ alignItems: 'inherit' }}>
53
- <div className={`${styles['dialog-status']} row`}>{getStatusIcon(this.state.status)}</div>
54
- <div className='col'>
55
- <Text className={'heading-6'} style={{ textAlign: this.state.alignment === DialogAlignment.center ? 'center' : 'start' }}>{this.state.title}</Text>
56
- <Text className={'body-3'} style={{ textAlign: this.state.alignment === DialogAlignment.center ? 'center' : 'start' }}>{this.state.content}</Text>
57
- </div>
58
- </div>
59
- <div className={`${styles['dialog-footer']} row`}>
60
- <button type='button' style={this.state.alignment === DialogAlignment.center ? { flex: 1, width: '100%' } : undefined} onClick={() => {
61
- if (this.state.onCancel) this.state.onCancel();
62
- this.setState({ open: false });
63
- }} className={`${styles['dialog-action']} row`}>
64
- <Text className='button-text-3'>{this.state.cancelTitle ?? t("cancel")}</Text>
65
- </button>
66
- <button type='button' style={this.state.alignment === DialogAlignment.center ? { flex: 1, width: '100%' } : undefined} onClick={() => {
67
- this.state.onSubmit();
68
- this.setState({ open: false });
69
- }} className={`${styles['dialog-action']} row ${styles['dialog-submit']}`} >
70
- <Text className='button-text-3'>{this.state.submitTitle ?? t('submit')}</Text>
71
- </button>
72
- </div>
73
- </div>
74
- </div>,
75
- document.body
76
- )}
77
- </>
78
- )
79
- }
80
- }
81
-
82
- const dialogRef = createRef<TDialog>()
83
- export const Dialog = () => {
84
- const { t, i18n } = useTranslation()
85
- return <TDialog ref={dialogRef} t={t} i18n={i18n} tReady={true} />
86
- }
87
-
88
- export const showDialog = (props: {
89
- title?: string,
90
- status?: ComponentStatus,
91
- content?: string,
92
- onSubmit?: Function,
93
- onCancel?: Function,
94
- submitTitle?: string,
95
- cancelTitle?: string,
96
- alignment?: DialogAlignment
97
- }) => {
98
- if (dialogRef.current)
99
- dialogRef.current.showDialogNoti({
100
- title: props.title ?? '',
101
- status: props.status ?? ComponentStatus.INFOR,
102
- content: props.content ?? '',
103
- onSubmit: props.onSubmit ?? (() => { }),
104
- onCancel: props.onCancel,
105
- submitTitle: props.submitTitle,
106
- cancelTitle: props.cancelTitle,
107
- alignment: props.alignment
108
- })
109
- }
@@ -1,83 +0,0 @@
1
- .import-file-container {
2
- position: relative;
3
- align-items: center;
4
- justify-content: center;
5
- }
6
-
7
- .import-file-container input {
8
- display: none;
9
- }
10
-
11
- .import-file-container:has(input:disabled) {
12
- background-color: var(--neutral-disable-background-color) !important;
13
- pointer-events: none !important;
14
- }
15
-
16
- .import-file-container:not(.button-only) {
17
- max-width: 57rem;
18
- padding: 2.4rem;
19
- gap: 1.6rem;
20
- border-radius: 0.8rem;
21
- border: var(--neutral-bolder-border);
22
- }
23
-
24
- .import-file-container:not(.button-only):has(svg.preview-icon) {
25
- border-style: dashed;
26
- }
27
-
28
- .import-file-container>.import-file-prefix:not(*:has(>img)) {
29
- width: 4.8rem;
30
- height: 4.8rem;
31
- border-radius: 50%;
32
- }
33
-
34
- .import-file-container>.import-file-prefix {
35
- background-color: var(--primary-background);
36
- align-items: center;
37
- justify-content: center;
38
- }
39
-
40
- .import-file-container>.import-file-prefix>img {
41
- max-width: 14rem;
42
- max-height: 8.8rem;
43
- border-radius: 0.8rem;
44
- }
45
-
46
- .import-file-container>.file-preview-content {
47
- max-width: 100%;
48
- flex: 1;
49
- row-gap: 0.4rem;
50
- align-items: start;
51
- }
52
-
53
- .import-file-container.col>.file-preview-content {
54
- align-items: center;
55
- }
56
-
57
- .remove-preview-file {
58
- width: 1.6rem;
59
- height: 1.6rem;
60
- margin-left: 0.6rem;
61
- }
62
-
63
- div[class*="Toastify__toast-body"]>div:last-child {
64
- font: 500 1.2rem/1.6rem;
65
- }
66
-
67
- .import-file-container.helper-text {
68
- overflow: visible !important;
69
- border-color: var(--helper-text-color) !important;
70
- }
71
-
72
- .import-file-container.helper-text::after {
73
- content: attr(helper-text);
74
- color: var(--helper-text-color);
75
- position: absolute;
76
- left: 0;
77
- bottom: -0.4rem;
78
- width: max-content;
79
- font-size: 1.2rem;
80
- line-height: 1.6rem;
81
- font-family: inherit;
82
- transform: translateY(100%);
83
- }
@@ -1,174 +0,0 @@
1
- import React, { createRef, CSSProperties } from 'react'
2
- import styles from './import-file.module.css'
3
- import { ComponentStatus } from '../component-status'
4
- import { Button, Text, ToastMessage, Winicon } from '../../index'
5
- import { WithTranslation, withTranslation } from 'react-i18next';
6
-
7
- const cloudSvg = (
8
- <svg width='100%' height='100%' style={{ width: '3rem', height: '3rem' }} viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
9
- <path d='M22.5312 6.51941C20.3258 6.12929 18.0555 6.35518 15.9702 7.1722C13.8849 7.98923 12.0654 9.36573 10.712 11.1502C9.53042 12.7081 8.74407 14.5243 8.41412 16.4432C6.99557 16.9154 5.7486 17.8144 4.85059 19.0274C3.77621 20.4786 3.27749 22.2764 3.45068 24.0737C3.62388 25.871 4.45672 27.5405 5.78845 28.7599C7.12018 29.9792 8.85639 30.6621 10.662 30.6766H13.1063C13.7786 30.6766 14.3236 30.1316 14.3236 29.4594C14.3236 28.7871 13.7786 28.2421 13.1063 28.2421H10.6769C9.47485 28.2313 8.31921 27.7762 7.43253 26.9643C6.54471 26.1514 5.98948 25.0384 5.87402 23.8402C5.75855 22.642 6.09103 21.4435 6.80729 20.476C7.52354 19.5085 8.57279 18.8406 9.75252 18.6013C10.2753 18.4952 10.6682 18.061 10.7216 17.5303C10.9012 15.7476 11.5691 14.049 12.6518 12.6214C13.7345 11.1938 15.1901 10.0926 16.8583 9.43899C18.5266 8.78536 20.3428 8.60466 22.1071 8.91675C23.8715 9.22884 25.5155 10.0216 26.8583 11.2079C28.2011 12.3941 29.1905 13.9278 29.7178 15.6402C30.2451 17.3526 30.2898 19.1772 29.8469 20.9134C29.404 22.6495 28.4907 24.2297 27.2075 25.4802C25.9244 26.7308 24.3211 27.603 22.5742 28.001C21.9187 28.1504 21.5084 28.8028 21.6577 29.4583C21.807 30.1138 22.4595 30.5241 23.115 30.3748C25.2987 29.8772 27.3028 28.7869 28.9067 27.2238C30.5107 25.6606 31.6523 23.6853 32.2059 21.5152C32.7595 19.345 32.7037 17.0642 32.0446 14.9237C31.3855 12.7833 30.1486 10.8661 28.4701 9.38333C26.7916 7.90052 24.7366 6.90953 22.5312 6.51941Z' style={{ fill: "var(--primary-main-color)" }} />
10
- <path d='M17.1146 17.6431C17.2313 17.5264 17.3658 17.4384 17.5094 17.379C17.6513 17.3201 17.8067 17.2874 17.9697 17.2866L17.9753 17.2866L17.9809 17.2866C18.2906 17.288 18.5998 17.4069 18.8361 17.6431L23.7052 22.5123C24.1806 22.9876 24.1806 23.7584 23.7052 24.2338C23.2298 24.7091 22.4591 24.7091 21.9837 24.2338L19.1926 21.4427V29.4594C19.1926 30.1317 18.6476 30.6767 17.9753 30.6767C17.303 30.6767 16.758 30.1317 16.758 29.4594V21.4427L13.9669 24.2338C13.4916 24.7091 12.7208 24.7091 12.2455 24.2338C11.7701 23.7584 11.7701 22.9876 12.2455 22.5123L17.1146 17.6431Z' style={{ fill: "var(--primary-main-color)" }} />
11
- </svg>
12
- )
13
-
14
- const fileSvg = (
15
- <svg className={styles['preview-icon']} width='100%' height='100%' style={{ width: '3rem', height: '3rem' }} viewBox='0 0 36 36' fill='none' xmlns='http://www.w3.org/2000/svg' >
16
- <path d='M20.9163 3.41669H7.54829C7.22597 3.41669 6.91686 3.54472 6.68895 3.77263C6.46105 4.00054 6.33301 4.30965 6.33301 4.63196V31.3681C6.33301 31.6904 6.46105 31.9995 6.68895 32.2274C6.91686 32.4553 7.22597 32.5834 7.54829 32.5834H29.4233C29.7456 32.5834 30.0547 32.4553 30.2826 32.2274C30.5105 31.9995 30.6386 31.6904 30.6386 31.3681V13.1389H22.1316C21.8093 13.1389 21.5002 13.0109 21.2723 12.783C21.0444 12.5551 20.9163 12.2459 20.9163 11.9236V3.41669Z' style={{ fill: "var(--primary-main-color)" }} />
17
- <path d='M29.9264 10.7084H23.3469V4.12884L29.9264 10.7084Z' style={{ fill: "var(--primary-main-color)" }} />
18
- </svg>
19
- )
20
-
21
- const closeSvg = (
22
- <svg width='100%' height='100%' style={{ width: '2.4rem', height: '2.4rem' }} fill='none' xmlns='http://www.w3.org/2000/svg' >
23
- <path d='M13.4144 12.0002L20.4144 5.00015L19.0002 3.58594L12.0002 10.5859L5.00015 3.58594L3.58594 5.00015L10.5859 12.0002L3.58594 19.0002L5.00015 20.4144L12.0002 13.4144L19.0002 20.4144L20.4144 19.0002L13.4144 12.0002Z' style={{ fill: "var(--error-main-color)" }} />
24
- </svg>
25
- )
26
-
27
- interface ImportFileState {
28
- status?: ComponentStatus,
29
- preview?: Array<File> | Array<{ [k: string]: any }>
30
- }
31
-
32
- type ChangeFileFunction = (a?: Array<File> | Array<{ [k: string]: any }>) => void;
33
-
34
- interface ImportFileProps extends WithTranslation {
35
- id?: string,
36
- status?: ComponentStatus,
37
- value?: File | Array<File> | { [k: string]: any } | Array<{ [k: string]: any }>,
38
- buttonOnly?: boolean,
39
- onChange?: ChangeFileFunction,
40
- label?: string,
41
- className?: string,
42
- style?: CSSProperties,
43
- allowType?: Array<string>,
44
- subTitle?: string,
45
- multiple?: boolean,
46
- helperText?: string,
47
- helperTextColor?: string,
48
- disabled?: boolean,
49
- fileTagStyle?: CSSProperties
50
- /**
51
- * maxSize unit: kb (kilobytes)
52
- */
53
- maxSize?: number,
54
- }
55
-
56
- const formatFileSize = (bytes: number, decimalPoint?: number) => {
57
- if (bytes == 0) return '0 Bytes';
58
- var k = 1000,
59
- dm = decimalPoint || 2,
60
- sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
61
- i = Math.floor(Math.log(bytes) / Math.log(k));
62
- return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
63
- }
64
-
65
- class TImportFile extends React.Component<ImportFileProps, ImportFileState> {
66
- private fileRef = createRef<HTMLInputElement>();
67
- constructor(props: ImportFileProps | Readonly<ImportFileProps>) {
68
- super(props);
69
- this.state = {
70
- preview: this.props.value ? Array.isArray(this.props.value) ? this.props.value : [this.props.value] : undefined
71
- }
72
- }
73
-
74
- showFilePicker() {
75
- this.fileRef.current?.click()
76
- }
77
-
78
- componentDidUpdate(prevProps: Readonly<ImportFileProps>): void {
79
- if (prevProps.value !== this.props.value || prevProps.status !== this.props.status) {
80
- this.setState({ ...this.state, status: this.props.status, preview: this.props.value ? Array.isArray(this.props.value) ? this.props.value : [this.props.value] : undefined })
81
- }
82
- }
83
-
84
- render() {
85
- const { t } = this.props;
86
- let sizeTitle: string | undefined
87
- if (this.props.maxSize) sizeTitle = formatFileSize(this.props.maxSize)
88
- let _style = this.state.preview ? (this.props.style ?? {}) : { cursor: 'pointer', ...(this.props.style ?? {}) }
89
- return <div
90
- id={this.props.id}
91
- className={`${styles['import-file-container']} ${this.props.className ?? 'row'} ${this.props.buttonOnly ? styles['button-only'] : ''} ${this.props.helperText?.length ? styles['helper-text'] : ""}`}
92
- style={{ '--helper-text-color': this.props.helperTextColor ?? '#e14337', ..._style } as CSSProperties}
93
- helper-text={this.props.helperText}
94
- onClick={() => {
95
- if (!this.state.preview && !this.props.buttonOnly) this.showFilePicker()
96
- }}
97
- >
98
- <input disabled={this.props.disabled} type='file' multiple={this.props.multiple} accept={(this.props.allowType ?? []).join(',')} ref={this.fileRef} onChange={(ev) => {
99
- let files: Array<File> | undefined
100
- if (ev.target.files?.length) {
101
- files = [...(ev.target.files as any)]
102
- if (this.props.maxSize) {
103
- if (files.some(f => (f.size > (this.props.maxSize! * 1024)))) {
104
- ToastMessage.errors(t("limitFileError", { name: files.find(f => (f.size > (this.props.maxSize! * 1024)))?.name, sizeTitle: sizeTitle }))
105
- files = files.filter(f => (f.size <= (this.props.maxSize! * 1024)))
106
- }
107
- }
108
- }
109
- if (files) {
110
- if (this.props.multiple) {
111
- const newValue = this.state.preview?.filter(e => files.every(f => e.name !== f.name && e.size !== f.size && e.lastModified !== f.lastModified)) ?? []
112
- this.setState({ ...this.state, preview: [...newValue, ...files] })
113
- if (this.props.onChange) this.props.onChange([...newValue, ...files])
114
- } else {
115
- this.setState({ ...this.state, preview: files })
116
- if (this.props.onChange) this.props.onChange(files)
117
- }
118
- }
119
- }} />
120
- {this.props.buttonOnly
121
- ? null
122
- : this.props.multiple && this.state.preview?.length ? <div className='row' style={{ flex: 1, flexWrap: "wrap", gap: "0.8rem" }}>
123
- {this.state.preview.map(f => {
124
- return <div key={`${f.name}-${f.size}-${f.lastModified}`} className='row' style={{ gap: "0.8rem", padding: "0.6rem 0.8rem", borderRadius: "0.4rem", border: "var(--neutral-main-border)", flex: "0 calc((100% * 6 / 24) - 0.8rem * 3 / 4)", width: "auto", minWidth: "11.4rem", ...(this.props.fileTagStyle ?? {}) }}>
125
- <Winicon src={`outline/${f.type?.includes('image') ? "multimedia/image" : "files/file-export"}`} size={"1.4rem"} />
126
- <Text className='subtitle-4' style={{ flex: 1, width: "100%" }} maxLine={1}>{f.name}</Text>
127
- <Winicon src='fill/user interface/e-remove' size={"1.4rem"} onClick={() => {
128
- const newValue = this.state.preview?.filter(e => e.name !== f.name && e.size !== f.size && e.lastModified !== f.lastModified)
129
- this.setState({ ...this.state, preview: newValue })
130
- if (this.props.onChange) this.props.onChange(newValue)
131
- }} color='#E14337' />
132
- </div>
133
- })}
134
- </div> : <>
135
- <div className={`${styles['import-file-prefix']} row`}>
136
- {this.state.preview?.length ? this.state.preview[0].type?.includes('image') ? <img src={this.state.preview[0] instanceof File ? URL.createObjectURL(this.state.preview[0]) : this.state.preview?.[0]?.url} /> : fileSvg : cloudSvg}
137
- </div>
138
- <div className={`${styles['file-preview-content']} col`} >
139
- <Text className={`${styles['title-file']} heading-8`} style={{ maxWidth: '100%' }}>
140
- {this.state.preview?.[0]?.name ?? (this.props.label ?? t("uploadFileAction"))}
141
- </Text>
142
- <Text className={`${styles['subtitle-file']} subtitle-3`} style={{ maxWidth: '100%' }}>
143
- {this.state.preview?.[0]?.size
144
- ? `${this.state.preview?.[0].size}KB`
145
- : (this.props.subTitle ?? (sizeTitle ? t("limitFileWarning", { sizeTitle: sizeTitle }) : ''))}
146
- </Text>
147
- </div>
148
- </>
149
- }
150
- {this.state.preview?.length && this.props.buttonOnly && !this.props.multiple ? <div className='row' style={{ gap: "0.4rem" }}>
151
- <Text className='button-text-6'>{this.state.preview?.[0].name ?? ''}</Text>
152
- <button type='button' className={`${styles['remove-preview-file']}`} onClick={() => {
153
- this.setState({ ...this.state, preview: undefined })
154
- if (this.props.onChange) this.props.onChange(undefined)
155
- }}>
156
- {closeSvg}
157
- </button>
158
- </div>
159
- : <Button
160
- label={this.state.preview?.length ? this.props.multiple ? `${t("add")} ${t("file").toLowerCase()}` : `${t("remove")} ${t("file").toLowerCase()}` : `${t("choose")} ${t("file").toLowerCase()}`}
161
- style={{ padding: "1.2rem", backgroundColor: "var(--neutral-main-background-color)" }}
162
- className='button-text-4'
163
- onClick={() => {
164
- if (this.state.preview && !this.props.multiple) {
165
- this.setState({ ...this.state, preview: undefined })
166
- if (this.props.onChange) this.props.onChange(undefined)
167
- } else if (this.props.buttonOnly || this.state.preview) this.showFilePicker()
168
- }}
169
- />}
170
- </div>
171
- }
172
- }
173
-
174
- export const ImportFile = withTranslation()(TImportFile)
@@ -1,34 +0,0 @@
1
- .infinite-scroll.loading::after {
2
- content: '';
3
- position: sticky;
4
- width: 1.2rem;
5
- height: 1.2rem;
6
- border: 0.4rem solid var(--neutral-absolute-background-color);
7
- border-radius: 50%;
8
- border-top: 0.4rem solid var(--infor-main-color);
9
- -webkit-animation: spin 2s linear infinite;
10
- /* Safari */
11
- animation: spin 2s linear infinite;
12
- order: 100000;
13
- }
14
-
15
- /* Safari */
16
- @-webkit-keyframes spin {
17
- 0% {
18
- -webkit-transform: rotate(0deg);
19
- }
20
-
21
- 100% {
22
- -webkit-transform: rotate(360deg);
23
- }
24
- }
25
-
26
- @keyframes spin {
27
- 0% {
28
- transform: rotate(0deg);
29
- }
30
-
31
- 100% {
32
- transform: rotate(360deg);
33
- }
34
- }
@@ -1,35 +0,0 @@
1
- import React, { CSSProperties, ReactNode } from 'react';
2
- import styles from './infinite-scroll.module.css'
3
-
4
-
5
- interface InfiniteScrollProps {
6
- id?: string,
7
- className?: string,
8
- style?: CSSProperties,
9
- handleScroll?: (onLoadMore: boolean, ev: React.UIEvent<HTMLDivElement, UIEvent>) => Promise<any> | null,
10
- children?: ReactNode,
11
- totalCount?: number,
12
- }
13
-
14
- interface InfiniteScrollState {
15
- loading: boolean
16
- }
17
-
18
- export class InfiniteScroll extends React.Component<InfiniteScrollProps, InfiniteScrollState> {
19
- state: Readonly<InfiniteScrollState> = {
20
- loading: false
21
- }
22
-
23
- render() {
24
- return <div id={this.props.id} onScroll={async (ev) => {
25
- if (this.props.handleScroll) {
26
- this.setState({ ...this.state, loading: true })
27
- let scrollElement = ev.target as HTMLDivElement
28
- await this.props.handleScroll(Math.round(scrollElement.offsetHeight + scrollElement.scrollTop) >= (scrollElement.scrollHeight - 1), ev)
29
- this.setState({ loading: false })
30
- }
31
- }} className={`${styles['infinite-scroll']} ${this.state.loading ? styles['loading'] : ''} ${this.props.className ?? 'col'}`} style={this.props.style ?? { 'overflow': 'hidden auto' }}>
32
- {this.props.children}
33
- </div>
34
- }
35
- }
@@ -1,121 +0,0 @@
1
- .select-multi-container {
2
- border-radius: 0.8rem;
3
- width: 100%;
4
- max-height: 100%;
5
- box-sizing: border-box;
6
- padding: 0.8rem 1.6rem;
7
- border: var(--neutral-bolder-border);
8
- border-radius: 0.8rem;
9
- gap: 0.8rem;
10
- position: relative;
11
- cursor: context-menu;
12
- }
13
-
14
- .select-multi-container:focus-within {
15
- border-color: var(--primary-main-color);
16
- }
17
-
18
- .select-multi-container.disabled {
19
- background-color: var(--neutral-disable-background-color) !important;
20
- pointer-events: none !important;
21
- }
22
-
23
- .select-multi-container.helper-text {
24
- overflow: visible !important;
25
- border-color: var(--helper-text-color) !important;
26
- }
27
-
28
- .select-multi-container.helper-text::after {
29
- content: attr(helper-text);
30
- color: var(--helper-text-color);
31
- position: absolute;
32
- left: 0;
33
- bottom: -0.4rem;
34
- width: max-content;
35
- font-size: 1.2rem;
36
- line-height: 1.6rem;
37
- font-family: inherit;
38
- transform: translateY(100%);
39
- }
40
-
41
- .select-multi-container *:has(input),
42
- .select-multi-container *:has(.selected-item-value),
43
- .select-multi-container input {
44
- font: inherit;
45
- color: inherit;
46
- font-size: inherit;
47
- font-family: inherit;
48
- font-weight: inherit;
49
- line-height: inherit;
50
- text-align: inherit;
51
- text-overflow: inherit;
52
- }
53
-
54
- .select-multi-container input {
55
- flex: 1;
56
- min-width: 6rem;
57
- border: none;
58
- outline: none;
59
- padding: 0;
60
- background-color: transparent;
61
- }
62
-
63
- .select-multi-container .selected-item-value {
64
- border-radius: 10rem;
65
- padding: 0.4rem 0.8rem;
66
- background-color: var(--neutral-selected-background-color);
67
- gap: 0.8rem;
68
- }
69
-
70
- .select-multi-popup {
71
- position: absolute;
72
- z-index: 10;
73
- background-color: var(--neutral-absolute-background-color);
74
- border-radius: 0.8rem;
75
- border: var(--neutral-main-border);
76
- height: fit-content;
77
- box-shadow: 0 0 12px 0 #00204d1f;
78
- align-items: center;
79
- }
80
-
81
- .select-multi-popup>.select-body {
82
- max-height: 100%;
83
- flex: 1;
84
- align-items: start;
85
- max-height: 28rem;
86
- min-height: 8rem;
87
- width: 100%;
88
- padding: 0.4rem 0;
89
- overflow: hidden auto;
90
- }
91
-
92
- .select-multi-popup>.select-body .select-tile {
93
- justify-content: start;
94
- align-items: center;
95
- padding: 0.8rem 1.6rem;
96
- gap: 0.8rem;
97
- width: 100%;
98
- cursor: context-menu;
99
- }
100
-
101
- .select-multi-popup>.select-body .select-tile:hover {
102
- background-color: var(--neutral-hover-background-color);
103
- }
104
-
105
- .select-multi-popup>.select-body .select-tile:has(input:checked) {
106
- background-color: var(--neutral-selected-background-color);
107
- }
108
-
109
- .select-multi-popup>.select-body .select-tile.disabled {
110
- background-color: var(--neutral-disable-background-color) !important;
111
- }
112
-
113
- .select-multi-popup>.select-body .select-tile.disabled * {
114
- color: var(--neutral-text-disabled-color) !important;
115
- }
116
-
117
- .no-results-found {
118
- padding: 0.8rem;
119
- font: 400 1.4rem/2rem "Inter";
120
- color: var(--neutral-text-title-reverse-color);
121
- }