coveragebook_components 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,9 +4,11 @@ export default CocoComponent("modal", () => {
4
4
  return {
5
5
  open: false,
6
6
  frame: null,
7
+ modal: null,
7
8
  options: ["dismissable", "closeOnSubmit"],
8
9
 
9
10
  init() {
11
+ this.modal = this;
10
12
  this.onFrameSubmitEnd = this.onFrameSubmitEnd.bind(this);
11
13
 
12
14
  this.frame = this.$el.closest("turbo-frame");
@@ -17,24 +19,34 @@ export default CocoComponent("modal", () => {
17
19
 
18
20
  show() {
19
21
  this.open = true;
22
+ setTimeout(() => {
23
+ this.$dispatch("modal:shown");
24
+ }, 400);
20
25
  },
21
26
 
22
27
  hide() {
23
28
  this.open = false;
24
- setTimeout(() => this.clearFrame(), 100);
29
+ setTimeout(() => {
30
+ this.clearFrame();
31
+ this.$dispatch("modal:hidden");
32
+ }, 200);
25
33
  },
26
34
 
27
35
  dismiss(event) {
28
36
  if (this.$options.dismissable) this.hide();
29
37
  },
30
38
 
39
+ scrollTo(pos) {
40
+ this.$root.scrollTop = pos + this.contentOffsetTop;
41
+ },
42
+
31
43
  clearFrame() {
32
44
  this.frame.removeAttribute("src");
33
45
  this.frame.removeAttribute("complete");
34
46
  this.frame.innerHTML = "";
35
47
  },
36
48
 
37
- onFrameSubmitEnd() {
49
+ onFrameSubmitEnd(event) {
38
50
  if (this.$options.closeOnSubmit && event.detail.success) {
39
51
  this.hide();
40
52
  }
@@ -44,11 +56,38 @@ export default CocoComponent("modal", () => {
44
56
  this.frame.removeEventListener("turbo:submit-end", this.onFrameSubmitEnd);
45
57
  },
46
58
 
59
+ get contentOffsetTop() {
60
+ return parseInt(
61
+ window.getComputedStyle(this.$refs.container).paddingTop,
62
+ 10
63
+ );
64
+ },
65
+
47
66
  root: {
48
67
  "x-options": "options",
49
68
  "x-show": "open",
50
69
  "@keydown.escape.document": "dismiss",
51
70
  "@modal:hide.document": "hide",
52
71
  },
72
+
73
+ overlay: {
74
+ "x-show": "open",
75
+ "x-transition:enter": "overlay-enter",
76
+ "x-transition:enter-start": "overlay-enter-start",
77
+ "x-transition:enter-end": "overlay-enter-end",
78
+ "x-transition:leave": "overlay-leave",
79
+ "x-transition:leave-start": "overlay-leave-start",
80
+ "x-transition:leave-end": "overlay-leave-end",
81
+ },
82
+
83
+ container: {
84
+ "x-show": "open",
85
+ "x-transition:enter": "container-enter",
86
+ "x-transition:enter-start": "container-enter-start",
87
+ "x-transition:enter-end": "container-enter-end",
88
+ "x-transition:leave": "container-leave",
89
+ "x-transition:leave-start": "container-leave-start",
90
+ "x-transition:leave-end": "container-leave-end",
91
+ },
53
92
  };
54
93
  });
@@ -8,14 +8,20 @@ module Coco
8
8
 
9
9
  renders_one :title
10
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
11
+ renders_one :container, types: {
12
+ dialog: ->(**kwargs, &block) do
13
+ @container_content = block
14
+ Coco::ModalDialog.new(dismissable: get_option_value(:dismissable), **kwargs)
15
+ end,
16
+
17
+ lightbox: ->(**kwargs, &block) do
18
+ Coco::ModalLightbox.new(dismissable: get_option_value(:dismissable), **kwargs)
19
+ end
20
+ }
15
21
 
16
22
  before_render do
17
- if dialog? && title?
18
- dialog.with_title { title.to_s }
23
+ if container? && title? && container.respond_to?(:with_title)
24
+ container.with_title { title.to_s }
19
25
  end
20
26
  end
21
27
 
@@ -36,11 +42,11 @@ module Coco
36
42
  end
37
43
 
38
44
  def modal_content
39
- dialog? ? dialog : content
45
+ container? ? container : content
40
46
  end
41
47
 
42
48
  def content
43
- @dialog_content || super
49
+ @container_content || super
44
50
  end
45
51
 
46
52
  def render_flash_messages
@@ -4,7 +4,7 @@
4
4
  @apply max-w-2xl; /* temp until sizes added */
5
5
 
6
6
  .modal-dialog-header {
7
- @apply relative flex items-center justify-center;
7
+ @apply relative flex items-center;
8
8
  @apply px-4 sm:px-8 h-14 sm:h-16 border-b border-gray-300 rounded-t-xl bg-white;
9
9
  }
10
10
 
@@ -14,7 +14,7 @@ export default CocoComponent("modalDialog", () => {
14
14
  },
15
15
 
16
16
  close() {
17
- this.$dispatch("modal:hide");
17
+ this.modal.hide();
18
18
  },
19
19
 
20
20
  onFrameLoad() {
@@ -0,0 +1,35 @@
1
+ @layer components {
2
+ [data-coco][data-component="modal-lightbox"] {
3
+ @apply relative;
4
+ width: fit-content;
5
+
6
+ .modal-lightbox-close {
7
+ @apply flex-none p-2 absolute -right-1.5 -top-1.5 sm:-right-4 sm:-top-4 rounded-full transition-all z-20;
8
+ @apply bg-background-dark-1 text-content-light-1;
9
+ @apply focus:ring-0 focus:outline-none text-content-light-1 shadow-md;
10
+ }
11
+
12
+ .modal-lightbox-content {
13
+ @apply rounded-xl overflow-hidden min-w-[100px] min-h-[100px] relative;
14
+ width: fit-content;
15
+ }
16
+
17
+ .modal-lightbox-loader {
18
+ @apply flex items-center justify-center absolute inset-0 opacity-70 bg-black/60 text-white;
19
+ }
20
+
21
+ .modal-lightbox-media {
22
+ @apply relative z-10;
23
+
24
+ img {
25
+ width: 100%;
26
+ }
27
+ }
28
+
29
+ &.loaded {
30
+ .modal-lightbox-content {
31
+ @apply shadow-2xl;
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,13 @@
1
+ <%= render component_tag(x: {data: x_data("modalLightbox"), bind: "root"}) do %>
2
+ <button type="button" class="modal-lightbox-close" data-role="close" @click="close" x-show="loaded">
3
+ <%= coco_icon(:x, size: :md) %>
4
+ </button>
5
+ <div class="modal-lightbox-content" @click.outside="close">
6
+ <div class="modal-lightbox-loader" x-show="!loaded">
7
+ <%= coco_icon(:loader_2, spin: true) %>
8
+ </div>
9
+ <div class="modal-lightbox-media" x-ref="media" x-show="loaded">
10
+ <%= image %>
11
+ </div>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,35 @@
1
+ import { CocoComponent } from "@js/coco";
2
+
3
+ export default CocoComponent("modalLightbox", () => {
4
+ return {
5
+ loaded: false,
6
+
7
+ init() {
8
+ if (this.img.complete && this.img.naturalHeight !== 0) {
9
+ this.imageLoaded();
10
+ }
11
+ },
12
+
13
+ close() {
14
+ this.modal.hide();
15
+ },
16
+
17
+ imageLoaded() {
18
+ this.loaded = true;
19
+ this.$nextTick(() => {
20
+ const scrollTop = parseInt(this.img.dataset.scrollTop, 10);
21
+ if (!isNaN(scrollTop) && scrollTop !== 0) {
22
+ this.modal.scrollTo(scrollTop);
23
+ }
24
+ });
25
+ },
26
+
27
+ get img() {
28
+ return this.$refs.media.querySelector("img");
29
+ },
30
+
31
+ root: {
32
+ ":class": "{loaded}",
33
+ },
34
+ };
35
+ });
@@ -0,0 +1,19 @@
1
+ module Coco
2
+ class ModalLightbox < Coco::Component
3
+ include Concerns::AcceptsOptions
4
+
5
+ renders_one :image, ->(scroll_top: 0, **kwargs) do
6
+ coco_image(
7
+ x: {"on:load": "imageLoaded"},
8
+ data: {scroll_top: scroll_top.to_i, role: "image"},
9
+ **kwargs
10
+ )
11
+ end
12
+
13
+ before_render do
14
+ unless image?
15
+ raise ArgumentError, "An image is required for the lightbox"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -35,7 +35,13 @@ module Coco
35
35
 
36
36
  def coco_modal_dialog(name = "default", **, &block)
37
37
  render(Coco::Modal.new(name: name, **)) do |modal|
38
- modal.with_dialog(&block)
38
+ modal.with_container_dialog(&block)
39
+ end
40
+ end
41
+
42
+ def coco_modal_lightbox(name = "default", scroll_top: nil, **, &block)
43
+ render(Coco::Modal.new(name: name, scroll_top: scroll_top, **)) do |modal|
44
+ modal.with_container_lightbox(&block)
39
45
  end
40
46
  end
41
47
 
data/lib/coco.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Coco
2
- VERSION = "0.7.4"
2
+ VERSION = "0.7.5"
3
3
  end
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.7.4
4
+ version: 0.7.5
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-10-05 00:00:00.000000000 Z
11
+ date: 2023-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -1500,6 +1500,10 @@ files:
1500
1500
  - app/components/coco/base/modal_dialog/modal_dialog.html.erb
1501
1501
  - app/components/coco/base/modal_dialog/modal_dialog.js
1502
1502
  - app/components/coco/base/modal_dialog/modal_dialog.rb
1503
+ - app/components/coco/base/modal_lightbox/modal_lightbox.css
1504
+ - app/components/coco/base/modal_lightbox/modal_lightbox.html.erb
1505
+ - app/components/coco/base/modal_lightbox/modal_lightbox.js
1506
+ - app/components/coco/base/modal_lightbox/modal_lightbox.rb
1503
1507
  - app/components/coco/base/placeholder/placeholder.css
1504
1508
  - app/components/coco/base/placeholder/placeholder.html.erb
1505
1509
  - app/components/coco/base/placeholder/placeholder.rb