Skip to content

Commit a4aa203

Browse files
committed
refactor(Datepicker): Extend HTMLElement directly
Drop the AlchemyHTMLElement base class in favor of a plain HTMLElement. The base class reads innerHTML in its constructor, which violates the Web Components spec and leaves cloned elements in an inconsistent state when jQuery's clone(true) walks the subtree. Bail out of connectedCallback after the async locale import if the element was disconnected in the meantime. Without this guard, a fast drag-drop would leak a flatpickr calendar onto a detached input because the drop ghost gets disconnected before the import resolves. Also guard disconnectedCallback with optional chaining so a teardown before initialization does not throw.
1 parent fcaf215 commit a4aa203

3 files changed

Lines changed: 13 additions & 16 deletions

File tree

app/assets/builds/alchemy/alchemy_admin.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/assets/builds/alchemy/alchemy_admin.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/javascript/alchemy_admin/components/datepicker.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,24 @@
1-
import { AlchemyHTMLElement } from "alchemy_admin/components/alchemy_html_element"
21
import { translate, currentLocale } from "alchemy_admin/i18n"
32
import flatpickr from "flatpickr"
43

54
const locale = currentLocale()
65

7-
class Datepicker extends AlchemyHTMLElement {
8-
static properties = {
9-
inputType: { default: "date" }
10-
}
11-
12-
constructor() {
13-
super()
14-
this.flatpickr = undefined
15-
}
16-
6+
class Datepicker extends HTMLElement {
177
// Load the locales for flatpickr before setting it up.
18-
async connected() {
8+
async connectedCallback() {
199
// English is the default locale for flatpickr, so we don't need to load it
2010
if (locale !== "en") {
2111
await import(`flatpickr/${locale}.js`)
2212
}
13+
// Bail out if the element was disconnected while the locale was loading.
14+
// Otherwise flatpickr would leak a calendar onto a detached input.
15+
if (!this.isConnected) return
2316

2417
this.flatpickr = flatpickr(this.inputField, this.flatpickrOptions)
2518
}
2619

27-
disconnected() {
28-
this.flatpickr.destroy()
20+
disconnectedCallback() {
21+
this.flatpickr?.destroy()
2922
}
3023

3124
get flatpickrOptions() {
@@ -56,6 +49,10 @@ class Datepicker extends AlchemyHTMLElement {
5649
get inputField() {
5750
return this.querySelector("input")
5851
}
52+
53+
get inputType() {
54+
return this.getAttribute("input-type") || "date"
55+
}
5956
}
6057

6158
customElements.define("alchemy-datepicker", Datepicker)

0 commit comments

Comments
 (0)