@everchron/ec-shards 7.2.0 → 7.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everchron/ec-shards",
3
- "version": "7.2.0",
3
+ "version": "7.2.2",
4
4
  "private": false,
5
5
  "description": "Everchron Shards UI Library",
6
6
  "repository": "https://github.com/everchron/ec-shards.git",
@@ -5,11 +5,11 @@
5
5
  disabled ? 'ecs-dropzone-disabled' : '',
6
6
  dragging ? 'ecs-dropzone-dragging' : ''
7
7
  ]"
8
- @dragenter="dragging=true"
9
- @dragleave="dragging=false"
8
+ @dragover="handleDragOver"
9
+ @dragenter="handleDragEnter"
10
+ @dragleave="handleDragLeave"
10
11
  @drop.prevent="drop"
11
- @dragover.prevent
12
- :aria-busy="loading || progress"
12
+ :aria-busy="isBusy"
13
13
  :aria-invalid="error">
14
14
 
15
15
  <input @change="change" type="file" :multiple="multiple" ref="file" />
@@ -24,10 +24,23 @@
24
24
  <!-- @slot Slot for a custom main label. Note: this will replace the file selector button as well as drag & drop label. Should only be used for states that do not require a drop action, such as active virus scanning. -->
25
25
  <slot name="customlabel"></slot>
26
26
  </div>
27
- <div v-if="$slots.hint" class="ecs-dropzone-hint">
28
- <!-- @slot Slot for an additional informational label underneath the dropzone text. Can contain basic HTML tags: `a`, `b`, `strong`. -->
27
+ <div v-if="$slots.hint && !uploadStats.show" class="ecs-dropzone-hint">
28
+ <!-- @slot Slot for an additional informational label underneath the dropzone text. Can contain basic HTML tags: `a`, `b`, `strong`. **Note:** the hint is hidden when `uploadStats` are present and shown. -->
29
29
  <slot name="hint"></slot>
30
30
  </div>
31
+ <!-- Shows when uploadStats show is true.-->
32
+ <div v-if="uploadStats.show" class="ecs-dropzone-stats">
33
+ <ecs-flex-row :gap="8" justify="center">
34
+ <ecs-text v-if="uploadStats.speed > 2000000" type="label" emphasized color="#474B60">Uploading</ecs-text>
35
+ <ecs-flex-row v-else :gap="4" title="Slow network, please check your connection.">
36
+ <ecs-sticker type="warning" />
37
+ <ecs-text type="label" emphasized color="warning">Uploading</ecs-text>
38
+ </ecs-flex-row>
39
+ <span>({{ formattedSpeed }})</span>
40
+ <span>Remaining: {{ uploadStats.timeRemaining }}</span>
41
+ </ecs-flex-row>
42
+ </div>
43
+
31
44
  <div v-if="error && errorMessage" class="ecs-dropzone-error-message">{{ errorMessage }}</div>
32
45
  </div>
33
46
  <ecs-progress v-if="loading || progress" :infinite="!progress" :running="!!progress" :value="progress" />
@@ -43,6 +56,9 @@
43
56
  import EcsProgress from '../progress/progress'
44
57
  import EcsButton from '../button/button'
45
58
  import EcsFocusRing from '../mixins/focus-ring'
59
+ import EcsFlexRow from '../flex/flex-row'
60
+ import EcsSticker from '../sticker/sticker'
61
+ import EcsText from '../text/text'
46
62
 
47
63
  export default {
48
64
  components: {
@@ -50,7 +66,10 @@
50
66
  EcsSkeletonLoader,
51
67
  EcsProgress,
52
68
  EcsButton,
53
- EcsFocusRing
69
+ EcsFocusRing,
70
+ EcsFlexRow,
71
+ EcsSticker,
72
+ EcsText
54
73
  },
55
74
 
56
75
  props: {
@@ -108,13 +127,24 @@
108
127
  icon: 'back'
109
128
  }
110
129
  }
