polaris_view_components 0.9.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/polaris_view_components/dropzone_controller.js +31 -4
- data/app/assets/javascripts/polaris_view_components/frame_controller.js +1 -1
- data/app/assets/javascripts/polaris_view_components/text_field_controller.js +5 -0
- data/app/assets/javascripts/polaris_view_components/{utils.js → utils/index.js} +3 -1
- data/app/assets/javascripts/polaris_view_components/utils/use-transition.js +162 -0
- data/app/assets/javascripts/polaris_view_components.js +184 -161
- data/app/assets/stylesheets/polaris_view_components/custom.css +37 -0
- data/app/assets/stylesheets/polaris_view_components.css +30 -0
- data/app/components/polaris/action_list/item_component.rb +2 -1
- data/app/components/polaris/button_component.html.erb +2 -2
- data/app/components/polaris/dropzone_component.html.erb +9 -6
- data/app/components/polaris/filters_component.rb +3 -1
- data/app/components/polaris/headless_button.html.erb +2 -2
- data/app/components/polaris/headless_button.rb +3 -1
- data/app/components/polaris/page_component.html.erb +81 -10
- data/app/components/polaris/page_component.rb +85 -28
- data/app/components/polaris/resource_item_component.rb +4 -1
- data/app/components/polaris/text_field_component.html.erb +1 -1
- data/app/components/polaris/text_field_component.rb +1 -1
- data/app/components/polaris/visually_hidden_component.rb +0 -3
- data/lib/polaris/view_components/version.rb +1 -1
- metadata +89 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6559d19f7338ce9195fa1903e58f14596006d813bbc30599061bce4c00d49c9d
|
4
|
+
data.tar.gz: 61223fea9beddaa96b4762b8b7dc00cf42051a462e92bab25733d6f35b232ae2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ad6e0a1dc0f3f491e6beeae7dc4c6c72a8a077ec0b6f6c4cc04e95723761aa93181d663ef9f9f52945d5fad3be40a9d3a3b7e3f64504f9e347925b733841fb5
|
7
|
+
data.tar.gz: 4b5b661dbd74e991dde7e7386f33b65caeaac53839b0c3c0d3951acb30f5179d1d007d97a08c058024c7e1a4e72d56fba8ba0d0a12729b885ebecf458a4116b3
|
data/README.md
CHANGED
@@ -34,11 +34,12 @@ export default class extends Controller {
|
|
34
34
|
}
|
35
35
|
|
36
36
|
files = []
|
37
|
-
acceptedFiles = []
|
38
37
|
rejectedFiles = []
|
39
38
|
_dragging = false
|
40
39
|
dragTargets = []
|
41
40
|
previewRendered = false
|
41
|
+
|
42
|
+
_acceptedFiles = []
|
42
43
|
_size = 'large'
|
43
44
|
|
44
45
|
connect () {
|
@@ -164,6 +165,9 @@ export default class extends Controller {
|
|
164
165
|
onDirectUploadsEnd = () => {
|
165
166
|
this.enable()
|
166
167
|
this.clearFiles()
|
168
|
+
|
169
|
+
if (this.acceptedFiles.length === 0) return
|
170
|
+
|
167
171
|
this.loaderTarget.classList.remove("Polaris--hidden")
|
168
172
|
}
|
169
173
|
|
@@ -172,10 +176,16 @@ export default class extends Controller {
|
|
172
176
|
const { id, file } = detail
|
173
177
|
const dropzone = target.closest('.Polaris-DropZone')
|
174
178
|
if (!dropzone) return
|
179
|
+
if (this.acceptedFiles.length === 0) return
|
175
180
|
|
176
|
-
|
177
|
-
|
178
|
-
|
181
|
+
if (this.sizeValue == 'small') {
|
182
|
+
this.clearFiles()
|
183
|
+
this.loaderTarget.classList.remove("Polaris--hidden")
|
184
|
+
} else {
|
185
|
+
const content = dropzone.querySelector(`[data-file-name="${file.name}"]`)
|
186
|
+
const progressBar = content.parentElement.querySelector('[data-target="progress-bar"]')
|
187
|
+
progressBar.id = `direct-upload-${id}`
|
188
|
+
}
|
179
189
|
}
|
180
190
|
|
181
191
|
onDirectUploadStart = (event) => {
|
@@ -258,6 +268,7 @@ export default class extends Controller {
|
|
258
268
|
this.toggleErrorOverlay(true)
|
259
269
|
|
260
270
|
const dropRejectedEvent = new CustomEvent('polaris-dropzone:drop-rejected', {
|
271
|
+
bubbles: true,
|
261
272
|
detail: { rejectedFiles: this.rejectedFiles }
|
262
273
|
})
|
263
274
|
this.element.dispatchEvent(dropRejectedEvent)
|
@@ -270,12 +281,14 @@ export default class extends Controller {
|
|
270
281
|
this.toggleErrorOverlay(false)
|
271
282
|
|
272
283
|
const dropAcceptedEvent = new CustomEvent('polaris-dropzone:drop-accepted', {
|
284
|
+
bubbles: true,
|
273
285
|
detail: {acceptedFiles: this.acceptedFiles }
|
274
286
|
})
|
275
287
|
this.element.dispatchEvent(dropAcceptedEvent)
|
276
288
|
}
|
277
289
|
|
278
290
|
const dropEvent = new CustomEvent('polaris-dropzone:drop', {
|
291
|
+
bubbles: true,
|
279
292
|
detail: {
|
280
293
|
files: this.files,
|
281
294
|
acceptedFiles: this.acceptedFiles,
|
@@ -436,6 +449,20 @@ export default class extends Controller {
|
|
436
449
|
|
437
450
|
this.element.classList.add(this.getSizeClass(val))
|
438
451
|
}
|
452
|
+
|
453
|
+
get acceptedFiles () {
|
454
|
+
return this._acceptedFiles
|
455
|
+
}
|
456
|
+
|
457
|
+
set acceptedFiles (val) {
|
458
|
+
this._acceptedFiles = val
|
459
|
+
|
460
|
+
const list = new DataTransfer()
|
461
|
+
|
462
|
+
val.forEach(file => list.items.add(file))
|
463
|
+
|
464
|
+
this.inputTarget.files = list.files
|
465
|
+
}
|
439
466
|
}
|
440
467
|
|
441
468
|
export function fileAccepted (file, accept) {
|
@@ -4,7 +4,7 @@
|
|
4
4
|
*
|
5
5
|
* @return {Function}
|
6
6
|
*/
|
7
|
-
export function debounce (fn, wait) {
|
7
|
+
export function debounce (fn, wait) {
|
8
8
|
let timeoutId
|
9
9
|
|
10
10
|
return (...args) => {
|
@@ -21,3 +21,5 @@ export function formatBytes (bytes, decimals) {
|
|
21
21
|
i = Math.floor(Math.log(bytes) / Math.log(k))
|
22
22
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
23
23
|
}
|
24
|
+
|
25
|
+
export { useTransition } from "./use-transition"
|
@@ -0,0 +1,162 @@
|
|
1
|
+
const alpineNames = {
|
2
|
+
enterFromClass: 'enter',
|
3
|
+
enterActiveClass: 'enterStart',
|
4
|
+
enterToClass: 'enterEnd',
|
5
|
+
leaveFromClass: 'leave',
|
6
|
+
leaveActiveClass: 'leaveStart',
|
7
|
+
leaveToClass: 'leaveEnd'
|
8
|
+
}
|
9
|
+
const defaultOptions = {
|
10
|
+
transitioned: false,
|
11
|
+
hiddenClass: 'hidden',
|
12
|
+
preserveOriginalClass: true,
|
13
|
+
removeToClasses: true
|
14
|
+
};
|
15
|
+
export const useTransition = (controller, options = {}) => {
|
16
|
+
var _a, _b, _c;
|
17
|
+
const targetName = controller.element.dataset.transitionTarget;
|
18
|
+
let targetFromAttribute;
|
19
|
+
if (targetName) {
|
20
|
+
targetFromAttribute = controller[`${targetName}Target`];
|
21
|
+
}
|
22
|
+
const targetElement = (options === null || options === void 0 ? void 0 : options.element) || targetFromAttribute || controller.element;
|
23
|
+
// data attributes are only available on HTMLElement and SVGElement
|
24
|
+
if (!(targetElement instanceof HTMLElement || targetElement instanceof SVGElement))
|
25
|
+
return;
|
26
|
+
const dataset = targetElement.dataset;
|
27
|
+
const leaveAfter = parseInt(dataset.leaveAfter || '') || options.leaveAfter || 0;
|
28
|
+
const { transitioned, hiddenClass, preserveOriginalClass, removeToClasses } = Object.assign(defaultOptions, options);
|
29
|
+
const controllerEnter = (_a = controller.enter) === null || _a === void 0 ? void 0 : _a.bind(controller);
|
30
|
+
const controllerLeave = (_b = controller.leave) === null || _b === void 0 ? void 0 : _b.bind(controller);
|
31
|
+
const controllerToggleTransition = (_c = controller.toggleTransition) === null || _c === void 0 ? void 0 : _c.bind(controller);
|
32
|
+
async function enter(event) {
|
33
|
+
if (controller.transitioned)
|
34
|
+
return;
|
35
|
+
controller.transitioned = true;
|
36
|
+
controllerEnter && controllerEnter(event);
|
37
|
+
const enterFromClasses = getAttribute('enterFrom', options, dataset);
|
38
|
+
const enterActiveClasses = getAttribute('enterActive', options, dataset);
|
39
|
+
const enterToClasses = getAttribute('enterTo', options, dataset);
|
40
|
+
const leaveToClasses = getAttribute('leaveTo', options, dataset);
|
41
|
+
if (!!hiddenClass) {
|
42
|
+
targetElement.classList.remove(hiddenClass);
|
43
|
+
}
|
44
|
+
if (!removeToClasses) {
|
45
|
+
removeClasses(targetElement, leaveToClasses);
|
46
|
+
}
|
47
|
+
await transition(targetElement, enterFromClasses, enterActiveClasses, enterToClasses, hiddenClass, preserveOriginalClass, removeToClasses);
|
48
|
+
if (leaveAfter > 0) {
|
49
|
+
setTimeout(() => {
|
50
|
+
leave(event);
|
51
|
+
}, leaveAfter);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
async function leave(event) {
|
55
|
+
if (!controller.transitioned)
|
56
|
+
return;
|
57
|
+
controller.transitioned = false;
|
58
|
+
controllerLeave && controllerLeave(event);
|
59
|
+
const leaveFromClasses = getAttribute('leaveFrom', options, dataset);
|
60
|
+
const leaveActiveClasses = getAttribute('leaveActive', options, dataset);
|
61
|
+
const leaveToClasses = getAttribute('leaveTo', options, dataset);
|
62
|
+
const enterToClasses = getAttribute('enterTo', options, dataset);
|
63
|
+
if (!removeToClasses) {
|
64
|
+
removeClasses(targetElement, enterToClasses);
|
65
|
+
}
|
66
|
+
await transition(targetElement, leaveFromClasses, leaveActiveClasses, leaveToClasses, hiddenClass, preserveOriginalClass, removeToClasses);
|
67
|
+
if (!!hiddenClass) {
|
68
|
+
targetElement.classList.add(hiddenClass);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
function toggleTransition(event) {
|
72
|
+
controllerToggleTransition && controllerToggleTransition(event);
|
73
|
+
if (controller.transitioned) {
|
74
|
+
leave();
|
75
|
+
}
|
76
|
+
else {
|
77
|
+
enter();
|
78
|
+
}
|
79
|
+
}
|
80
|
+
async function transition(element, initialClasses, activeClasses, endClasses, hiddenClass, preserveOriginalClass, removeEndClasses) {
|
81
|
+
// if there's any overlap between the current set of classes and initialClasses/activeClasses/endClasses,
|
82
|
+
// we should remove them before we start and add them back at the end
|
83
|
+
const stashedClasses = [];
|
84
|
+
if (preserveOriginalClass) {
|
85
|
+
initialClasses.forEach(cls => element.classList.contains(cls) && cls !== hiddenClass && stashedClasses.push(cls));
|
86
|
+
activeClasses.forEach(cls => element.classList.contains(cls) && cls !== hiddenClass && stashedClasses.push(cls));
|
87
|
+
endClasses.forEach(cls => element.classList.contains(cls) && cls !== hiddenClass && stashedClasses.push(cls));
|
88
|
+
}
|
89
|
+
// Add initial class before element start transition
|
90
|
+
addClasses(element, initialClasses);
|
91
|
+
// remove the overlapping classes
|
92
|
+
removeClasses(element, stashedClasses);
|
93
|
+
// Add active class before element start transition and maitain it during the entire transition.
|
94
|
+
addClasses(element, activeClasses);
|
95
|
+
await nextAnimationFrame();
|
96
|
+
// remove the initial class on frame after the beginning of the transition
|
97
|
+
removeClasses(element, initialClasses);
|
98
|
+
// add the endClass on frame after the beginning of the transition
|
99
|
+
addClasses(element, endClasses);
|
100
|
+
// dynamically comput the duration of the transition from the style of the element
|
101
|
+
await afterTransition(element);
|
102
|
+
// remove both activeClasses and endClasses
|
103
|
+
removeClasses(element, activeClasses);
|
104
|
+
if (removeEndClasses) {
|
105
|
+
removeClasses(element, endClasses);
|
106
|
+
}
|
107
|
+
// restore the overlaping classes
|
108
|
+
addClasses(element, stashedClasses);
|
109
|
+
}
|
110
|
+
function initialState() {
|
111
|
+
controller.transitioned = transitioned;
|
112
|
+
if (transitioned) {
|
113
|
+
if (!!hiddenClass) {
|
114
|
+
targetElement.classList.remove(hiddenClass);
|
115
|
+
}
|
116
|
+
enter();
|
117
|
+
}
|
118
|
+
else {
|
119
|
+
if (!!hiddenClass) {
|
120
|
+
targetElement.classList.add(hiddenClass);
|
121
|
+
}
|
122
|
+
leave();
|
123
|
+
}
|
124
|
+
}
|
125
|
+
function addClasses(element, classes) {
|
126
|
+
if (classes.length > 0) {
|
127
|
+
element.classList.add(...classes);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
function removeClasses(element, classes) {
|
131
|
+
if (classes.length > 0) {
|
132
|
+
element.classList.remove(...classes);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
initialState();
|
136
|
+
Object.assign(controller, { enter, leave, toggleTransition });
|
137
|
+
return [enter, leave, toggleTransition];
|
138
|
+
};
|
139
|
+
function getAttribute(name, options, dataset) {
|
140
|
+
const datasetName = `transition${name[0].toUpperCase()}${name.substr(1)}`;
|
141
|
+
const datasetAlpineName = alpineNames[name];
|
142
|
+
const classes = options[name] || dataset[datasetName] || dataset[datasetAlpineName] || ' ';
|
143
|
+
return isEmpty(classes) ? [] : classes.split(' ');
|
144
|
+
}
|
145
|
+
async function afterTransition(element) {
|
146
|
+
return new Promise(resolve => {
|
147
|
+
const duration = Number(getComputedStyle(element).transitionDuration.split(',')[0].replace('s', '')) * 1000;
|
148
|
+
setTimeout(() => {
|
149
|
+
resolve(duration);
|
150
|
+
}, duration);
|
151
|
+
});
|
152
|
+
}
|
153
|
+
async function nextAnimationFrame() {
|
154
|
+
return new Promise(resolve => {
|
155
|
+
requestAnimationFrame(() => {
|
156
|
+
requestAnimationFrame(resolve);
|
157
|
+
});
|
158
|
+
});
|
159
|
+
}
|
160
|
+
function isEmpty(str) {
|
161
|
+
return str.length === 0 || !str.trim();
|
162
|
+
}
|