polaris_view_components 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/polaris_view_components/autocomplete_controller.js +32 -15
  3. data/app/assets/javascripts/polaris_view_components/dropzone_controller.js +495 -0
  4. data/app/assets/javascripts/polaris_view_components/index.js +2 -0
  5. data/app/assets/javascripts/polaris_view_components/popover_controller.js +9 -2
  6. data/app/assets/javascripts/polaris_view_components/utils.js +23 -0
  7. data/app/assets/javascripts/polaris_view_components.js +533 -63
  8. data/app/assets/stylesheets/polaris_view_components/custom.css +38 -6
  9. data/app/assets/stylesheets/polaris_view_components.css +2102 -2021
  10. data/app/assets/stylesheets/polaris_view_components.postcss.css +1 -1
  11. data/app/components/polaris/action_list/item_component.rb +1 -1
  12. data/app/components/polaris/action_list/section_component.rb +1 -1
  13. data/app/components/polaris/action_list_component.rb +1 -1
  14. data/app/components/polaris/autocomplete/action_component.rb +1 -1
  15. data/app/components/polaris/autocomplete/option_component.rb +1 -1
  16. data/app/components/polaris/autocomplete/section_component.rb +1 -1
  17. data/app/components/polaris/autocomplete_component.rb +9 -2
  18. data/app/components/polaris/avatar_component.rb +1 -1
  19. data/app/components/polaris/badge_component.rb +1 -1
  20. data/app/components/polaris/banner_component.rb +2 -2
  21. data/app/components/polaris/base_button.rb +1 -1
  22. data/app/components/polaris/base_checkbox.rb +1 -1
  23. data/app/components/polaris/base_component.rb +1 -1
  24. data/app/components/polaris/base_radio_button.rb +1 -1
  25. data/app/components/polaris/button_group_component.rb +3 -3
  26. data/app/components/polaris/callout_card_component.rb +1 -1
  27. data/app/components/polaris/caption_component.rb +1 -1
  28. data/app/components/polaris/card/header_component.rb +1 -1
  29. data/app/components/polaris/card/section_component.rb +2 -2
  30. data/app/components/polaris/card_component.rb +1 -1
  31. data/app/components/polaris/checkbox_component.rb +1 -1
  32. data/app/components/polaris/choice_component.rb +1 -1
  33. data/app/components/polaris/choice_list_component.rb +1 -1
  34. data/app/components/polaris/component.rb +6 -1
  35. data/app/components/polaris/data_table/cell_component.rb +1 -1
  36. data/app/components/polaris/data_table/column_component.rb +1 -1
  37. data/app/components/polaris/data_table_component.rb +1 -1
  38. data/app/components/polaris/description_list_component.rb +2 -2
  39. data/app/components/polaris/display_text_component.rb +1 -1
  40. data/app/components/polaris/dropzone_component.html.erb +156 -0
  41. data/app/components/polaris/dropzone_component.rb +150 -0
  42. data/app/components/polaris/empty_state_component.rb +1 -1
  43. data/app/components/polaris/exception_list/item_component.rb +1 -1
  44. data/app/components/polaris/exception_list_component.rb +1 -1
  45. data/app/components/polaris/filters_component.rb +3 -3
  46. data/app/components/polaris/footer_help_component.rb +1 -1
  47. data/app/components/polaris/form_layout/group_component.rb +2 -2
  48. data/app/components/polaris/form_layout/item_component.rb +1 -1
  49. data/app/components/polaris/form_layout_component.rb +1 -1
  50. data/app/components/polaris/frame/save_bar_component.rb +1 -1
  51. data/app/components/polaris/frame/top_bar_component.rb +1 -1
  52. data/app/components/polaris/frame_component.rb +1 -1
  53. data/app/components/polaris/heading_component.rb +1 -1
  54. data/app/components/polaris/headless_button.rb +1 -1
  55. data/app/components/polaris/icon_component.rb +1 -1
  56. data/app/components/polaris/index_table/cell_component.rb +1 -1
  57. data/app/components/polaris/index_table/column_component.rb +1 -1
  58. data/app/components/polaris/index_table_component.rb +1 -1
  59. data/app/components/polaris/inline_error_component.rb +1 -1
  60. data/app/components/polaris/label_component.rb +1 -1
  61. data/app/components/polaris/labelled_component.rb +1 -1
  62. data/app/components/polaris/layout/annotated_section.rb +1 -1
  63. data/app/components/polaris/layout/section.rb +1 -1
  64. data/app/components/polaris/layout_component.rb +1 -1
  65. data/app/components/polaris/link_component.rb +1 -1
  66. data/app/components/polaris/list_component.rb +2 -2
  67. data/app/components/polaris/modal/section_component.rb +1 -1
  68. data/app/components/polaris/modal_component.rb +1 -1
  69. data/app/components/polaris/navigation/item_component.rb +2 -2
  70. data/app/components/polaris/navigation/section_component.rb +2 -2
  71. data/app/components/polaris/navigation_component.rb +1 -1
  72. data/app/components/polaris/option_list/checkbox_component.rb +1 -1
  73. data/app/components/polaris/option_list/option_component.rb +1 -1
  74. data/app/components/polaris/option_list/radio_button_component.rb +1 -1
  75. data/app/components/polaris/option_list/section_component.rb +1 -1
  76. data/app/components/polaris/option_list_component.rb +1 -1
  77. data/app/components/polaris/page_actions_component.rb +1 -1
  78. data/app/components/polaris/page_component.rb +1 -1
  79. data/app/components/polaris/pagination_component.rb +1 -1
  80. data/app/components/polaris/popover/pane_component.rb +1 -1
  81. data/app/components/polaris/popover/section_component.rb +1 -1
  82. data/app/components/polaris/popover_component.rb +10 -4
  83. data/app/components/polaris/progress_bar_component.rb +1 -1
  84. data/app/components/polaris/radio_button_component.rb +1 -1
  85. data/app/components/polaris/resource_item_component.rb +1 -1
  86. data/app/components/polaris/resource_list_component.rb +1 -1
  87. data/app/components/polaris/scrollable_component.rb +1 -1
  88. data/app/components/polaris/select_component.rb +1 -1
  89. data/app/components/polaris/setting_toggle_component.rb +1 -1
  90. data/app/components/polaris/shopify_navigation_component.rb +2 -2
  91. data/app/components/polaris/skeleton_body_text_component.rb +1 -1
  92. data/app/components/polaris/spacer_component.rb +1 -1
  93. data/app/components/polaris/spinner_component.rb +1 -1
  94. data/app/components/polaris/stack/item_component.rb +15 -0
  95. data/app/components/polaris/stack_component.rb +2 -18
  96. data/app/components/polaris/subheading_component.rb +1 -1
  97. data/app/components/polaris/tabs/tab_component.rb +1 -1
  98. data/app/components/polaris/tabs_component.rb +1 -1
  99. data/app/components/polaris/tag_component.rb +3 -2
  100. data/app/components/polaris/text_container_component.rb +1 -1
  101. data/app/components/polaris/text_field_component.rb +2 -2
  102. data/app/components/polaris/text_style_component.rb +1 -1
  103. data/app/components/polaris/thumbnail_component.rb +1 -1
  104. data/app/components/polaris/toast_component.rb +1 -1
  105. data/app/components/polaris/top_bar/user_menu_component.rb +1 -1
  106. data/app/components/polaris/visually_hidden_component.rb +1 -1
  107. data/app/helpers/polaris/form_builder.rb +14 -5
  108. data/app/helpers/polaris/view_helper.rb +2 -1
  109. data/lib/polaris/view_components/engine.rb +5 -1
  110. data/lib/polaris/view_components/version.rb +1 -1
  111. metadata +7 -9
  112. data/app/components/polaris/application_component.rb +0 -35
  113. data/app/components/polaris/dropzone/component.html.erb +0 -72
  114. data/app/components/polaris/dropzone/component.rb +0 -128
  115. data/app/components/polaris/dropzone/controller.js +0 -226
  116. data/app/components/polaris/dropzone/utils.js +0 -57
  117. data/app/components/polaris/new_component.rb +0 -10
  118. data/app/helpers/polaris/conditional_helper.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9e5671bf20a8c0aec20920be9fcea01ba39b902057eec479f30b9d621bdbf50
