phoenix_live_view 0.18.13 → 0.18.15

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.
package/README.md CHANGED
@@ -10,12 +10,14 @@ you can build, or see a sneak peek below:
10
10
 
11
11
  https://user-images.githubusercontent.com/576796/162234098-31b580fe-e424-47e6-b01d-cd2cfcf823a9.mp4
12
12
 
13
+ <br />
14
+
13
15
  After you [install Elixir](https://elixir-lang.org/install.html)
14
16
  on your machine, you can create your first LiveView app in two
15
17
  steps:
16
18
 
17
19
  $ mix archive.install hex phx_new
18
- $ mix phx.new demo --live
20
+ $ mix phx.new demo
19
21
 
20
22
  ## Features
21
23
 
@@ -58,6 +60,8 @@ steps:
58
60
 
59
61
  News from the Phoenix team on LiveView:
60
62
 
63
+ * [LiveBeats: Building a Social Music App With Phoenix LiveView](https://fly.io/blog/livebeats/)
64
+
61
65
  * [Build a real-time Twitter clone with LiveView](https://www.phoenixframework.org/blog/build-a-real-time-twitter-clone-in-15-minutes-with-live-view-and-phoenix-1-5)
62
66
 
63
67
  * [Initial announcement](https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-real-time-apps-no-need-to-write-javascript)
@@ -270,6 +270,20 @@ let DOM = {
270
270
  }
271
271
  },
272
272
 
273
+ resetForm(form, phxFeedbackFor){
274
+ Array.from(form.elements).forEach(input => {
275
+ let query = `[${phxFeedbackFor}="${input.id}"],
276
+ [${phxFeedbackFor}="${input.name}"],
277
+ [${phxFeedbackFor}="${input.name.replace(/\[\]$/, "")}"]`
278
+
279
+ this.deletePrivate(input, PHX_HAS_FOCUSED)
280
+ this.deletePrivate(input, PHX_HAS_SUBMITTED)
281
+ this.all(document, query, feedbackEl => {
282
+ feedbackEl.classList.add(PHX_NO_FEEDBACK_CLASS)
283
+ })
284
+ })
285
+ },
286
+
273
287
  showError(inputEl, phxFeedbackFor){
274
288
  if(inputEl.id || inputEl.name){
275
289
  this.all(inputEl.form, `[${phxFeedbackFor}="${inputEl.id}"], [${phxFeedbackFor}="${inputEl.name}"]`, (el) => {
@@ -90,10 +90,7 @@ let JS = {
90
90
  },
91
91
 
92
92
  exec_transition(eventType, phxEvent, view, sourceEl, el, {time, transition}){
93
- let [transition_start, running, transition_end] = transition
94
- let onStart = () => this.addOrRemoveClasses(el, transition_start.concat(running), [])
95
- let onDone = () => this.addOrRemoveClasses(el, transition_end, transition_start.concat(running))
96
- view.transition(time, onStart, onDone)
93
+ this.addOrRemoveClasses(el, [], [], transition, time, view)
97
94
  },
98
95
 
99
96
  exec_toggle(eventType, phxEvent, view, sourceEl, el, {display, ins, outs, time}){
@@ -152,7 +149,8 @@ let JS = {
152
149
  if(eventType === "remove"){ return }
153
150
  let onStart = () => {
154
151
  this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses))
155
- DOM.putSticky(el, "toggle", currentEl => currentEl.style.display = (display || "block"))
152
+ let stickyDisplay = display || this.defaultDisplay(el)
153
+ DOM.putSticky(el, "toggle", currentEl => currentEl.style.display = stickyDisplay)
156
154
  window.requestAnimationFrame(() => {
157
155
  this.addOrRemoveClasses(el, inClasses, [])
158
156
  window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses))
@@ -174,7 +172,8 @@ let JS = {
174
172
  } else {
175
173
  window.requestAnimationFrame(() => {
176
174
  el.dispatchEvent(new Event("phx:show-start"))
177
- DOM.putSticky(el, "toggle", currentEl => currentEl.style.display = display || "block")
175
+ let stickyDisplay = display || this.defaultDisplay(el)
176
+ DOM.putSticky(el, "toggle", currentEl => currentEl.style.display = stickyDisplay)
178
177
  el.dispatchEvent(new Event("phx:show-end"))
179
178
  })
180
179
  }
@@ -225,6 +224,10 @@ let JS = {
225
224
 
226
225
  filterToEls(sourceEl, {to}){
227
226
  return to ? DOM.all(document, to) : [sourceEl]
227
+ },
228
+
229
+ defaultDisplay(el){
230
+ return {tr: "table-row", td: "table-cell"}[el.tagName.toLowerCase()] || "block"
228
231
  }
229
232
  }
230
233
 
@@ -95,6 +95,7 @@ import {
95
95
  PHX_THROTTLE,
96
96
  PHX_TRACK_UPLOADS,
97
97
  PHX_SESSION,
98
+ PHX_FEEDBACK_FOR,
98
99
  RELOAD_JITTER_MIN,
99
100
  RELOAD_JITTER_MAX,
100
101
  } from "./constants"
@@ -855,6 +856,15 @@ export default class LiveSocket {
855
856
  })
856
857
  }, false)
857
858
  }
859
+ this.on("reset", (e) => {
860
+ let form = e.target
861
+ DOM.resetForm(form, this.binding(PHX_FEEDBACK_FOR))
862
+ let input = Array.from(form.elements).find(el => el.type === "reset")
863
+ // wait until next tick to get updated input value
864
+ window.requestAnimationFrame(() => {
865
+ input.dispatchEvent(new Event("input", {bubbles: true, cancelable: false}))
866
+ })
867
+ })
858
868
  }
859
869
 
860
870
  debounce(el, event, eventType, callback){
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phoenix_live_view",
3
- "version": "0.18.13",
3
+ "version": "0.18.15",
4
4
  "description": "The Phoenix LiveView JavaScript client.",
5
5
  "license": "MIT",
6
6
  "repository": {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phoenix_live_view",
3
- "version": "0.18.13",
3
+ "version": "0.18.15",
4
4
  "description": "The Phoenix LiveView JavaScript client.",
5
5
  "license": "MIT",
6
6
  "module": "./priv/static/phoenix_live_view.esm.js",
@@ -511,6 +511,18 @@ var DOM = {
511
511
  el.classList.add(PHX_NO_FEEDBACK_CLASS);
512
512
  }
513
513
  },
514
+ resetForm(form, phxFeedbackFor) {
515
+ Array.from(form.elements).forEach((input) => {
516
+ let query = `[${phxFeedbackFor}="${input.id}"],
517
+ [${phxFeedbackFor}="${input.name}"],
518
+ [${phxFeedbackFor}="${input.name.replace(/\[\]$/, "")}"]`;
519
+ this.deletePrivate(input, PHX_HAS_FOCUSED);
520
+ this.deletePrivate(input, PHX_HAS_SUBMITTED);
521
+ this.all(document, query, (feedbackEl) => {
522
+ feedbackEl.classList.add(PHX_NO_FEEDBACK_CLASS);
523
+ });
524
+ });
525
+ },
514
526
  showError(inputEl, phxFeedbackFor) {
515
527
  if (inputEl.id || inputEl.name) {
516
528
  this.all(inputEl.form, `[${phxFeedbackFor}="${inputEl.id}"], [${phxFeedbackFor}="${inputEl.name}"]`, (el) => {
@@ -2256,10 +2268,7 @@ var JS = {
2256
2268
  this.addOrRemoveClasses(el, [], names, transition, time, view);
2257
2269
  },
2258
2270
  exec_transition(eventType, phxEvent, view, sourceEl, el, { time, transition }) {
2259
- let [transition_start, running, transition_end] = transition;
2260
- let onStart = () => this.addOrRemoveClasses(el, transition_start.concat(running), []);
2261
- let onDone = () => this.addOrRemoveClasses(el, transition_end, transition_start.concat(running));
2262
- view.transition(time, onStart, onDone);
2271
+ this.addOrRemoveClasses(el, [], [], transition, time, view);
2263
2272
  },
2264
2273
  exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time }) {
2265
2274
  this.toggle(eventType, view, el, display, ins, outs, time);
@@ -2310,7 +2319,8 @@ var JS = {
2310
2319
  }
2311
2320
  let onStart = () => {
2312
2321
  this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses));
2313
- dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = display || "block");
2322
+ let stickyDisplay = display || this.defaultDisplay(el);
2323
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
2314
2324
  window.requestAnimationFrame(() => {
2315
2325
  this.addOrRemoveClasses(el, inClasses, []);
2316
2326
  window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses));
@@ -2332,7 +2342,8 @@ var JS = {
2332
2342
  } else {
2333
2343
  window.requestAnimationFrame(() => {
2334
2344
  el.dispatchEvent(new Event("phx:show-start"));
2335
- dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = display || "block");
2345
+ let stickyDisplay = display || this.defaultDisplay(el);
2346
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
2336
2347
  el.dispatchEvent(new Event("phx:show-end"));
2337
2348
  });
2338
2349
  }
@@ -2377,6 +2388,9 @@ var JS = {
2377
2388
  },
2378
2389
  filterToEls(sourceEl, { to }) {
2379
2390
  return to ? dom_default.all(document, to) : [sourceEl];
2391
+ },
2392
+ defaultDisplay(el) {
2393
+ return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";
2380
2394
  }
2381
2395
  };
2382
2396
  var js_default = JS;
@@ -4177,6 +4191,14 @@ var LiveSocket = class {
4177
4191
  });
4178
4192
  }, false);
4179
4193
  }
4194
+ this.on("reset", (e) => {
4195
+ let form = e.target;
4196
+ dom_default.resetForm(form, this.binding(PHX_FEEDBACK_FOR));
4197
+ let input = Array.from(form.elements).find((el) => el.type === "reset");
4198
+ window.requestAnimationFrame(() => {
4199
+ input.dispatchEvent(new Event("input", { bubbles: true, cancelable: false }));
4200
+ });
4201
+ });
4180
4202
  }
4181
4203
  debounce(el, event, eventType, callback) {
4182
4204
  if (eventType === "blur" || eventType === "focusout") {