coveragebook_components 0.6.5 → 0.7.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.
- checksums.yaml +4 -4
- data/app/assets/build/coco/app.css +88 -3
- data/app/assets/build/coco/app.js +185 -102
- data/app/assets/build/coco/book.css +100 -2
- data/app/assets/build/coco/book.js +168 -85
- data/app/components/coco/app/elements/snackbar/snackbar.css +1 -1
- data/app/components/coco/base/button/button.css +1 -1
- data/app/components/coco/base/icon/icon.css +1 -1
- data/app/components/coco/base/modal/modal.css +21 -0
- data/app/components/coco/base/modal/modal.html.erb +25 -0
- data/app/components/coco/base/modal/modal.js +54 -0
- data/app/components/coco/base/modal/modal.rb +52 -0
- data/app/components/coco/base/modal_dialog/modal_dialog.css +28 -0
- data/app/components/coco/base/modal_dialog/modal_dialog.html.erb +19 -0
- data/app/components/coco/base/modal_dialog/modal_dialog.js +36 -0
- data/app/components/coco/base/modal_dialog/modal_dialog.rb +27 -0
- data/app/helpers/coco/base_helper.rb +39 -12
- data/lib/coco/engine.rb +1 -0
- data/lib/coco.rb +1 -1
- metadata +24 -2
@@ -0,0 +1,25 @@
|
|
1
|
+
<% if render_as_modal? %>
|
2
|
+
<%= turbo_frame_tag coco_modal_frame_id(name), class: "modal-frame" do %>
|
3
|
+
<%= render component_tag(
|
4
|
+
id: id,
|
5
|
+
role: "dialog",
|
6
|
+
aria: {modal: "true"},
|
7
|
+
data: {turbo_temporary: true},
|
8
|
+
x: {
|
9
|
+
data: x_data("modal"),
|
10
|
+
bind: "root",
|
11
|
+
cloak: true,
|
12
|
+
},
|
13
|
+
) do %>
|
14
|
+
<div class="modal-overlay" x-show="open" x-transition.opacity></div>
|
15
|
+
<div class="modal-container" x-show="open" x-transition>
|
16
|
+
<div class="modal-content" x-trap.noscroll.inert.noreturn="open">
|
17
|
+
<%= modal_content %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
<%= render_flash_messages %>
|
22
|
+
<% end %>
|
23
|
+
<% else %>
|
24
|
+
<%= content %>
|
25
|
+
<% end %>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { CocoComponent } from "@js/coco";
|
2
|
+
|
3
|
+
export default CocoComponent("modal", () => {
|
4
|
+
return {
|
5
|
+
open: false,
|
6
|
+
frame: null,
|
7
|
+
options: ["dismissable", "closeOnSubmit"],
|
8
|
+
|
9
|
+
init() {
|
10
|
+
this.onFrameSubmitEnd = this.onFrameSubmitEnd.bind(this);
|
11
|
+
|
12
|
+
this.frame = this.$el.closest("turbo-frame");
|
13
|
+
this.frame.addEventListener("turbo:submit-end", this.onFrameSubmitEnd);
|
14
|
+
|
15
|
+
this.$nextTick(() => this.show()); // ensure transitions run
|
16
|
+
},
|
17
|
+
|
18
|
+
show() {
|
19
|
+
this.open = true;
|
20
|
+
},
|
21
|
+
|
22
|
+
hide() {
|
23
|
+
this.open = false;
|
24
|
+
setTimeout(() => this.clearFrame(), 100);
|
25
|
+
},
|
26
|
+
|
27
|
+
dismiss(event) {
|
28
|
+
if (this.$options.dismissable) this.hide();
|
29
|
+
},
|
30
|
+
|
31
|
+
clearFrame() {
|
32
|
+
this.frame.removeAttribute("src");
|
33
|
+
this.frame.removeAttribute("complete");
|
34
|
+
this.frame.innerHTML = "";
|
35
|
+
},
|
36
|
+
|
37
|
+
onFrameSubmitEnd() {
|
38
|
+
if (this.$options.closeOnSubmit && event.detail.success) {
|
39
|
+
this.hide();
|
40
|
+
}
|
41
|
+
},
|
42
|
+
|
43
|
+
destroy() {
|
44
|
+
this.frame.removeEventListener("turbo:submit-end", this.onFrameSubmitEnd);
|
45
|
+
},
|
46
|
+
|
47
|
+
root: {
|
48
|
+
"x-options": "options",
|
49
|
+
"x-show": "open",
|
50
|
+
"@keydown.escape.document": "dismiss",
|
51
|
+
"@modal:hide.document": "hide",
|
52
|
+
},
|
53
|
+
};
|
54
|
+
});
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Coco
|
2
|
+
class Modal < Coco::Component
|
3
|
+
include Concerns::AcceptsOptions
|
4
|
+
include Turbo::FramesHelper
|
5
|
+
|
6
|
+
accepts_option :dismissable, from: [true, false], default: true
|
7
|
+
accepts_option :close_on_submit, from: [true, false], default: true
|
8
|
+
|
9
|
+
renders_one :title
|
10
|
+
|
11
|
+
renders_one :dialog, ->(**kwargs, &block) do
|
12
|
+
@dialog_content = capture { block.call }
|
13
|
+
Coco::ModalDialog.new(dismissable: get_option_value(:dismissable), **kwargs)
|
14
|
+
end
|
15
|
+
|
16
|
+
before_render do
|
17
|
+
if dialog? && title?
|
18
|
+
dialog.with_title { title.to_s }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :name, :show
|
23
|
+
|
24
|
+
def initialize(name:, show: false, **kwargs)
|
25
|
+
@name = name
|
26
|
+
@show = show
|
27
|
+
title { kwargs[:title] } if kwargs[:title]
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_as_modal?
|
31
|
+
request.headers["Turbo-Frame"].present? || show
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
"coco-modal-#{name.to_s.dasherize}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def modal_content
|
39
|
+
dialog? ? dialog : content
|
40
|
+
end
|
41
|
+
|
42
|
+
def content
|
43
|
+
@dialog_content || super
|
44
|
+
end
|
45
|
+
|
46
|
+
def render_flash_messages
|
47
|
+
if helpers.respond_to?(:render_turbo_stream_flash_messages)
|
48
|
+
helpers.render_turbo_stream_flash_messages
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
@layer components {
|
2
|
+
[data-coco][data-component="modal-dialog"] {
|
3
|
+
@apply shadow-2xl rounded-xl w-full;
|
4
|
+
@apply max-w-2xl; /* temp until sizes added */
|
5
|
+
|
6
|
+
.modal-dialog-header {
|
7
|
+
@apply relative flex items-center justify-center;
|
8
|
+
@apply px-8 h-16 border-b border-gray-300 rounded-t-xl bg-white;
|
9
|
+
}
|
10
|
+
|
11
|
+
.modal-dialog-title {
|
12
|
+
@apply text-lg pr-6 w-full font-semibold truncate;
|
13
|
+
}
|
14
|
+
|
15
|
+
.modal-dialog-close {
|
16
|
+
@apply flex-none block p-2 absolute top-1/2 right-3 -translate-y-1/2;
|
17
|
+
@apply focus:ring-0 focus:outline-none text-content-dark-muted hover:text-content-dark-2;
|
18
|
+
}
|
19
|
+
|
20
|
+
.modal-dialog-content {
|
21
|
+
@apply px-8 py-6 rounded-xl bg-background-light-3;
|
22
|
+
}
|
23
|
+
|
24
|
+
.modal-dialog-header + .modal-dialog-content {
|
25
|
+
@apply rounded-t-none;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= render component_tag(x: {data: x_data("modalDialog")}) do %>
|
2
|
+
<% if header? %>
|
3
|
+
<header class="modal-dialog-header">
|
4
|
+
<% if title? %>
|
5
|
+
<h4 class="modal-dialog-title" data-role="title">
|
6
|
+
<%= title %>
|
7
|
+
</h4>
|
8
|
+
<% end %>
|
9
|
+
<% if dismissable? %>
|
10
|
+
<button type="button" class="modal-dialog-close" data-role="close" @click="close">
|
11
|
+
<%= coco_icon(:x, size: :md) %>
|
12
|
+
</button>
|
13
|
+
<% end %>
|
14
|
+
</header>
|
15
|
+
<% end %>
|
16
|
+
<div class="modal-dialog-content">
|
17
|
+
<%= content %>
|
18
|
+
</div>
|
19
|
+
<% end %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { CocoComponent } from "@js/coco";
|
2
|
+
|
3
|
+
export default CocoComponent("modalDialog", () => {
|
4
|
+
return {
|
5
|
+
frame: null,
|
6
|
+
|
7
|
+
init() {
|
8
|
+
this.onFrameLoad = this.onFrameLoad.bind(this);
|
9
|
+
this.frame = this.$el.closest("turbo-frame");
|
10
|
+
|
11
|
+
if (this.frame) {
|
12
|
+
this.frame.addEventListener("turbo:frame-load", this.onFrameLoad);
|
13
|
+
}
|
14
|
+
},
|
15
|
+
|
16
|
+
close() {
|
17
|
+
this.$dispatch("modal:hide");
|
18
|
+
},
|
19
|
+
|
20
|
+
onFrameLoad() {
|
21
|
+
this.$focus.focus(this.firstInput);
|
22
|
+
},
|
23
|
+
|
24
|
+
destroy() {
|
25
|
+
if (this.frame) {
|
26
|
+
this.frame.removeEventListener("turbo:frame-load", this.onFrameLoad);
|
27
|
+
}
|
28
|
+
},
|
29
|
+
|
30
|
+
get firstInput() {
|
31
|
+
return this.$root.querySelector(
|
32
|
+
"input:not([type=hidden]), textarea, select"
|
33
|
+
);
|
34
|
+
},
|
35
|
+
};
|
36
|
+
});
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Coco
|
2
|
+
class ModalDialog < Coco::Component
|
3
|
+
include Concerns::AcceptsOptions
|
4
|
+
|
5
|
+
accepts_option :dismissable, from: [true, false], default: true
|
6
|
+
|
7
|
+
renders_one :title
|
8
|
+
|
9
|
+
before_render do
|
10
|
+
unless title?
|
11
|
+
raise ArgumentError, "A title is required for modal dialogs"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(**kwargs)
|
16
|
+
title { kwargs[:title] } if kwargs[:title]
|
17
|
+
end
|
18
|
+
|
19
|
+
def header?
|
20
|
+
title || dismissable?
|
21
|
+
end
|
22
|
+
|
23
|
+
def dismissable?
|
24
|
+
get_option_value(:dismissable)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,32 +1,59 @@
|
|
1
1
|
module Coco
|
2
2
|
module BaseHelper
|
3
|
-
def coco_tag(
|
4
|
-
render Coco::Tag.new(
|
3
|
+
def coco_tag(*, **, &block)
|
4
|
+
render Coco::Tag.new(*, **), &block
|
5
5
|
end
|
6
6
|
|
7
|
-
def coco_svg(path = nil, **
|
8
|
-
render Coco::Svg.new(path: path, **
|
7
|
+
def coco_svg(path = nil, **)
|
8
|
+
render Coco::Svg.new(path: path, **)
|
9
9
|
end
|
10
10
|
|
11
|
-
def coco_image(src = nil, **
|
12
|
-
render Coco::Image.new(src: src, **
|
11
|
+
def coco_image(src = nil, **)
|
12
|
+
render Coco::Image.new(src: src, **)
|
13
13
|
end
|
14
14
|
|
15
|
-
def coco_icon(icon_name = nil,
|
16
|
-
render Coco::Icon.new(name: icon_name, **
|
15
|
+
def coco_icon(icon_name = nil, **, &block)
|
16
|
+
render Coco::Icon.new(name: icon_name, **), &block
|
17
17
|
end
|
18
18
|
|
19
|
-
def coco_embed(platform, url = nil, **
|
19
|
+
def coco_embed(platform, url = nil, **)
|
20
20
|
case platform
|
21
21
|
when :youtube
|
22
|
-
render Coco::Embeds::Youtube.new(url: url, **
|
22
|
+
render Coco::Embeds::Youtube.new(url: url, **)
|
23
23
|
else
|
24
24
|
raise ArgumentError, "`#{platform}` is not a valid embed type"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
def coco_placeholder(
|
29
|
-
render Coco::Placeholder.new(
|
28
|
+
def coco_placeholder(*, **, &block)
|
29
|
+
render Coco::Placeholder.new(*, **), &block
|
30
|
+
end
|
31
|
+
|
32
|
+
def coco_modal(name = "default", **, &block)
|
33
|
+
render(Coco::Modal.new(name: name, **), &block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def coco_modal_dialog(name = "default", **, &block)
|
37
|
+
render(Coco::Modal.new(name: name, **)) do |modal|
|
38
|
+
modal.with_dialog(&block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def coco_modal_link(*, data: {}, modal: nil, **kwargs, &)
|
43
|
+
kwargs[:data] = coco_modal_data_attributes(modal || "default").merge(data)
|
44
|
+
|
45
|
+
link_to(*, **kwargs, &)
|
46
|
+
end
|
47
|
+
|
48
|
+
def coco_modal_frame_id(name = "default")
|
49
|
+
"coco-modal-frame-#{name.to_s.dasherize}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def coco_modal_data_attributes(name = "default")
|
53
|
+
{
|
54
|
+
turbo: true,
|
55
|
+
turbo_frame: coco_modal_frame_id(name)
|
56
|
+
}
|
30
57
|
end
|
31
58
|
end
|
32
59
|
end
|
data/lib/coco/engine.rb
CHANGED
data/lib/coco.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coveragebook_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Perkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: turbo-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description:
|
56
70
|
email:
|
57
71
|
- dev@coveragebook.com
|
@@ -1487,6 +1501,14 @@ files:
|
|
1487
1501
|
- app/components/coco/base/image_uploader/image_uploader.rb
|
1488
1502
|
- app/components/coco/base/link/link.css
|
1489
1503
|
- app/components/coco/base/link/link.rb
|
1504
|
+
- app/components/coco/base/modal/modal.css
|
1505
|
+
- app/components/coco/base/modal/modal.html.erb
|
1506
|
+
- app/components/coco/base/modal/modal.js
|
1507
|
+
- app/components/coco/base/modal/modal.rb
|
1508
|
+
- app/components/coco/base/modal_dialog/modal_dialog.css
|
1509
|
+
- app/components/coco/base/modal_dialog/modal_dialog.html.erb
|
1510
|
+
- app/components/coco/base/modal_dialog/modal_dialog.js
|
1511
|
+
- app/components/coco/base/modal_dialog/modal_dialog.rb
|
1490
1512
|
- app/components/coco/base/placeholder/placeholder.css
|
1491
1513
|
- app/components/coco/base/placeholder/placeholder.html.erb
|
1492
1514
|
- app/components/coco/base/placeholder/placeholder.rb
|