turbo_modal 0.2.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc0f4ed0edea874e6b769fb7516c4daae96a428497202d80911b9c3fb0c1160c
4
- data.tar.gz: e7d5fa95f4ca0bb2e7609e1a5a87b076b4d38b374047f91dc50a5f4eaea733ff
3
+ metadata.gz: e8e72cdd25686a64f8cca7d141062e27cec69ae52e607a60a437ca1aad450cee
4
+ data.tar.gz: 29555235b607fc5f343e3f11643143c0233329cf1d210402999896afdb4cecc2
5
5
  SHA512:
6
- metadata.gz: cd8b55e97ef967a916720d5506bb0b28ef72c7f5c464b9ab3d36830480617a8e4ca021f84357c8b949ccd35e37a11c109c563c6d1c86202b710367748dc6ad2a
7
- data.tar.gz: 9b5f9abfb087b28726f58e2aa5b25a5ec527e8f33ea3e5ba724e4aa78a98de0b367bd8495117b7d5d74247be247205e613a4db25d34accac2f92938a4c3945e5
6
+ metadata.gz: 9380653ea1ff7ce20473b1b6e34b2324c3e4665f10abf4ff4f6e840bc7ae659c79d54bc9722c0714b8c9c2eaa469ee2f02a379148b1f1c2376f390df6d67cf0e
7
+ data.tar.gz: 7220766f0abdd58b4eb5c89ec44a63db814ef6acd7e299af5e354d680896cbd6e66307405386f4820c0e696378dfe7999fd8db755848193ae811491a0ac87135
data/README.md CHANGED
@@ -18,6 +18,15 @@ Turbo modal provides helpers to add a basic scrim and modal target frame. These
18
18
  @import "~@katalyst-interactive/turbo-modal";