4
- data.tar.gz: 21bb979fd293cd8379e0e012e9ef2ee9ae06cf62bfdd226fc1ae90ff3b65e9c3
3
+ metadata.gz: 2770c340a3ec833f8538a56a85c52a73cb2a62fdd3e7710713d4af38fe08c838
4
+ data.tar.gz: bb143c334cb2a57b29e3a103d8e2179cd0e3a972e80a908a15e35ecf4e3df669
5
5
  SHA512:
6
- metadata.gz: 638f5ef1f9c7be3d41b1f1b9016f3a8f14f13c3fbc65c5df6ab8f02b7e903f7456a01514f1d5297c3ecbc022bf66d4283a014a602a9a49662b9d99a368d1a88a
7
- data.tar.gz: f482994119dd2a2334bf633eae54cb8998d39d38821efc9d16bd88af92869f7f9e18f418cc1f71e2fdf7bbb0d6558cd449c24ae61f93dd660950104b192f4427
6
+ metadata.gz: 2ac4c9763c823f62b1590928d7b1cc23d549518ae3cb694f0d36128e1fc7bee3def5d9c50008ed5335b42e0d4a66777c525002a1e3060f2060431e630bf5a3b2
7
+ data.tar.gz: 580747d9aa8af31dea5a8a13c6a59ed4cbed2f4ebbe8d2787600d5c411e6659e2efd6047c00c40778e277800fa3a71b903354afc2423f86d39f3dfea4039df9a
@@ -1,9 +1,10 @@
1
1
  import { Controller } from '@hotwired/stimulus'
