coveragebook_components 0.5.0 → 0.5.1
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.
- checksums.yaml +4 -4
- data/app/assets/build/coco/app.css +7 -5
- data/app/assets/build/coco/app.js +95 -48
- data/app/assets/build/coco/book.css +3 -0
- data/app/assets/build/coco/book.js +2 -2
- data/app/assets/js/helpers/path.js +9 -1
- data/app/components/coco/app/blocks/slide_editor/slide_editor.css +4 -0
- data/app/components/coco/app/blocks/slide_editor/slide_editor.html.erb +145 -190
- data/app/components/coco/app/blocks/slide_editor/slide_editor.js +70 -17
- data/app/components/coco/app/blocks/slide_editor/slide_editor.rb +37 -86
- data/app/components/coco/app/elements/alert/alert.css +1 -1
- data/app/components/coco/app/elements/color_picker_button/color_picker_button.html.erb +17 -16
- data/app/components/coco/app/elements/color_picker_button/color_picker_button.js +0 -8
- data/app/components/coco/app/elements/color_picker_button/color_picker_button.rb +2 -15
- data/app/components/coco/app/elements/image_picker/image_picker.html.erb +4 -4
- data/app/components/coco/app/elements/image_picker/image_picker.js +18 -6
- data/app/components/coco/app/elements/image_picker/image_picker.rb +2 -11
- data/app/components/coco/app/elements/image_picker_button/image_picker_button.html.erb +9 -8
- data/app/components/coco/app/elements/image_picker_button/image_picker_button.js +10 -23
- data/app/components/coco/app/elements/image_picker_button/image_picker_button.rb +19 -35
- data/app/components/coco/app/elements/seamless_textarea/seamless_textarea.html.erb +7 -4
- data/app/components/coco/app/elements/seamless_textarea/seamless_textarea.js +9 -3
- data/app/components/coco/app/elements/seamless_textarea/seamless_textarea.rb +5 -20
- data/app/components/coco/base/image_uploader/image_uploader.html.erb +3 -2
- data/app/components/coco/base/image_uploader/image_uploader.rb +2 -12
- data/app/components/coco/book/blocks/slides/media_slide/media_slide.css +1 -1
- data/lib/coco.rb +1 -1
- metadata +2 -6
- data/app/assets/build/coco/app.dev.css +0 -3427
- data/app/assets/build/coco/app.dev.js +0 -24891
- data/app/assets/build/coco/book.dev.css +0 -992
- data/app/assets/build/coco/book.dev.js +0 -19840
@@ -1,218 +1,172 @@
|
|
1
1
|
<%= render component_tag(x: {
|
2
2
|
data: x_data("appSlideEditor", alpine_props),
|
3
|
-
":class": "{ready}"
|
4
|
-
"@direct-upload:error": "directUploadError",
|
3
|
+
":class": "{ready}"
|
5
4
|
}) do %>
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
<% toolbar.with_section do |section| %>
|
19
|
-
<% if bg_color? %>
|
20
|
-
<% section.with_color_picker_button(
|
21
|
-
input_name: bg_color_name,
|
22
|
-
selected: bg_color_value,
|
23
|
-
form_builder: f,
|
24
|
-
wrapper: {
|
25
|
-
data: {
|
26
|
-
role: "bg-color-picker"
|
27
|
-
},
|
28
|
-
x: {
|
29
|
-
modelable: "selectedColor",
|
30
|
-
model: "bgColor"
|
31
|
-
}
|
5
|
+
<div class="editor-toolbar">
|
6
|
+
<%= coco_toolbar do |toolbar| %>
|
7
|
+
<% toolbar.with_section do |section| %>
|
8
|
+
<% if bg_color? %>
|
9
|
+
<% section.with_color_picker_button(
|
10
|
+
**@bg_color_options.to_h,
|
11
|
+
wrapper: {
|
12
|
+
data: {
|
13
|
+
role: "bg-color-picker"
|
14
|
+
},
|
15
|
+
x: {
|
16
|
+
"@color-picker:change": "bgColor = $event.detail.color"
|
32
17
|
}
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
18
|
+
}
|
19
|
+
) do |button| %>
|
20
|
+
<% button.with_picker %>
|
21
|
+
<% button.with_text { "Background colour" } %>
|
22
|
+
<% button.with_icon do %>
|
23
|
+
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" class="editor-icon-bg-color">
|
24
|
+
<path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z"></path>
|
25
|
+
</svg>
|
41
26
|
<% end %>
|
42
27
|
<% end %>
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
x: {
|
56
|
-
modelable: "selectedImage",
|
57
|
-
model: "bgImage"
|
58
|
-
}
|
28
|
+
<% end %>
|
29
|
+
|
30
|
+
<% if bg_image? %>
|
31
|
+
<% section.with_image_picker_button(
|
32
|
+
icon: :image_plus,
|
33
|
+
src: bg_image_src,
|
34
|
+
wrapper: {
|
35
|
+
data: {
|
36
|
+
role: "bg-image-picker"
|
37
|
+
},
|
38
|
+
x: {
|
39
|
+
"@image-picker:change": "bgImage = $event.detail.image"
|
59
40
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
41
|
+
}
|
42
|
+
) do |button| %>
|
43
|
+
<% button.with_picker do |picker| %>
|
44
|
+
<% picker.with_blank_state_text do %>
|
45
|
+
Drag a jpg, png or gif onto the slide area or…
|
65
46
|
<% end %>
|
66
|
-
|
67
|
-
Background image
|
68
47
|
<% end %>
|
48
|
+
|
49
|
+
Background image
|
69
50
|
<% end %>
|
51
|
+
<% end %>
|
70
52
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
x: {
|
81
|
-
modelable: "selectedColor",
|
82
|
-
model: "textColor"
|
83
|
-
}
|
53
|
+
<% if text_color? %>
|
54
|
+
<% section.with_color_picker_button(
|
55
|
+
**@text_color_options.to_h,
|
56
|
+
wrapper: {
|
57
|
+
data: {
|
58
|
+
role: "text-color-picker"
|
59
|
+
},
|
60
|
+
x: {
|
61
|
+
"@color-picker:change": "textColor = $event.detail.color"
|
84
62
|
}
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
63
|
+
}
|
64
|
+
) do |button| %>
|
65
|
+
<% button.with_picker %>
|
66
|
+
<% button.with_text { "Text colour" } %>
|
67
|
+
<% button.with_icon do %>
|
68
|
+
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" class="editor-icon-text-color">
|
69
|
+
<path d="M4.99994 13.3333L9.99994 3.33334L14.9999 13.3333" stroke="#111827" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
70
|
+
<path d="M6.66656 10H13.3332" stroke="#111827" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
71
|
+
<rect x="2.25" y="15.25" width="15.5" height="2.5" rx="1.25" fill="currentColor" stroke="#111827" stroke-width="0.5"/>
|
72
|
+
</svg>
|
95
73
|
<% end %>
|
96
74
|
<% end %>
|
97
75
|
<% end %>
|
76
|
+
<% end %>
|
98
77
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
78
|
+
<% toolbar.with_section do |section| %>
|
79
|
+
<% section.with_button(
|
80
|
+
icon: :undo_2,
|
81
|
+
click: "history.undo",
|
82
|
+
tooltip: "Undo",
|
83
|
+
theme: :text_secondary,
|
84
|
+
disabled: true,
|
85
|
+
x: { "effect": "disabled = saving || !history.undoable" },
|
86
|
+
data: {
|
87
|
+
role: "undo"
|
88
|
+
}
|
89
|
+
) %>
|
111
90
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
<% end %>
|
91
|
+
<% section.with_button(
|
92
|
+
icon: :redo_2,
|
93
|
+
click: "history.redo",
|
94
|
+
tooltip: "Redo",
|
95
|
+
theme: :text_secondary,
|
96
|
+
disabled: true,
|
97
|
+
x: { "effect": "disabled = saving || !history.redoable" },
|
98
|
+
data: {
|
99
|
+
role: "redo"
|
100
|
+
}
|
101
|
+
) %>
|
102
|
+
|
103
|
+
<% section.with_button(
|
104
|
+
theme: :positive,
|
105
|
+
icon: :check,
|
106
|
+
collapsible: false,
|
107
|
+
type: "submit",
|
108
|
+
disabled: true,
|
109
|
+
data: {
|
110
|
+
role: "save"
|
111
|
+
},
|
112
|
+
x: {
|
113
|
+
"@click.stop.prevent": "if(!loading) save()",
|
114
|
+
"effect": "loading = saving; disabled = !history.undoable",
|
115
|
+
":class": "{'editor-saving': saving}"
|
116
|
+
}
|
117
|
+
) do |button| %>
|
118
|
+
<% button.with_state(:loading, text: "Saving...") %>
|
119
|
+
Save
|
142
120
|
<% end %>
|
143
|
-
<% end %>
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
multiline: false,
|
169
|
-
form_builder: f,
|
170
|
-
**title_options,
|
171
|
-
wrapper: {
|
172
|
-
data: {
|
173
|
-
role: "title-editor"
|
174
|
-
},
|
175
|
-
x: {
|
176
|
-
modelable: "value",
|
177
|
-
model: "title"
|
178
|
-
}
|
179
|
-
}
|
180
|
-
) %>
|
181
|
-
<% end %>
|
121
|
+
<% end %>
|
122
|
+
<% end %>
|
123
|
+
</div>
|
124
|
+
|
125
|
+
<%# Editable slide %>
|
126
|
+
<div
|
127
|
+
class="editor-slide"
|
128
|
+
x-ref="slide"
|
129
|
+
@dragenter.stop.prevent="dragging = true"
|
130
|
+
@dragover.stop.prevent="dragging = true"
|
131
|
+
@dragleave.stop.prevent="dragging = false"
|
132
|
+
@drop.stop.prevent="handleImageDrop($event)">
|
133
|
+
<%= coco_editable_slide(
|
134
|
+
**slide_args,
|
135
|
+
data: {
|
136
|
+
role: "slide"
|
137
|
+
},
|
138
|
+
x: {
|
139
|
+
":style": "slideStyles",
|
140
|
+
":class": "slideClasses",
|
141
|
+
}
|
142
|
+
) do |slide| %>
|
143
|
+
<% if title? %>
|
144
|
+
<% slide.with_title do %>
|
145
|
+
<%= title %>
|
182
146
|
<% end %>
|
147
|
+
<% end %>
|
183
148
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
name: text_1_name,
|
188
|
-
multiline: true,
|
189
|
-
form_builder: f,
|
190
|
-
**text_1_options,
|
191
|
-
wrapper: {
|
192
|
-
data: {
|
193
|
-
role: "text-1-editor"
|
194
|
-
},
|
195
|
-
x: {
|
196
|
-
modelable: "value",
|
197
|
-
model: "text1"
|
198
|
-
}
|
199
|
-
}
|
200
|
-
) %>
|
201
|
-
<% end %>
|
149
|
+
<% if text_1? %>
|
150
|
+
<% slide.with_text_1 do %>
|
151
|
+
<%= text_1 %>
|
202
152
|
<% end %>
|
203
153
|
<% end %>
|
204
|
-
</div>
|
205
|
-
|
206
|
-
<% if content %>
|
207
|
-
<%# Any additional fields required %>
|
208
|
-
<div class="editor-additional-content">
|
209
|
-
<%= content %>
|
210
|
-
</div>
|
211
154
|
<% end %>
|
155
|
+
</div>
|
212
156
|
|
157
|
+
<% if content %>
|
158
|
+
<div
|
159
|
+
class="editor-form"
|
160
|
+
x-ref="form"
|
161
|
+
@turbo:submit-end="submitSuccess"
|
162
|
+
@turbo:fetch-request-error="submitError"
|
163
|
+
@direct-upload:error="directUploadError"
|
164
|
+
@direct-uploads:end="save">
|
165
|
+
<%= content %>
|
166
|
+
</div>
|
213
167
|
<% end %>
|
214
|
-
|
215
|
-
<% if thumbnail? %>
|
168
|
+
|
169
|
+
<% if false && thumbnail? %>
|
216
170
|
<%# Slide used for thumbnail generation %>
|
217
171
|
<div class="editor-screenshot-wrapper">
|
218
172
|
<div x-ref="screenshot" class="editor-screenshot">
|
@@ -232,4 +186,5 @@
|
|
232
186
|
</div>
|
233
187
|
</div>
|
234
188
|
<% end %>
|
189
|
+
|
235
190
|
<% end %>
|
@@ -13,15 +13,30 @@ const thumbnailOpts = {
|
|
13
13
|
};
|
14
14
|
|
15
15
|
export default CocoComponent("appSlideEditor", (data) => {
|
16
|
+
const initialData = {
|
17
|
+
layout: data.layout,
|
18
|
+
title: data.title,
|
19
|
+
text1: data.text1,
|
20
|
+
bgColor: data.bgColor,
|
21
|
+
textColor: data.textColor,
|
22
|
+
bgImage: {
|
23
|
+
name: data.bgImage,
|
24
|
+
data: data.bgImage,
|
25
|
+
},
|
26
|
+
};
|
27
|
+
|
16
28
|
return {
|
17
29
|
use: [withUndo()],
|
18
30
|
|
19
|
-
...
|
20
|
-
|
31
|
+
...initialData,
|
32
|
+
|
33
|
+
saved: { ...initialData },
|
34
|
+
|
21
35
|
saving: false,
|
22
36
|
ready: false,
|
23
37
|
dragging: false,
|
24
38
|
errors: [],
|
39
|
+
|
25
40
|
thumbnailFile: null,
|
26
41
|
|
27
42
|
get bgImagePicker() {
|
@@ -29,13 +44,6 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
29
44
|
},
|
30
45
|
|
31
46
|
init() {
|
32
|
-
// Add property changes to the undo/redo history
|
33
|
-
this._fields.forEach((name) => {
|
34
|
-
this.$watch(name, (value, oldValue) =>
|
35
|
-
this.history.add(name, value, oldValue)
|
36
|
-
);
|
37
|
-
});
|
38
|
-
|
39
47
|
// Update thumbnail field when new thumbnail is generated
|
40
48
|
this.$watch("thumbnailFile", () => this._syncThumbnailField());
|
41
49
|
|
@@ -43,7 +51,16 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
43
51
|
errors.forEach((error) => console.error(error.message)); // TODO display errors properly!
|
44
52
|
});
|
45
53
|
|
46
|
-
this.$nextTick(() =>
|
54
|
+
this.$nextTick(() => {
|
55
|
+
// Add property changes to the undo/redo history
|
56
|
+
this._fields.forEach((name) => {
|
57
|
+
this.$watch(name, (value, oldValue) =>
|
58
|
+
this.history.add(name, value, oldValue)
|
59
|
+
);
|
60
|
+
});
|
61
|
+
|
62
|
+
this.ready = true;
|
63
|
+
});
|
47
64
|
},
|
48
65
|
|
49
66
|
undo(name, value) {
|
@@ -79,7 +96,11 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
79
96
|
}
|
80
97
|
}
|
81
98
|
|
82
|
-
this.$refs.form
|
99
|
+
if (this.$refs.form) {
|
100
|
+
this.$refs.form.querySelector("form").requestSubmit();
|
101
|
+
} else {
|
102
|
+
this.submitSuccess();
|
103
|
+
}
|
83
104
|
},
|
84
105
|
|
85
106
|
submitEnd(event) {
|
@@ -106,12 +127,43 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
106
127
|
this._handleSaveError($event.detail.error, { event: $event });
|
107
128
|
},
|
108
129
|
|
130
|
+
syncImageField(el, image) {
|
131
|
+
const dataTransfer = new DataTransfer();
|
132
|
+
if (image.file && image.file instanceof File) {
|
133
|
+
dataTransfer.items.add(image.file);
|
134
|
+
}
|
135
|
+
el.files = dataTransfer.files;
|
136
|
+
},
|
137
|
+
|
138
|
+
input: {
|
139
|
+
layout: { "x-model.fill": "layout" },
|
140
|
+
title: { "x-model.fill": "title" },
|
141
|
+
text1: { "x-model.fill": "text1" },
|
142
|
+
bgColor: { "x-model.fill": "bgColorHex" },
|
143
|
+
textColor: { "x-model.fill": "textColorHex" },
|
144
|
+
bgImage: { "x-effect": "syncImageField($el, bgImage)" },
|
145
|
+
bgImagePurge: { ":checked": "!hasBgImage" },
|
146
|
+
},
|
147
|
+
|
148
|
+
get hasBgImage() {
|
149
|
+
return !!(this.bgImage && this.bgImage.data);
|
150
|
+
},
|
151
|
+
|
152
|
+
get bgColorHex() {
|
153
|
+
return this.bgColor.replace("#", "");
|
154
|
+
},
|
155
|
+
|
156
|
+
get textColorHex() {
|
157
|
+
return this.textColor.replace("#", "");
|
158
|
+
},
|
159
|
+
|
109
160
|
get slideStyles() {
|
110
161
|
return {
|
111
162
|
backgroundColor: this.bgColor,
|
112
163
|
color: this.textColor,
|
113
|
-
backgroundImage:
|
114
|
-
|
164
|
+
backgroundImage: this.hasBgImage
|
165
|
+
? `url('${this.bgImage.data}')`
|
166
|
+
: "none",
|
115
167
|
};
|
116
168
|
},
|
117
169
|
|
@@ -123,9 +175,7 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
123
175
|
},
|
124
176
|
|
125
177
|
get isDarkBg() {
|
126
|
-
return
|
127
|
-
? isDark(this.bgColor)
|
128
|
-
: false;
|
178
|
+
return this.hasBgImage || this.bgColor ? isDark(this.bgColor) : false;
|
129
179
|
},
|
130
180
|
|
131
181
|
get shouldGenerateThumbnail() {
|
@@ -133,7 +183,7 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
133
183
|
},
|
134
184
|
|
135
185
|
get _fields() {
|
136
|
-
return Object.keys(
|
186
|
+
return Object.keys(initialData);
|
137
187
|
},
|
138
188
|
|
139
189
|
async _generateThumbnail() {
|
@@ -170,6 +220,9 @@ export default CocoComponent("appSlideEditor", (data) => {
|
|
170
220
|
|
171
221
|
_handleSaveError(message = "Error saving slide", context = {}) {
|
172
222
|
this.errors.push({ message, context });
|
223
|
+
this.errors.forEach((err) => {
|
224
|
+
console.log(err.message);
|
225
|
+
});
|
173
226
|
this.saving = false;
|
174
227
|
|
175
228
|
this.$dispatch("slide:save-end", { success: false });
|