◆ ShadowDOM 内の場合はドロップできるエリアが小さい
◆ ボタンの上だけ
◆ input[type="file"] 自体が内部で ShadowDOM ぽいし 競合してる?

久々にファイルをドラッグ&ドロップできる機能を持つツールを作りました
drop イベントなどを使うのが自由度高いですが楽に済ませたかったので前に書いたこの記事の方法(input 要素を使う)にしました
ただ 使ってみるとなんか挙動がおかしいです
もう 3 年ほど経ってますし Chrome の仕様が変わったのかなと思って記事を書いたときに作ったサンプルページを使ってみるとちゃんと動きます

調べてみると ShadowDOM の内側でのみちゃんと動かないようです
通常時は input の内側全体がファイルのドロップを受け取るようになっていますが ShadowDOM の内部では input の中の 「ファイルを選択」 と書いたボタン部分にドロップしたときだけ input がドロップを受け取れます
input 要素の内側でもボタン外だとドラッグ中のマウスを乗せてもボタンの見た目が変わらないですし ドロップしたら普通のページにファイルをドロップしたときのように ブラウザがそのファイルを開いてページ遷移してしまいます

input の type="file" や video など独自の UI が出るものは Chrome 内部で ShadowDOM を使ってるらしいですし それらと競合してしまってるように思います

こういう動きになっています

<!doctype html>
<meta charset="utf-8">

<style>
div {
margin: 10px;
}
.file {
width: 400px;
height: 200px;
border: 2px solid gray;
}
</style>

<script>
customElements.define("a-b", class extends HTMLElement {
constructor(){
super()
this.attachShadow({mode: "open"})
this.shadowRoot.innerHTML = `
<div>shadow DOM ⇩</div>
<input type="file" class="file">

<style>
.file {
width: 400px;
height: 200px;
border: 2px solid gray;
}
</style>
`
}
})
</script>

<div>
<input type="file" class="file">
</div>
<div>
<a-b></a-b>
</div>

動画

chrome-shadowdom-input-drop

ShadowDOM 内のイベントは一部外側まで伝わらないので ドラッグイベントなどが window や document まで伝わらないのが原因かと思ってそれらのイベントを受け取って再度ディスパッチするようにしてみましたが 変わりなかったです
修正されるまでは input 要素じゃなくて 自分で drop イベントなどを使ってドロップされたファイルを管理するほうがよさそうです