widgets example
InputRange
基本的な使用法
<input-range>
にshadow DOM treeがアタッチされDOMを追加します。
ドキュメントのstyleは適用されません。
<input-range min=-10 max=10 value=0></input-range>
値をthumbと連動して動かす
open
属性を付けることで<input-range>
の子孫要素をLight DOMに追加し、ドキュメントのstyleを適用することができます。
値は<input-range>
直下の<output>
要素に出力され、styleには予め値に応じたleft
プロパティが設定されます。
normalize cssなどでinputのmarginが上書きされている場合はデフォルト値(2px)に設定し直す必要があります。
<input-range open id="ir1" min=-10 max=10 value=0></input-range>
#ir1{
position: relative;
}
#ir1 input{
margin: 2px;
}
#ir1 output{
position: absolute;
transform: translate(-50%, 100%);
}
もっとstyleを付ける
参照:Value Bubbles for Range Inputs | CSS-Tricks
<input-range open id="ir2" min=-10 max=10 value=0></input-range>
#ir2{
position: relative;
}
#ir2 input{
margin: 2px;
}
#ir2 output{
width: 30px;
height: 24px;
line-height: 24px;
text-align: center;
background: #03a9f4;
color: #fff;
font-size: 12px;
display: block;
position: absolute;
transform: translate(-50%, -56px);
border-radius: 6px;
}
#ir2 output::before {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: 10px solid #03a9f4;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
top: 100%;
left: 50%;
margin-left: -5px;
margin-top: -1px;
}
OutputFor
基本的な使用法
data-for
で指定したセレクターと最初に一致するインプット要素のvalueを表示します。
<input type="text" value="some text">
<output-for data-for='input[type="text"]'></output-for>
出力を加工する
data-func
に加工用の関数名を指定します。
function toUpper(str){return str.toUpperCase()}
<input id="in1" type="text" value="to upper case">
<output-for data-for='#in1' data-func="toUpper"></output-for>
もっと出力を加工する
実用性はありませんが可能性として。
キーワードで検索した最初の書籍のサムネイルを出力
async function book(str) {
const data = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${str}`).then(res => res.json());
return `<img src="${data.items[0].volumeInfo.imageLinks.smallThumbnail}">`
}
<input id="book" type="text" value="webcomponent">
<p><output-for data-for='#book' data-func="book"></output-for></p>
都道府県の天気予報
window.forcast = (function () {
const areaURL = "https://www.jma.go.jp/bosai/common/const/area.json";
const areaPromise = fetch(areaURL).then(res => res.json());
return async function forcast(pref) {
if (!pref) return "";
const area = await areaPromise;
let code;
Object.entries(area.offices).forEach(([c, obj]) => { if (obj.name.startsWith(pref)) { code = c } })
if (!code) return "";
const forcastURL = `https://www.jma.go.jp/bosai/forecast/data/forecast/${code}.json`;
const data = await fetch(forcastURL).then(res => res.json());
return data[0].timeSeries[0].areas[0].weathers[0];
}
})();
<input id="tenki" type="text" value="東京">
<p><output-for data-for='#tenki' data-func="forcast"></output-for></p>
(出所:気象庁ホームページ)