@everchron/ec-shards 1.2.1 → 1.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everchron/ec-shards",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "description": "Everchron Shards UI Library",
6
6
  "repository": "https://github.com/everchron/ec-shards.git",
@@ -1,22 +1,163 @@
1
1
  <template>
2
- <div class="ecs-dropzone" @drop.prevent="drop" @dragenter.prevent="drag" @dragleave.prevent="drag" @dragover.prevent>
3
- <label class="ecs-dropzone-message" for="file">
4
- <slot></slot>
5
- <input type="file" id="file">
6
- </label>
2
+ <div class="ecs-dropzone"
3
+ :class="[
4
+ error ? 'ecs-dropzone-error' : '',
5
+ disabled ? 'ecs-dropzone-disabled' : '',
6
+ dragging ? 'ecs-dropzone-dragging' : ''
7
+ ]"
8
+ @dragenter="dragging=true"
9
+ @dragleave="dragging=false"
10
+ @drop.prevent="drop"
11
+ @dragover.prevent>
12
+
13
+ <input @change="change" type="file" :multiple="multiple" ref="file" />
14
+
15
+ <ecs-empty-state type="empty-file-drag" :iconColor="iconColor">
16
+ <ecs-skeleton-loader v-if="initializing" type="single" :width="100" class="ecs-dropzone-skeleton" />
17
+ <div v-else>
18
+ Drag and drop your {{ fileTypeLabel }} or <i @click="() => this.$refs.file.click()">browse</i> to upload.
19
+ <div v-if="$slots.hint" class="ecs-dropzone-hint">
20
+ <!-- @slot Slot for an additional informational label underneath the dropzone text. Can contain basic HTML tags: `a`, `b`, `strong`. -->
21
+ <slot name="hint"></slot>
22
+ </div>
23
+ <div v-if="error && errorMessage" class="ecs-dropzone-error-message">{{ errorMessage }}</div>
24
+ </div>
25
+ <ecs-progress v-if="loading || progress" :infinite="!progress" :running="!!progress" :value="progress" />
26
+ </ecs-empty-state>
27
+
28
+ <ecs-button v-if="cancelButtonOptions.show" @click="cancelUpload" type="secondary" :icon="cancelButtonOptions.icon" class="ecs-dropzone-cancel">{{ cancelButtonOptions.label }}</ecs-button>
7
29
  </div>
8
30
  </template>
9
31
 
10
32
  <script>