2
2
  import { get } from '@rails/request.js'
3
+ import { debounce } from './utils'
3
4
 
4
5
  export default class extends Controller {
5
6
  static targets = ['popover', 'input', 'results', 'option', 'emptyState']
6
- static values = { url: String }
7
+ static values = { url: String, selected: Array }
7
8
 
8
9
  connect() {
9
10
  this.inputTarget.addEventListener("input", this.onInputChange)
@@ -16,13 +17,10 @@ export default class extends Controller {
16
17
  // Actions
17
18
 
18
19
  toggle() {
19
- if (this.visibleOptions.length > 0) {
20
- this.hideEmptyState()
21
- this.popoverController.show()
22
- } else if (this.value.length > 0 && this.hasEmptyStateTarget) {
23
- this.showEmptyState()
20
+ if (this.isRemote && this.visibleOptions.length == 0 && this.value.length == 0) {
21
+ this.fetchResults()
24
22
  } else {
25
- this.popoverController.forceHide()
23
+ this.handleResults()
26
24
  }
27
25
  }
28
26
 
@@ -44,6 +42,13 @@ export default class extends Controller {
44
42
  }
45
43
  }, 200)
46
44
 
45
+ reset() {
46
+ this.inputTarget.value = ''
47
+ this.optionTargets.forEach(option => {
48
+ option.classList.add('Polaris--hidden')
49
+ })
50
+ this.handleResults()
51
+ }
47
52
 
48
53
  // Private
49
54
 
@@ -65,6 +70,18 @@ export default class extends Controller {
65
70
  })
66
71
  }
67
72
 
73
+ handleResults() {
74
+ if (this.visibleOptions.length > 0) {
75
+ this.hideEmptyState()
76
+ this.popoverController.show()
77
+ this.checkSelected()
78
+ } else if (this.value.length > 0 && this.hasEmptyStateTarget) {
79
+ this.showEmptyState()
80
+ } else {
81
+ this.popoverController.forceHide()
82
+ }
83
+ }
84
+
68
85
  filterOptions() {
69
86
  if (this.value === '') {
70
87
  this.optionTargets.forEach(option => {
@@ -80,7 +97,7 @@ export default class extends Controller {
80
97
  }
81
98
  })
82
99
  }
83
- this.toggle()
100
+ this.handleResults()
84
101
  }
85
102
 
86
103
  async fetchResults() {
@@ -90,7 +107,7 @@ export default class extends Controller {
90
107
  if (response.ok) {
91
108
  const results = await response.html
92
109
  this.resultsTarget.innerHTML = results
93
- this.toggle()
110
+ this.handleResults()
94
111
  }
95
112
  }
96
113
 
@@ -107,13 +124,13 @@ export default class extends Controller {
107
124
  this.resultsTarget.classList.remove('Polaris--hidden')
108
125
  }
109
126
  }