130
+ },
131
+ /** Shows upload statistics inside the dropzone, while files are uploading. Time remaining must be pre-formatted, as formatting is not handled in the shard component. */
132
+ uploadStats: {
133
+ type: Object,
134
+ default() {
135
+ return {
136
+ show: false,
137
+ speed: 0,
138
+ timeRemaining: ''
139
+ }
140
+ }
111
141
  }
112
142
  },
113
143
 
114
144
  data() {
115
145
  return {
116
146
  uploads : [],
117
- dragging : false
147
+ dragging : false,
118
148
  }
119
149
  },
120
150
 
@@ -143,16 +173,65 @@
143
173
  return '#D7DAE1'
144
174
  },
145
175
 
176
+ isBusy() {
177
+ return !!(
178
+ this.initializing ||
179
+ this.loading ||
180
+ this.progress ||
181
+ this.uploadStats.show
182
+ );
183
+ },
184
+
146
185
  cancelButtonOptions() {
147
186
  return Object.assign({
148
187
  show: false,
149
188
  label: 'Cancel',
150
189
  icon: 'back'
151
190
  }, this.cancelButton);
191
+ },
192
+
193
+ uploadStatsOptions() {
194
+ return Object.assign({
195
+ show: false,
196
+ speed: 0,
197
+ timeRemaining: ''
198
+ }, this.uploadStats);
199
+ },
200
+
201
+ formattedSpeed() {
202
+ const bytes = this.uploadStats.speed;
203
+ if (bytes === 0) return '0 Bytes';
204
+
205
+ const k = 1024;
206
+ const dm = 2;
207
+ const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
208
+
209
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
210
+
211
+ if (sizes[i] == 'Bytes' && 'KB')
212
+ return '<1 KB';
213
+
214
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
152
215
  }
153
216
  },
154
217
 
155
218
  methods: {
219
+ handleDragEnter(event) {
220
+ event.preventDefault();
221
+ this.dragging = true;
222
+ },
223
+
224
+ handleDragLeave(event) {
225
+ if (event.target === this.$el || !this.$el.contains(event.target)) {
226
+ this.dragging = false;
227
+ }
228
+ },
229
+
230
+ handleDragOver(event) {
231
+ event.preventDefault();
232
+ this.dragging = true;
233
+ },
234
+
156
235
  browseFile() {
157
236
  this.$refs.file.click()
158
237
  },
@@ -249,6 +328,12 @@
249
328
  margin: $spacing-25 auto 0 auto;
250
329
  }
251
330
 
331
+ &-stats{
332
+ font-size: $type-scale-3-font-size;
333
+ line-height: $type-scale-3-line-height;
334
+ margin-top: $spacing-10;
335
+ }
336
+
252
337
  &-hint,
253
338
  &-error-message{
254
339
  font-size: $type-scale-3-font-size;
@@ -12,7 +12,7 @@
12
12
  @click="handleClick">
13
13
 
14
14
  <ecs-icon v-if="icon" :type="icon" />
15
- <ecs-icon v-if="icon && sticker" :type="`sticker-${sticker}`" class="sticker" size="16" />
15
+ <ecs-sticker v-if="icon && sticker" :type="sticker" />
16
16
  <slot></slot>
17
17
  <span v-if="shortcut" class="shortcut">{{ shortcut }}</span>
18
18
  <ecs-focus-ring :inset="0" />
@@ -22,11 +22,13 @@
22
22
 
23
23
  <script>
24
24
  import EcsIcon from '../icon/icon'
25
+ import EcsSticker from '../sticker/sticker'
25
26
  import EcsFocusRing from '../mixins/focus-ring'
26
27
 
27
28
  export default {
28
29
  components: {
29
30
  EcsIcon,
31
+ EcsSticker,
30
32
  EcsFocusRing
31
33
  },
32
34
 
@@ -52,7 +54,8 @@
52
54
  },
53
55
  /** Adds an ecs-sticker to this tab button, check the Sticker component for available types. */
54
56
  sticker: {
55
- type: String
57
+ type: String,
58
+ validator: v => ['current', 'error', 'loading', 'warning', 'success', 'info', 'shared', 'null', null, undefined].includes(v)
56
59
  },
57
60
  /** Disables the tab button. */
58
61
  disabled: {
@@ -70,7 +73,6 @@
70
73
  },
71
74
 
72
75
  computed: {
73
-
74
76
  },
75
77
 
76
78
  mounted() {
@@ -162,7 +164,7 @@
162
164
  pointer-events: none;
163
165
  }
164
166
 
165
- .sticker{
167
+ .ecs-sticker{
166
168
  position: absolute;
167
169
  }
168
170
  }
@@ -243,11 +245,11 @@
243
245
  margin-right: 0;
244
246
  }