33
+ import EcsEmptyState from '../empty-state/empty-state'
34
+ import EcsSkeletonLoader from '../skeleton-loader/skeleton-loader'
35
+ import EcsProgress from '../progress/progress'
36
+ import EcsButton from '../button/button'
37
+
11
38
  export default {
39
+ components: {
40
+ EcsEmptyState,
41
+ EcsSkeletonLoader,
42
+ EcsProgress,
43
+ EcsButton
44
+ },
45
+
46
+ props: {
47
+ /** Determines the file label in the informational text. E.g. "Drag and drop your **`load file`** or browse to upload." */
48
+ fileTypeLabel: {
49
+ type: String,
50
+ default: 'files'
51
+ },
52
+ /** Determines if multiple items should be returned on @onFileDrop. */
53
+ multiple: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ /** Disables the upload dropzone. */
58
+ disabled: {
59
+ type: Boolean,
60
+ default: false
61
+ },
62
+ /** Indicates an error by coloring the dropzone red. */
63
+ error: {
64
+ type: Boolean,
65
+ default: false
66
+ },
67
+ /** Shows an additional error message. Will only show up when the `error` prop is also `true`. */
68
+ errorMessage: {
69
+ type: String
70
+ },
71
+ /** Turns the dropzone into initializing state. */
72
+ initializing: {
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+ /** Shows an infinite progress bar. This should only be used when an exact percentage value isn't availabel. */
77
+ loading: {
78
+ type: Boolean,
79
+ default: false
80
+ },
81
+ /** Shows a progress bar with the given % value. */
82
+ progress: {
83
+ type: Number
84
+ },
85
+ /** Shows a button in the bottom left of the dropzone which can be used to cancel the upload process, go back in the workflow, etc. Emits `@cancel` on click. */
86
+ cancelButton: {
87
+ type: Object,
88
+ default () {
89
+ return {
90
+ show: false,
91
+ label: 'Cancel',
92
+ icon: 'back'
93
+ }
94
+ }
95
+ }
96
+ },
97
+
98
+ data() {
99
+ return {
100
+ uploads : [],
101
+ dragging : false
102
+ }
103
+ },
104
+
105
+ computed: {
106
+ showError(){
107
+ return !this.dragging && this.error
108
+ },
109
+
110
+ iconColor(){
111
+ if(this.dragging)
112
+ return '#6BAFFF'
113
+ else if(this.initializing || this.disabled)
114
+ return '#ECEDF2'
115
+ else
116
+ return '#D7DAE1'
117
+ },
118
+
119
+ cancelButtonOptions() {
120
+ return Object.assign({
121
+ show: false,
122
+ label: 'Cancel',
123
+ icon: 'back'
124
+ }, this.cancelButton);
125
+ }
126
+ },
127
+
12
128
  methods: {
13
- drop(e) {
14
- e.currentTarget.classList.toggle('drag-over')
129
+ drop({ dataTransfer }) {
130
+ this.dragging = false
131
+ const files = dataTransfer.files
132
+ const items = dataTransfer.items
133
+ if (files && files[0]){
134
+ if (this.multiple)
135
+ this.$emit('onFileDrop', files, items)
136
+ else
137
+ this.$emit('onFileDrop', files[0], items[0])
138
+ }
139
+ },
140
+
141
+ change({ target }) {
142
+ if (this.multiple)
143
+ /** Emitted when items are dropped into the dropzone area. */
144
+ this.$emit('onFileDrop', target.files)
145
+ else
146
+ this.$emit('onFileDrop', target.files[0])
15
147
  },
16
148
 
17
- drag(e) {
18
- e.currentTarget.classList.toggle('drag-over')
149
+ cancelUpload() {
150
+ /** Emitted when clicking the optional cancel/back button inside the dropzone. */
151
+ this.$emit('cancel')
19
152
  }
153
+ },
154
+
155
+ mounted() {
156
+ document.addEventListener('dragenter', this.show)
157
+ },
158
+
159
+ beforeDestroy() {
160
+ document.removeEventListener('dragenter', this.show)
20
161
  }
21
162
  }
22
163
  </script>
@@ -29,52 +170,72 @@
29
170
  display: flex;
30
171
  justify-content: center;
31
172
  align-items: center;
32
- border-radius: $border-radius-small;
33
- position: absolute;
34
- left: 10px;
35
- top: 10px;
36
- bottom: 10px;
37
- right: 10px;
173
+ border-radius: $border-radius-large;
174
+ width: 100%;
175
+ height: 100%;
176
+ border: 1px dashed $color-gray-4;
177
+ position: relative;
38
178
  transition: .2s;
39
179
 
40
180
  input[type=file]{
41
181
  display: none;
42
182
  }
43
183
 
44
- &.drag-over{
45
- background: $color-blue-1;
46
- cursor: copy;
184
+ .ecs-empty-state-message i{
185
+ color: $color-blue-10;
186
+ font-weight: $font-weight-medium;
187
+ font-style: normal;
188
+ cursor: pointer;
189
+ }
47
190
 
48
- .dropzone-message:before{
49
- opacity: .8;
50
- }
191
+ &-skeleton{
192
+ margin: 9px auto;
51
193
  }
52
194
 
53
- &-message{
54
- padding-top: 180px;
55
- position: relative;
56
- font-size: $type-scale-4-font-size;
57
- font-weight: 300;
195
+ .ecs-progress{
196
+ width: 80%;
197
+ margin: $spacing-25 auto 0 auto;
198
+ }
199
+
200
+ &-hint,
201
+ &-error-message{
202
+ font-size: $type-scale-3-font-size;
203
+ line-height: $type-scale-3-line-height;
204
+ margin-top: $spacing-10;
205
+ }
206
+
207
+ &-hint{
58
208
  color: $color-gray-8;
209
+ }
210
+
211
+ &-cancel{
212
+ position: absolute;
213
+ bottom: 16px;
214
+ left: 16px;
215
+ }
216
+
217
+ &-dragging{
218
+ background: $color-blue-1;
219
+ border: 1px solid $color-blue-4;
220
+ box-shadow: 0 0 0 1px $color-blue-4 inset;
221
+ }
222
+
223
+ &-error{
224
+ background: $color-red-1;
225
+ border-color: $color-red-4;
59
226
 
60
- i{
61
- color: $color-blue-10;
62
- font-style: normal;
63
- font-weight: 400;
64
- cursor: pointer;
227
+ &-message{
228
+ color: $color-red-10;
65
229
  }
230
+ }
231
+
232
+ &-disabled{
233
+ background: $color-gray-1;
66
234
 
67
- &:before{
68
- content: "";
69
- position: absolute;
70
- width: 121px;
71
- height: 151px;
72
- background: svg-uri('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="121" height="151" viewBox="0 0 121 151"><defs><path id="b" d="M30,20 L30,140 L0,140 L0,20 L0,0 L110,0 L110,20 L30,20 Z"/><path id="a" d="M0,0 L110,0 L110,140 L0,140 L0,0 Z"/><mask id="d" width="110" height="140" x="0" y="0" fill="white"><use xlink:href="#a"/></mask></defs><g fill="none" fill-rule="evenodd"><mask id="c" fill="white"><use xlink:href="#b"/></mask><g stroke="#858E9E" stroke-dasharray="9 6" stroke-width="2" mask="url(#c)" opacity=".8"><use mask="url(#d)" xlink:href="#a"/></g><g stroke="#858E9E" transform="translate(30 20)"><path d="M0.5,0.5 L0.5,130.5 L90.5,130.5 L90.5,20.4954694 L70.9952996,0.5 L0.5,0.5 Z"/><polyline stroke-linecap="round" stroke-linejoin="round" points="90.496 20.5 70.5 20.5 70.5 .5"/></g></g></svg>');
73
- top: 0;
74
- left: 50%;
75
- margin-left: -60px;
76
- transition: .2s;
77
- opacity: .6;
235
+ .ecs-empty-state-message i{
236
+ pointer-events: none;
237
+ color: $color-gray-10;
238
+ cursor: default;
78
239
  }
79
240
  }
80
241
  }
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="ecs-empty-state">
3
- <ecs-icon v-if="type!='loading'" :type="type" color="#C9D0D4" :width="iconSize" :height="iconSize" />
3
+ <ecs-icon v-if="type!='loading'" :type="type" :color="iconColor" :width="iconSize" :height="iconSize" />
4
4
  <div v-else class="ecs-empty-state-loading" />
5
5
  <div v-if="type!='loading'" class="ecs-empty-state-message" :class="size">
6
6
  <slot></slot>
@@ -30,6 +30,11 @@
30
30
  validator: v => ['sml', null].includes(v),
31
31
  default: null
32
32
  },
33
+ /** Determines the color if the empty state illustration icon. */
34
+ iconColor: {
35
+ type: String,
36
+ default: "#C9D0D4"
37
+ }
33
38
  },
34
39
 
35
40
  computed: {
@@ -57,18 +62,17 @@
57
62
  height: 100%;
58
63
 
59
64
  &-message{
60
- font-weight: 300;
61
65
  font-size: $type-scale-4-font-size;
62
- color: $color-gray-8;
66
+ color: $color-gray-9;
63
67
  min-width: 300px;
64
68
  max-width: 400px;
65
69
  text-align: center;
66
70
  margin-top: 10px;
67
- line-height: 1.3em;
71
+ line-height: $type-scale-4-line-height;
68
72
 
69
73
  &.sml{
70
- font-weight: 400;
71
74
  font-size: $type-scale-3-font-size;
75
+ line-height: $type-scale-3-line-height;
72
76
  min-width: auto;
73
77
  max-width: 100%;
74
78
  }
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-flex-row" :class="[directionClass, justifyClass, alignClass, wrapClass]">
2
+ <div class="ecs-flex-row" :class="[directionClass, justifyClass, alignClass, wrapClass]" :style="{columnGap: gap + 'px'}">
3
3
  <slot></slot>
4
4
  </div>
5
5
  </template>
@@ -29,6 +29,10 @@
29
29
  wrap: {
30
30
  type: Boolean,
31
31
  default: false
32
+ },
33
+ /** Determines the spacing between flex columns inside the row. Accepts only pixel values. */
34
+ gap: {
35
+ type: Number
32
36
  }
33
37
  },
34
38
 
@@ -63,5 +63,6 @@
63
63
 
64
64
  .icon{
65
65
  flex-shrink: 0;
66
+ transition: .2s color;
66
67
  }
67
68
  </style>
@@ -161,7 +161,7 @@
161
161
  if(this.fullWidth && !this.$slots.tabs){
162
162
  return '100%'
163
163
  } else {
164
- return '900px'
164
+ return '920px'
165
165
  }
166
166
  },
167
167
 
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="ecs-tab-content" :class="flex ? 'ecs-tab-content-flex' : ''">
2
+ <div class="ecs-tab-content" :class="[flex ? 'ecs-tab-content-flex' : '', fill ? 'ecs-tab-content-fill' : '']">
3
3
  <slot></slot>
4
4
  </div>
5
5
  </template>
@@ -11,6 +11,11 @@
11
11
  flex: {
12
12
  type: Boolean,
13
13
  default: false
14
+ },
15
+ /** Sets the height of the tabs area to 100%. Also sets the inner tab height to 100%. */
16
+ fill: {
17
+ type: Boolean,
18
+ default: false
14
19
  }
15
20
  }
16
21
  }
@@ -24,4 +29,12 @@
24
29
  height: 100%;
25
30
  min-height: 0;
26
31
  }
32
+
33
+ .ecs-tab-content-fill{
34
+ min-height: 100%;
35
+
36
+ .ecs-tab-pane{
37
+ min-height: 100%;
38
+ }
39
+ }
27
40
  </style>
@@ -6,6 +6,34 @@ import { Meta } from '@storybook/addon-docs/blocks';
6
6
  Changelog
7
7
  </h1>
8
8
 
9
+ ## Version 1.3.0 (26 August 2022)
10
+
11
+ ### Features
12
+
13
+ - Added the EcsDropzone component which can be used for file upload dropzones.
14
+
15
+ ### Changes
16
+
17
+ - Allow to change the color of the illustrations within EcsEmptyState by using the new `iconColor` prop.
18
+ - Small text style adjustments on EcsEmptyState
19
+ - Added a transition for color on EcsIcon
20
+
21
+ ## Version 1.2.3 (25 August 2022)
22
+
23
+ ### Features
24
+
25
+ - Added `gap` prop to EcsFlexRow component.
26
+
27
+ ### Changes
28
+
29
+ - Increased the EcsOverlay content area width from 900 to 920 pixels.
30
+
31
+ ## Version 1.2.2 (25 August 2022)
32
+
33
+ ### Features
34
+
35
+ - Added `fill` prop to EcsTabs component.
36
+
9
37
  ## Version 1.2.1 (25 August 2022)
10
38
 
11
39
  ### Features
@@ -1,11 +1,71 @@
1
1
  import EcsDropzone from '@components/dropzone/dropzone';
2
2
 
3
3
  export default {
4
- title: 'Input/Dropzone',
4
+ title: 'Input/Dropzone File Upload',
5
5
  component: EcsDropzone
6
6
  };
7
7
 
8
8
  export const dropzone = () => ({
9
9
  components: { EcsDropzone },
10
- template: `<ecs-dropzone>Drag and drop here or <i>browse</i> to upload.</ecs-dropzone>`,
10
+ template: `
11
+ <div style="width:100%; height: 600px">
12
+ <ecs-dropzone />
13
+ </div>
14
+ `,
15
+ });
16
+
17
+ export const dropzoneWithHint = () => ({
18
+ components: { EcsDropzone },
19
+ template: `
20
+ <div style="width:100%; height: 600px">
21
+ <ecs-dropzone>
22
+ <template slot="hint">This is an additional <a href="#">hint text</a>.</template>
23
+ </ecs-dropzone>
24
+ </div>
25
+ `,
26
+ });
27
+
28
+ export const dropzoneError = () => ({
29
+ components: { EcsDropzone },
30
+ template: `
31
+ <div style="width:100%; height: 600px">
32
+ <ecs-dropzone error error-message="This is an optional error message." />
33
+ </div>
34
+ `,
35
+ });
36
+
37
+ export const dropzoneWithCancel = () => ({
38
+ components: { EcsDropzone },
39
+ template: `
40
+ <div style="width:100%; height: 600px">
41
+ <ecs-dropzone :cancel-button="{show: true, label: 'Back', icon: 'back'}" />
42
+ </div>
43
+ `,
44
+ });
45
+
46
+ export const dropzoneInitializing = () => ({
47
+ components: { EcsDropzone },
48
+ template: `
49
+ <div style="width:100%; height: 600px">
50
+ <ecs-dropzone initializing />
51
+ </div>
52
+ `,
53
+ });
54
+
55
+ export const dropzoneProcessing = () => ({
56
+ components: { EcsDropzone },
57
+ template: `
58
+ <div style="width:100%; height: 600px">
59
+ <ecs-dropzone loading />
60
+ </div>
61
+ `,
62
+ });
63
+
64
+ export const dropzoneUploading = () => ({
65
+ components: { EcsDropzone },
66
+ template: `
67
+ <div style="width:100%; height: 600px">
68
+ <ecs-dropzone :progress="56" />
69
+ </div>
70
+ `,
11
71
  });
@@ -15,6 +15,15 @@ export const flexRow = () => ({
15
15
  </ecs-flex-row>`,
16
16
  });
17
17
 
18
+ export const flexRowColumnGap = () => ({
19
+ components: { EcsFlexRow, EcsFlexCol },
20
+ template: `<ecs-flex-row class="highlight" :gap="16">
21
+ <div>Flex Item 1</div>
22
+ <div>Flex Item 2</div>
23
+ <div>Flex Item 3</div>
24
+ </ecs-flex-row>`,
25
+ });
26
+
18
27
  export const flexRowDirection = () => ({
19
28
  components: { EcsFlexRow, EcsFlexCol },
20
29
  template: `<div>
@@ -28,7 +28,7 @@ export const tabs = () => ({
28
28
  <ecs-tab-button @click="tabIndex = 2" :show="tabIndex == 2">Calendar</ecs-tab-button>
29
29
  <ecs-tab-button @click="tabIndex = 3" :show="tabIndex == 3">Versions</ecs-tab-button>
30
30
  </ecs-tab-bar>
31
- <ecs-tabs>
31
+ <ecs-tabs fill>
32
32
  <ecs-tab :show="tabIndex == 1">First Tab</ecs-tab>
33
33
  <ecs-tab :show="tabIndex == 2">Second Tab</ecs-tab>
34
34
  <ecs-tab :show="tabIndex == 3">Third Tab</ecs-tab>