110
- }
111
127
 
112
- const debounce = (fn, delay = 10) => {
113
- let timeoutId = null
128
+ checkSelected() {
129
+ this.visibleOptions.forEach(option => {
130
+ const input = option.querySelector('input')
131
+ if (!input) return
114
132
 
115
- return (...args) => {
116
- clearTimeout(timeoutId)
117
- timeoutId = setTimeout(fn, delay)
133
+ input.checked = this.selectedValue.includes(input.value)
134
+ })
118
135
  }
119
136
  }
@@ -0,0 +1,495 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { debounce, formatBytes } from './utils'
3
+
4
+ const dragEvents = ['dragover', 'dragenter', 'drop']
5
+ const SIZES = {
6
+ SMALL: 'small',
7
+ MEDIUM: 'medium',
8
+ LARGE: 'large',
9
+ EXTRA_LARGE: 'extraLarge',
10
+ }
11
+
12
+ // eslint-disable-next-line import/no-default-export
13
+ export default class extends Controller {
14
+ static targets = [
15
+ 'container',
16
+ 'fileUpload',
17
+ 'loader',
18
+ 'input',
19
+ 'preview',
20
+ 'previewTemplate',
21
+ 'itemTemplate',
22
+ 'overlay',
23
+ 'errorOverlay'
24
+ ]
25
+ static classes = ['disabled']
26
+ static values = {
27
+ accept: String,
28
+ allowMultiple: Boolean,
29
+ disabled: Boolean,
30
+ dropOnPage: Boolean,
31
+ focused: Boolean,
32
+ renderPreview: Boolean,
33
+ size: String
34
+ }
35
+
36
+ files = []
37
+ acceptedFiles = []
38
+ rejectedFiles = []
39
+ _dragging = false
40
+ dragTargets = []
41
+ previewRendered = false
42
+ _size = 'large'
43
+
44
+ connect () {
45
+ document.body.addEventListener('click', this.onExternalTriggerClick)
46
+ addEventListener('resize', this.onWindowResize)
47
+ addEventListener('direct-uploads:start', this.onDirectUploadsStart)
48
+ addEventListener('direct-uploads:end', this.onDirectUploadsEnd)
49
+ addEventListener('direct-upload:initialize', this.onDirectUploadInitialize)
50
+ addEventListener('direct-upload:start', this.onDirectUploadStart)
51
+ addEventListener('direct-upload:progress', this.onDirectUploadProgress)
52
+ addEventListener('direct-upload:error', this.onDirectUploadError)
53
+ addEventListener('direct-upload:end', this.onDirectUploadEnd)
54
+
55
+ this.onWindowResize()
56
+ }
57
+
58
+ disconnect () {
59
+ document.body.removeEventListener('click', this.onExternalTriggerClick)
60
+ removeEventListener('resize', this.onWindowResize)
61
+ removeEventListener('direct-uploads:start', this.onDirectUploadsStart)
62
+ removeEventListener('direct-uploads:end', this.onDirectUploadsEnd)
63
+ removeEventListener('direct-upload:initialize', this.onDirectUploadInitialize)
64
+ removeEventListener('direct-upload:start', this.onDirectUploadStart)
65
+ removeEventListener('direct-upload:progress', this.onDirectUploadProgress)
66
+ removeEventListener('direct-upload:error', this.onDirectUploadError)
67
+ removeEventListener('direct-upload:end', this.onDirectUploadEnd)
68
+ }
69
+
70
+ onExternalTriggerClick = (event) => {
71
+ const trigger = event.target.closest(`[data-${this.identifier}-external-target="trigger"]`)
72
+ if (!trigger) return
73
+
74
+ event.preventDefault()
75
+
76
+ this.onClick()
77
+ }
78
+
79
+ onWindowResize = debounce(() => {
80
+ const size = this.calculateSize()
81
+
82
+ if (size !== this.size) {
83
+ this.size = size
84
+ }
85
+ }, 50)
86
+
87
+ onBlur () {
88
+ this.focusedValue = false
89
+ }
90
+
91
+ onChange (e) {
92
+ this.stopEvent(e)
93
+ if (this.disabled) return
94
+
95
+ this.clearFiles()
96
+
97
+ const fileList = getDataTransferFiles(e)
98
+ const { files, acceptedFiles, rejectedFiles } = this.getValidatedFiles(fileList)
99
+ this.dragTargets = []
100
+
101
+ this.files = files
102
+ this.acceptedFiles = acceptedFiles
103
+ this.rejectedFiles = rejectedFiles
104
+
105
+ this.render()
106
+ }
107
+
108
+ onDragOver (e) {
109
+ this.stopEvent(e)
110
+ if (this.disabled) return
111
+ }
112
+
113
+ onDragEnter (e) {
114
+ this.stopEvent(e)
115
+ if (this.disabled) return
116
+
117
+ if (e.target && !this.dragTargets.includes(e.target)) {
118
+ this.dragTargets.push(e.target)
119
+ }
120
+
121
+ if (this.dragging) return
122
+
123
+ this.dragging = true
124
+ }
125
+
126
+ onDragLeave (e) {
127
+ this.stopEvent(e)
128
+ if (this.disabled) return
129
+
130
+ this.dragTargets = this.dragTargets.filter(el => {
131
+ const compareNode = this.element
132
+
133
+ return el !== e.target && compareNode && compareNode.contains(el)
134
+ })
135
+
136
+ if (this.dragTargets.length > 0) return
137
+
138
+ this.dragging = false
139
+ }
140
+
141
+ onDrop (e) {
142
+ this.stopEvent(e)
143
+ if (this.disabled) return
144
+
145
+ this.dragging = false
146
+
147
+ this.onChange(e)
148
+ }
149
+
150
+ onFocus () {
151
+ this.focusedValue = true
152
+ }
153
+
154
+ onClick () {
155
+ if (this.disabledValue) return
156
+
157
+ this.open()
158
+ }
159
+
160
+ onDirectUploadsStart = () => {
161
+ this.disable()
162
+ }
163
+
164
+ onDirectUploadsEnd = () => {
165
+ this.enable()
166
+ this.clearFiles()
167
+ this.loaderTarget.classList.remove("Polaris--hidden")
168
+ }
169
+
170
+ onDirectUploadInitialize = (event) => {
171
+ const { target, detail } = event
172
+ const { id, file } = detail
173
+ const dropzone = target.closest('.Polaris-DropZone')
174
+ if (!dropzone) return
175
+
176
+ const content = dropzone.querySelector(`[data-file-name="${file.name}"]`)
177
+ const progressBar = content.parentElement.querySelector('[data-target="progress-bar"]')
178
+ progressBar.id = `direct-upload-${id}`
179
+ }
180
+
181
+ onDirectUploadStart = (event) => {
182
+ const { id } = event.detail
183
+ const progressBar = document.getElementById(`direct-upload-${id}`)
184
+ if (!progressBar) return
185
+
186
+ progressBar.classList.remove("Polaris--hidden")
187
+ }
188
+
189
+ onDirectUploadProgress = (event) => {
190
+ const { id, progress } = event.detail
191
+ const progressBar = document.getElementById(`direct-upload-${id}`)
192
+ if (!progressBar) return
193
+
194
+ const progressElement = progressBar.querySelector('.Polaris-ProgressBar__Indicator')
195
+ progressElement.style.width = `${progress}%`
196
+ }
197
+
198
+ onDirectUploadError = (event) => {
199
+ const { id, error } = event.detail
200
+ const progressBar = document.getElementById(`direct-upload-${id}`)
201
+ if (!progressBar) return
202
+
203
+ event.preventDefault()
204
+ progressBar.classList.add("Polaris--hidden")
205
+ const uploadError = progressBar.parentElement.querySelector('[data-target="upload-error"]')
206
+ const errorIcon = uploadError.querySelector('.Polaris-InlineError__Icon')
207
+ if (errorIcon) errorIcon.remove()
208
+ uploadError.classList.remove("Polaris--hidden")
209
+ }
210
+
211
+ onDirectUploadEnd = (event) => {
212
+ const { id } = event.detail
213
+ const progressBar = document.getElementById(`direct-upload-${id}`)
214
+ if (!progressBar) return
215
+
216
+ progressBar.classList.add("Polaris-ProgressBar--colorSuccess")
217
+ }
218
+
219
+ open () {
220
+ this.inputTarget.click()
221
+ }
222
+
223
+ focusedValueChanged () {
224
+ this.element.classList.toggle('Polaris-DropZone--focused', this.focusedValue)
225
+ }
226
+
227
+ stopEvent (e) {
228
+ e.preventDefault()
229
+ e.stopPropagation()
230
+ }
231
+
232
+ getValidatedFiles (files) {
233
+ const acceptedFiles = []
234
+ const rejectedFiles = []
235
+
236
+ Array.from(files).forEach(file => {
237
+ if (fileAccepted(file, this.acceptValue)) {
238
+ acceptedFiles.push(file)
239
+ } else {
240
+ rejectedFiles.push(file)
241
+ }
242
+ })
243
+
244
+ if (!this.allowMultipleValue) {
245
+ acceptedFiles.splice(1, acceptedFiles.length)
246
+ rejectedFiles.push(...acceptedFiles.slice(1))
247
+ }
248
+
249
+ return { files, acceptedFiles, rejectedFiles }
250
+ }
251
+
252
+ render () {
253
+ if (this.files.length === 0) {
254
+ this.toggleFileUpload(true)
255
+ this.toggleErrorOverlay(false)
256
+ } else if (this.rejectedFiles.length > 0) {
257
+ this.toggleFileUpload(false)
258
+ this.toggleErrorOverlay(true)
259
+
260
+ const dropRejectedEvent = new CustomEvent('polaris-dropzone:drop-rejected', {
261
+ detail: { rejectedFiles: this.rejectedFiles }
262
+ })
263
+ this.element.dispatchEvent(dropRejectedEvent)
264
+ } else if (this.acceptedFiles.length > 0) {
265
+ if (this.renderPreviewValue) {
266
+ this.renderUploadedFiles()
267
+ this.toggleFileUpload(false)
268
+ }
269
+
270
+ this.toggleErrorOverlay(false)
271
+
272
+ const dropAcceptedEvent = new CustomEvent('polaris-dropzone:drop-accepted', {
273
+ detail: {acceptedFiles: this.acceptedFiles }
274
+ })
275
+ this.element.dispatchEvent(dropAcceptedEvent)
276
+ }
277
+
278
+ const dropEvent = new CustomEvent('polaris-dropzone:drop', {
279
+ detail: {
280
+ files: this.files,
281
+ acceptedFiles: this.acceptedFiles,
282
+ rejectedFiles: this.rejectedFiles
283
+ }
284
+ })
285
+ this.element.dispatchEvent(dropEvent)
286
+ }
287
+
288
+ renderUploadedFiles () {
289
+ if (this.acceptedFiles.length === 0) return
290
+
291
+ const clone = this.previewTemplateTarget.content.cloneNode(true)
292
+ const filesTarget = clone.querySelector('.target')
293
+ let files = this.acceptedFiles
294
+
295
+ if (this.sizeValue == 'small') files = [files[0]]
296
+
297
+ files
298
+ .map(file => this.renderFile(file))
299
+ .forEach(fragment => filesTarget.parentNode.appendChild(fragment))
300
+ filesTarget.remove()
301
+
302
+ this.containerTarget.prepend(clone)
303
+
304
+ this.previewRendered = true
305
+ }
306
+
307
+ toggleFileUpload (show = false) {
308
+ this.fileUploadTarget.classList.toggle('Polaris-VisuallyHidden', !show)
309
+ }
310
+
311
+ toggleErrorOverlay (show = false) {
312
+ this.errorOverlayTarget.classList.toggle('Polaris-VisuallyHidden', !show)
313
+ this.element.classList.toggle('Polaris-DropZone--hasError', show)
314
+ }
315
+
316
+ renderFile (file) {
317
+ const validImageTypes = ['image/gif', 'image/jpeg', 'image/png']
318
+ const clone = this.itemTemplateTarget.content.cloneNode(true)
319
+ const [icon, thumbnail, content, fileSize] = [
320
+ clone.querySelector('[data-target="icon"]'),
321
+ clone.querySelector('[data-target="thumbnail"]'),
322
+ clone.querySelector('[data-target="content"]'),
323
+ clone.querySelector('[data-target="file-size"]')
324
+ ]
325
+
326
+ if (validImageTypes.includes(file.type)) {
327
+ const img = thumbnail.querySelector('img')
328
+ img.alt = file.name
329
+ img.src = window.URL.createObjectURL(file)
330
+ icon.remove()
331
+ } else {
332
+ thumbnail.remove()
333
+ }
334
+
335
+ if (this.sizeValue != 'small') {
336
+ content.insertAdjacentText('afterbegin', file.name)
337
+ content.setAttribute('data-file-name', file.name)
338
+ fileSize.textContent = formatBytes(file.size)
339
+ }
340
+
341
+ return clone
342
+ }
343
+
344
+ clearFiles () {
345
+ if (!this.previewRendered) return
346
+
347
+ this.acceptedFiles = []
348
+ this.files = []
349
+ this.rejectedFiles = []
350
+
351
+ if (!this.hasPreviewTarget) return
352
+
353
+ this.previewTarget.remove()
354
+ this.previewRendered = false
355
+ }
356
+
357
+ calculateSize () {
358
+ const width = this.element.getBoundingClientRect().width
359
+
360
+ let size = SIZES.LARGE
361
+
362
+ if (width < 100) {
363
+ size = SIZES.SMALL
364
+ } else if (width < 160) {
365
+ size = SIZES.MEDIUM
366
+ } else if (width > 300) {
367
+ size = SIZES.EXTRA_LARGE
368
+ }
369
+
370
+ this.size = size
371
+
372
+ return size
373
+ }
374
+
375
+ getSizeClass (size = 'large') {
376
+ return this.sizeClassesSchema[size] || this.sizeClassesSchema.large
377
+ }
378
+
379
+ disable() {
380
+ this.disabled = true
381
+ this.element.classList.add(this.disabledClass)
382
+ this.inputTarget.disabled = true
383
+ }
384
+
385
+ enable() {
386
+ this.disabled = false
387
+ this.element.classList.remove(this.disabledClass)
388
+ this.inputTarget.disabled = false
389
+ }
390
+
391
+ get fileListRendered () {
392
+ return this.element.querySelector('[data-rendered]')
393
+ }
394
+
395
+ get dropNode () {
396
+ return this.dropOnPageValue ? document : this.element
397
+ }
398
+
399
+ get disabled () {
400
+ return this.disabledValue
401
+ }
402
+
403
+ set disabled (val) {
404
+ this.disabledValue = val
405
+ }
406
+
407
+ get dragging () {
408
+ return this._dragging
409
+ }
410
+
411
+ set dragging (val) {
412
+ this._dragging = val
413
+
414
+ this.element.classList.toggle('Polaris-DropZone--isDragging', val)
415
+ this.overlayTarget.classList.toggle('Polaris-VisuallyHidden', !val)
416
+ }
417
+
418
+ get sizeClassesSchema () {
419
+ return {
420
+ [SIZES.SMALL]: 'Polaris-DropZone--sizeSmall',
421
+ [SIZES.MEDIUM]: 'Polaris-DropZone--sizeMedium',
422
+ [SIZES.LARGE]: 'Polaris-DropZone--sizeLarge',
423
+ [SIZES.EXTRA_LARGE]: 'Polaris-DropZone--sizeExtraLarge',
424
+ }
425
+ }
426
+
427
+ get size () {
428
+ return this._size
429
+ }
430
+
431
+ set size (val) {
432
+ this._size = val
433
+
434
+ const sizeClassesToRemove = Object.values(this.sizeClassesSchema)
435
+ sizeClassesToRemove.forEach(className => this.element.classList.remove(className))
436
+
437
+ this.element.classList.add(this.getSizeClass(val))
438
+ }
439
+ }
440
+
441
+ export function fileAccepted (file, accept) {
442
+ return file.type === 'application/x-moz-file' || accepts(file, accept)
443
+ }
444
+
445
+ export function getDataTransferFiles (event) {
446
+ if (isDragEvent(event) && event.dataTransfer) {
447
+ const dt = event.dataTransfer
448
+
449
+ if (dt.files && dt.files.length) {
450
+ return Array.from(dt.files)
451
+ } else if (dt.items && dt.items.length) {
452
+ // Chrome is the only browser that allows to read the file list on drag
453
+ // events and uses `items` instead of `files` in this case.
454
+ return Array.from(dt.items)
455
+ }
456
+ } else if (isChangeEvent(event) && event.target.files) {
457
+ // Return files from even when a file was selected from an upload dialog
458
+ return Array.from(event.target.files)
459
+ }
460
+
461
+ return []
462
+ }
463
+
464
+ function accepts (file, acceptedFiles = ['']) {
465
+ if (file && acceptedFiles) {
466
+ const fileName = file.name || ''
467
+ const mimeType = file.type || ''
468
+ const baseMimeType = mimeType.replace(/\/.*$/, '')
469
+ const acceptedFilesArray = Array.isArray(acceptedFiles)
470
+ ? acceptedFiles
471
+ : acceptedFiles.split(',')
472
+
473
+ return acceptedFilesArray.some((type) => {
474
+ const validType = type.trim()
475
+ if (validType.startsWith('.')) {
476
+ return fileName.toLowerCase().endsWith(validType.toLowerCase())
477
+ } else if (validType.endsWith('/*')) {
478
+ // This is something like a image/* mime type
479
+ return baseMimeType === validType.replace(/\/.*$/, '')
480
+ }
481
+
482
+ return mimeType === validType
483
+ })
484
+ }
485
+
486
+ return true
487
+ }
488
+
489
+ function isDragEvent (event) {
490
+ return dragEvents.indexOf(event.type) > 0
491
+ }
492
+
493
+ function isChangeEvent (event) {
494
+ return event.type === 'change'
495
+ }
@@ -1,5 +1,6 @@
1
1
  import Autocomplete from './autocomplete_controller'
2
2
  import Button from './button_controller'
3
+ import Dropzone from './dropzone_controller'
3
4
  import Frame from './frame_controller'
4
5
  import Modal from './modal_controller'
5
6
  import OptionList from './option_list_controller'
@@ -16,6 +17,7 @@ export { Frame, Modal, Polaris, Popover, ResourceItem, Scrollable, Select, TextF
16
17
  export function registerPolarisControllers(application) {
17
18
  application.register('polaris-autocomplete', Autocomplete)
18
19
  application.register('polaris-button', Button)
20
+ application.register('polaris-dropzone', Dropzone)
19
21
  application.register('polaris-frame', Frame)
20
22
  application.register('polaris-modal', Modal)
21
23
  application.register('polaris-option-list', OptionList)
@@ -10,7 +10,7 @@ export default class extends Controller {
10
10
  }
11
11
 
12
12
  connect() {
13
- createPopper(this.activatorTarget, this.popoverTarget, {
13
+ this.popper = createPopper(this.activatorTarget, this.popoverTarget, {
14
14
  placement: this.placementValue,
15
15
  modifiers: [
16
16
  {
@@ -19,6 +19,12 @@ export default class extends Controller {
19
19
  offset: [0, 5],
20
20
  },
21
21
  },
22
+ {
23
+ name: 'flip',
24
+ options: {
25
+ allowedAutoPlacements: ['top-start', 'bottom-start', 'top-end', 'bottom-end']
26
+ },
27
+ }
22
28
  ]
23
29
  })
24
30
  if (this.activeValue) {
@@ -31,9 +37,10 @@ export default class extends Controller {
31
37
  this.popoverTarget.classList.toggle(this.openClass)
32
38
  }
33
39
 
34
- show() {
40
+ async show() {
35
41
  this.popoverTarget.classList.remove(this.closedClass)
36
42
  this.popoverTarget.classList.add(this.openClass)
43
+ await this.popper.update()
37
44
  }
38
45
 
39
46
  hide(event) {
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @param {Function} fn
3
+ * @param {number} wait
4
+ *
5
+ * @return {Function}
6
+ */
7
+ export function debounce (fn, wait) {
8
+ let timeoutId
9
+
10
+ return (...args) => {
11
+ clearTimeout(timeoutId)
12
+ timeoutId = setTimeout(() => fn.apply(this, args), wait)
13
+ }
14
+ }
15
+
16
+ export function formatBytes (bytes, decimals) {
17
+ if (bytes == 0) return '0 Bytes'
18
+ const k = 1024,
19
+ dm = decimals || 2,
20
+ sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
21
+ i = Math.floor(Math.log(bytes) / Math.log(k))
22
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
23
+ }