245
247
 
246
- .icon:not(.sticker){
248
+ .icon{
247
249
  margin: 0 4px 0 -4px;
248
250
  }
249
251
 
250
- .sticker{
252
+ .ecs-sticker{
251
253
  left: $spacing-25;
252
254
  bottom: $spacing-10;
253
255
  }
@@ -275,11 +277,11 @@
275
277
  border-radius: 0 2px 2px 0;
276
278
  }
277
279
 
278
- .icon:not(.sticker){
280
+ .icon{
279
281
  margin: -5px 5px -5px -5px;
280
282
  }
281
283
 
282
- .sticker{
284
+ .ecs-sticker{
283
285
  top: 20px;
284
286
  left: 29px;
285
287
  }
@@ -6,6 +6,16 @@ import { Meta } from '@storybook/addon-docs/blocks';
6
6
  Changelog
7
7
  </h1>
8
8
 
9
+ ## Version 7.2.2 (5 June 2023)
10
+
11
+ ### Features
12
+
13
+ - Added uploadStats to EcsDropzone component
14
+
15
+ ### Fixes
16
+
17
+ - Fixed the dragover events on EcsDropzone component
18
+
9
19
  ## Version 7.2.0 (29 May 2023)
10
20
 
11
21
  ### Features
@@ -25,6 +25,17 @@ export const dropzoneWithHint = () => ({
25
25
  `,
26
26
  });
27
27
 
28
+ export const dropzoneDisabled = () => ({
29
+ components: { EcsDropzone },
30
+ template: `
31
+ <div style="width:100%; height: 600px">
32
+ <ecs-dropzone disabled>
33
+ <template slot="hint">This is an additional <a href="#">hint text</a>.</template>
34
+ </ecs-dropzone>
35
+ </div>
36
+ `,
37
+ });
38
+
28
39
  export const dropzoneError = () => ({
29
40
  components: { EcsDropzone },
30
41
  template: `
@@ -75,6 +86,36 @@ export const dropzoneUploading = () => ({
75
86
  `,
76
87
  });
77
88
 
89
+ export const dropzoneUploadingWithStats = () => ({
90
+ components: { EcsDropzone },
91
+ data() {
92
+ return {
93
+ uploadSpeed: 82943,
94
+ };
95
+ },
96
+ methods: {
97
+ simulateUploadSpeedChange() {
98
+ setInterval(() => {
99
+ this.uploadSpeed = Math.floor(Math.random() * 1000000);
100
+ }, 1000);
101
+ },
102
+ },
103
+ mounted() {
104
+ this.simulateUploadSpeedChange();
105
+ },
106
+ template: `
107
+ <div style="width:100%; height: 600px">
108
+ <ecs-dropzone
109
+ state="upload"
110
+ :progress="56"
111
+ :uploadStats="{show: true, speed: uploadSpeed, timeRemaining: '2 minutes'}"
112
+ >
113
+ <template slot="hint">This is an additional <a href="#">hint text</a>.</template>
114
+ </ecs-dropzone>
115
+ </div>
116
+ `,
117
+ });
118
+
78
119
  export const dropzoneCustomLabel = () => ({
79
120
  components: { EcsDropzone },
80
121
  template: `