19
19
  ```
20
20
 
21
+ ### Import turbo_modal stimulus controllers
22
+ ```js
23
+ /* application.js */
24
+ import TurboModal from "@katalyst-interactive/turbo-modal"
25
+ application.load(TurboModal)
26
+ ```
27
+
28
+ ### Show a modal
29
+
21
30
  To get a modal displaying you will need 2 things:
22
31
  1. A `modal_link` (or programmatic trigger)
23
32
  2. Some `modal_content`
@@ -1,29 +1,57 @@
1
- .modal {
1
+ .modal-wrapper {
2
2
  position: fixed;
3
- top: 50%;
4
- left: 50%;
3
+ top: 0;
4
+ bottom: 0;
5
+ left: 0;
6
+ right: 0;
5
7
  z-index: 11;
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ pointer-events: none;
12
+ }
13
+ .bottom-sheet .modal-wrapper {
14
+ align-items: flex-end;
15
+ }
16
+
17
+ .modal {
18
+ min-width: 40rem;
19
+ max-height: 100%;
20
+ display: flex;
21
+ position: relative;
22
+ top: unset;
23
+ left: unset;
6
24
  background: white;
7
25
  border-radius: 4px;
8
- padding: 2rem;
26
+ padding: 0;
9
27
  --animation-in: slide-in;
10
28
  --animation-out: slide-out;
29
+ pointer-events: auto;
30
+ margin: 2rem;
31
+ }
32
+ @media screen and (max-width: 45rem) {
33
+ .modal {
34
+ min-width: 100%;
35
+ }
36
+ }
37
+ .modal .modal-content {
38
+ overflow-y: scroll;
39
+ padding: 2rem;
11
40
  }
12
41
  @media screen and (max-width: 45rem) {
13
42
  .fullscreen .modal {
14
- top: 0;
15
- left: 0;
16
- right: 0;
17
- bottom: 0;
43
+ margin: 0;
18
44
  border-radius: 0;
45
+ height: 100%;
46
+ flex-grow: 1;
19
47
  }
20
48
  }
21
49
  .bottom-sheet .modal {
22
50
  top: unset;
23
- bottom: 0;
24
- left: 0;
25
- right: 0;
51
+ width: 100%;
52
+ margin: 0;
26
53
  min-height: 40vh;
54
+ transform: unset;
27
55
  --animation-in: slide-up;
28
56
  --animation-out: slide-down;
29
57
  }
@@ -36,7 +64,6 @@
36
64
  .animate-in {
37
65
  animation: var(--animation-in);
38
66
  animation-duration: 0.25s;
39
- animation-fill-mode: forwards;
40
67
  }
41
68
  @media screen and (max-width: 45rem) {
42
69
  .fullscreen .animate-in {
@@ -58,21 +85,21 @@
58
85
  @keyframes slide-in {
59
86
  from {
60
87
  opacity: 0;
61
- transform: translate(-50%, -35%);
88
+ transform: translateY(35%);
62
89
  }
63
90
  to {
64
91
  opacity: 1;
65
- transform: translate(-50%, -50%);
92
+ transform: translateY(0%);
66
93
  }
67
94
  }
68
95
  @keyframes slide-out {
69
96
  from {
70
97
  opacity: 1;
71
- transform: translate(-50%, -50%);
98
+ transform: translateY(0%);
72
99
  }
73
100
  to {
74
101
  opacity: 0;
75
- transform: translate(-50%, -35%);
102
+ transform: translateY(35%);
76
103
  }
77
104
  }
78
105
  @keyframes slide-in-left {
@@ -1,30 +1,59 @@
1
- .modal {
1
+ .modal-wrapper {
2
2
  position: fixed;
3
- top: 50%;
4
- left: 50%;
3
+ top: 0;
4
+ bottom: 0;
5
+ left: 0;
6
+ right: 0;
5
7
  z-index: 11;
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ pointer-events: none;
12
+
13
+ .bottom-sheet & {
14
+ align-items: flex-end;
15
+ }
16
+ }
17
+
18
+ .modal {
19
+ min-width: 40rem;
20
+ max-height: 100%;
21
+ display: flex;
22
+ position: relative;
23
+ top: unset;
24
+ left: unset;
6
25
  background: white;
7
26
  border-radius: 4px;
8
- padding: 2rem;
27
+ padding: 0;
9
28
  --animation-in : slide-in;
10
29
  --animation-out : slide-out;
30
+ pointer-events: auto;
31
+ margin: 2rem;
32
+
33
+ @media screen and(max-width: 45rem) {
34
+ min-width: 100%;
35
+ }
36
+
37
+ .modal-content {
38
+ overflow-y: scroll;
39
+ padding: 2rem;
40
+ }
11
41
 
12
42
  .fullscreen & {
13
43
  @media screen and(max-width: 45rem) {
14
- top: 0;
15
- left: 0;
16
- right: 0;
17
- bottom: 0;
44
+ margin: 0;
18
45
  border-radius: 0;
46
+ height: 100%;
47
+ flex-grow: 1;
19
48
  }
20
49
  }
21
50
 
22
51
  .bottom-sheet & {
23
52
  top: unset;
24
- bottom: 0;
25
- left: 0;
26
- right: 0;
53
+ width: 100%;
54
+ margin: 0;
27
55
  min-height: 40vh;
56
+ transform: unset;
28
57
  --animation-in : slide-up;
29
58
  --animation-out : slide-down;
30
59
 
@@ -37,7 +66,6 @@
37
66
  .animate-in {
38
67
  animation: var(--animation-in);
39
68
  animation-duration: 0.25s;
40
- animation-fill-mode: forwards;
41
69
 
42
70
  .fullscreen & {
43
71
  @media screen and(max-width: 45rem) {
@@ -62,24 +90,24 @@
62
90
  @keyframes slide-in {
63
91
  from {
64
92
  opacity: 0;
65
- transform: translate(-50%, -35%);
93
+ transform: translateY(35%);
66
94
  }
67
95
 
68
96
  to {
69
97
  opacity: 1;
70
- transform: translate(-50%, -50%);
98
+ transform: translateY(0%);
71
99
  }
72
100
  }
73
101
 
74
102
  @keyframes slide-out {
75
103
  from {
76
104
  opacity: 1;
77
- transform: translate(-50%, -50%);
105
+ transform: translateY(0%);
78
106
  }
79
107
 
80
108
  to {
81
109
  opacity: 0;
82
- transform: translate(-50%, -35%);
110
+ transform: translateY(35%);
83
111
  }
84
112
  }
85
113
 
@@ -2,7 +2,12 @@
2
2
 
3
3
  module ModalHelper
4
4
  MODAL_ID = "modal"
5
- LINK_OPTIONS = { data: { turbo_frame: MODAL_ID, action: "modal#onLinkClick", modal_type: "" } }.freeze
5
+ LINK_OPTIONS = { data: {
6
+ turbo_frame: MODAL_ID,
7
+ controller: "modal-link",
8
+ action: "modal-link#onClick",
9
+ modal_type: "",
10
+ } }.freeze
6
11
 
7
12
  def modal_tag(modal_id = MODAL_ID)
8
13
  turbo_frame_tag modal_id, data: { controller: "modal", modal_target: "turboFrame", action: <<~ACTIONS }
@@ -11,34 +16,30 @@ module ModalHelper
11
16
  ACTIONS
12
17
  end
13
18
 
19
+ # @see ActionView::Helpers::UrlHelper#link_to for argument details
14
20
  def modal_link_to(name = nil, options = nil, html_options = nil, &block)
15
21
  if block
16
- link_to name, LINK_OPTIONS.deep_merge(options || {}), html_options, &block
22
+ link_to name, LINK_OPTIONS.deep_merge(options || {}), &block
17
23
  else
18
- link_to name, options, LINK_OPTIONS.deep_merge(html_options || {}), &block
24
+ link_to name, options, LINK_OPTIONS.deep_merge(html_options || {})
19
25
  end
20
26
  end
21
27
 
22
- def modal_link(text = nil, path = nil, options = {}, &block)
23
- options = LINK_OPTIONS.deep_merge(options)
24
- if block
25
- link_to text || path, options, &block
26
- else
27
- link_to text, path, options
28
- end
29
- end
28
+ alias modal_link modal_link_to
30
29
 
31
30
  def modal_content(options = {}, &block)
32
31
  modal_id = options.fetch(:modal_id, MODAL_ID)
33
32
  turbo_frame_tag modal_id, data: { hidden: "" } do
34
- tag.div(class: "modal animate-in #{options.delete(:modal_classes)}",
35
- data: {
36
- action: <<~ACTIONS
37
- keyup@window->modal#keyup
38
- scrim:hide@window->modal#close
39
- ACTIONS
40
- }) do
41
- yield if block
33
+ tag.div(class: "modal-wrapper") do
34
+ tag.div(class: "modal animate-in #{options.delete(:modal_classes)}",
35
+ data: {
36
+ action: <<~ACTIONS
37
+ keyup@window->modal#keyup
38
+ scrim:hide@window->modal#close
39
+ ACTIONS
40
+ }) do
41
+ yield if block
42
+ end
42
43
  end
43
44
  end
44
45
  end
@@ -1,4 +1,16 @@
1
1
  import ModalController, { openModal, closeModal } from "./modal_controller";
2
+ import ModalLinkController from "./modal_link_controller";
2
3
  import ScrimController, { showScrim, hideScrim } from "./scrim_controller";
3
4
 
4
- export { ModalController, openModal, closeModal, ScrimController, showScrim, hideScrim };
5
+ const Definitions = [
6
+ { identifier: "modal", controllerConstructor: ModalController },
7
+ { identifier: "modal-link", controllerConstructor: ModalLinkController },
8
+ { identifier: "scrim", controllerConstructor: ScrimController }
9
+ ];
10
+
11
+ export {
12
+ Definitions as default,
13
+ ModalController, openModal, closeModal,
14
+ ScrimController, showScrim, hideScrim,
15
+ ModalLinkController
16
+ };
@@ -2,7 +2,7 @@ import { Controller } from "stimulus";
2
2
  import { hideScrim, showScrim } from "./scrim_controller";
3
3
 
4
4
  /**
5
- * Shows a Turbo modal when triggered by a `modal_link` click or a call to `openModal`.
5
+ * Shows a Turbo modal when triggered by a `modal:open` event (e.g. `openModal`).
6
6
  */
7
7
  class ModalController extends Controller {
8
8
  static targets = ["turboFrame"];
@@ -19,7 +19,7 @@ class ModalController extends Controller {
19
19
  open(e) {
20
20
  this.turboFrameTarget.src = e.detail.url;
21
21
  this.typeValue = e.detail.type;
22
- showScrim();
22
+ showScrim(e.detail.dismiss);
23
23
  }
24
24
 
25
25
  close(e) {
@@ -45,18 +45,13 @@ class ModalController extends Controller {
45
45
  closeModal();
46
46
  }
47
47
  }
48
-
49
- onLinkClick(e) {
50
- const modal_link = e.target.closest("a[data-modal-type]")
51
- openModal(modal_link.href, modal_link.dataset.modalType);
52
- }
53
48
  }
54
49
 
55
50
  /**
56
51
  * Show a modal, requires a url for a page that renders a turbo-frame with id `modal`.
57
52
  */
58
- function openModal(url, type = "") {
59
- window.dispatchEvent(new CustomEvent("modal:open", { detail: { url: url, type: type }}));
53
+ function openModal(url, type = "", dismiss = true) {
54
+ window.dispatchEvent(new CustomEvent("modal:open", { detail: { url: url, type: type, dismiss: dismiss }}));
60
55
  }
61
56
 
62
57
  /**
@@ -0,0 +1,12 @@
1
+ import { Controller } from "stimulus";
2
+ import { openModal } from "./modal_controller";
3
+
4
+ /**
5
+ * Shows a Turbo modal when clicked.
6
+ */
7
+ export default class ModalLinkController extends Controller {
8
+ onClick(e) {
9
+ e.preventDefault();
10
+ openModal(this.element.href, this.element.dataset.modalType);
11
+ }
12
+ }
@@ -15,22 +15,36 @@ class ScrimController extends Controller {
15
15
 
16
16
  show(event) {
17
17
  delete this.scrimTarget.dataset.hidden;
18
+ document.body.style.height = "100vh";
19
+ document.body.style.overflow = "hidden";
20
+
21
+ if (!event.detail.dismiss) {
22
+ this.scrimTarget.style.pointerEvents = "none";
23
+ }
18
24
  }
19
25
 
20
26
  hide(event) {
21
27
  this.scrimTarget.dataset.hidden = "";
28
+ unclipScreen();
22
29
  }
23
30
 
24
31
  onClick(event) {
25
32
  window.dispatchEvent(new Event("scrim:hide"));
26
33
  }
34
+
35
+ disconnect() {
36
+ this.scrimTarget.dataset.hidden = "";
37
+ unclipScreen();
38
+ super.disconnect();
39
+ }
40
+
27
41
  }
28
42
 
29
43
  /**
30
44
  * Show the scrim element
31
45
  */
32
- function showScrim() {
33
- window.dispatchEvent(new Event("scrim:show"));
46
+ function showScrim(dismiss = true) {
47
+ window.dispatchEvent(new CustomEvent("scrim:show", { detail: { dismiss: dismiss }}));
34
48
  }
35
49
 
36
50
  /**
@@ -40,4 +54,12 @@ function hideScrim() {
40
54
  window.dispatchEvent(new Event("scrim:hide"));
41
55
  }
42
56
 
57
+ /**
58
+ * Unclips body to viewport size
59
+ */
60
+ function unclipScreen() {
61
+ document.body.style.height = "unset";
62
+ document.body.style.overflow = "unset";
63
+ }
64
+
43
65
  export { ScrimController as default, showScrim, hideScrim }
@@ -20,6 +20,5 @@ say "Install Turbo Modal"
20
20
  say "Turbo Modal #{TurboModal::VERSION} requires Stimulus@2.0.0", :yellow
21
21
  run "yarn add @katalyst-interactive/turbo-modal"
22
22
 
23
- append_to_file "app/javascript/controllers/index.js", %(\nimport { ScrimController, ModalController } from "@katalyst-interactive/turbo-modal"\n)
24
- append_to_file "app/javascript/controllers/index.js", %(application.register("scrim", ScrimController)\n)
25
- append_to_file "app/javascript/controllers/index.js", %(application.register("modal", ModalController)\n)
23
+ append_to_file "app/javascript/controllers/index.js", %(\nimport TurboModal from "@katalyst-interactive/turbo-modal"\n)
24
+ append_to_file "app/javascript/controllers/index.js", %(application.load(TurboModal)\n)
@@ -1,3 +1,3 @@
1
1
  module TurboModal
2
- VERSION = '0.2.2'
2
+ VERSION = "0.3.3".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_modal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Cornthwaite
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-03-16 00:00:00.000000000 Z
12
+ date: 2022-05-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -60,6 +60,7 @@ files:
60
60
  - app/helpers/scrim_helper.rb
61
61
  - app/javascript/turbo_modal/index.js
62
62
  - app/javascript/turbo_modal/modal_controller.js
63
+ - app/javascript/turbo_modal/modal_link_controller.js
63
64
  - app/javascript/turbo_modal/scrim_controller.js
64
65
  - config/routes.rb
65
66
  - lib/install/turbo_modal.rb