2022年11月17日

Visit Japan Web について、細かいことですが一応。

帰国準備にあたってデジタル庁の Visit Japan Web にて検疫と税関の手続きをしました。





アカウントを作成し、パスポート写真とCOVIDワクチン接種カードをアップロード。おそらくパスポートは自動認識、COVIDカードは人力で確認しているっぽい感じです。とはいえそれほど待たされることもなく「審査完了」(青色)になったので、ここまでは良く作り込まれているなと感じました。



ただ一点残念だったのは、税関申告のページで「出発地」を入力する部分。

入力欄をクリックするとドロップダウンリストが表示されるのですが、全世界の都市名が不明な並び順でずらーっと出てきます。




ひたすらスクロールしても「ホノルル」も「ハワイ」も見つかりません。

さらにスクロールし続けると日本語の後になぜか英語表記が続きます。「英語なら見つかるのかな?」とさらに探しても「Honolulu」も「Hawaii」も選択肢にありません。

かろうじて「Other」という選択肢があったので、それにしようかとも思ったのですが、「いや、これだけホノルル便で入国する人が居るのだからまさか選択肢に無いということは無いだろう」と悩んでしまいました。


数秒間考えた後ふと思いついてキーボードから「H」と入力すると、ドロップダウンリストの内容が'H'で始まる都市名に絞られたので、「そうか、なるほど~」と「HONO」の4文字を入力したところでようやく「HONOLULU」の選択肢が現れました。

ところがどっこい、下の画像のとおり、「HONOLULU HA」と「HONOLULU - HA」の2行が表示されています。どっちを選べば良いのでしょう。笑)




まあ多分どちらを選んでも問題は無いと思うのですが、まぎらわしい選択肢が出ることは良いことではありません。


まとめると、「出発地」入力欄のUIの問題点は下の3つになるかと思います。


  1. 「都市名の先頭数文字を入力すると選択肢を絞り込める」ということが見た目上分からない。
  2. 何も入力せずクリックした場合に表示されるドロップダウンリストの内容が不完全。(おそらく全ての都市名を表示すると長くなり過ぎるので最初の200件程度で切っている。)
  3. 選択肢の並び順が不明。また都市名に重複がある。


これに対して私の考える改善策は下記になります。


  1. 「出発地」入力欄の下か上に「※ 最初の2〜3文字をキー入力すると選択肢が絞り込まれます。」などの注釈を表示する。
  2. 何も入力されていない場合はドロップダウンリストを表示しない。
  3. 選択肢の並び順を辞書順にする。都市名の重複を除去する。


いずれも簡単な修正なので、近いうちに改善されることを願います。


デジタル庁の実力はまだまだこんなものではないはず。期待しております!




2022年2月13日

MacでWindows 10/11向けにZip圧縮ファイルを作成する

MacのFinderで任意のフォルダを右クリックし、「圧縮」を選ぶと簡単にフォルダを丸ごとZipファイルに圧縮することが出来ます。


先日この方法で作成したファイルを人に送ったところ、Windows上で「フォルダ名やファイル名に日本語が含まれていると文字化けする」という問題が発生しました。


検索すると「MacはUTF8でWindowsはShift-JISだから...」という説明がたくさん見つかりますが、Zipファイルの解凍に関してはWindows 8以降であればUTF8にも対応しているためOS標準の機能(エクスプローラ上で右クリックから解凍など)を使えばこの問題は起こらないはずだそうです。



ところが、念のため自分のWindows 11マシンで試して見たところ、エクスプローラの右クリックから解凍した場合でも確かに日本語のフォルダ名とファイル名が文字化けすることを確認しました。Windows 11に至ってもまだこんな問題が残っているんでしょうかね。



以下にこの問題を回避するためにとった方法をメモとして残しておきます。



結論: Mac用のコマンドライン版7-zipをインストールする

 
```
brew install p7zip
```

自分の環境で試した限りでは、これでインストールされる 7z コマンドを使って圧縮すれば、Windows 10/11でも問題なく解凍出来るZipファイルを作成出来るようです。


圧縮ファイルを作成する

```
7z a [圧縮ファイル名].zip [フォルダ名]
```



問題が起きていたフォルダをこの方法で圧縮してWindows 11マシン上のエクスプローラ・右クリックで解凍して見たところ、文字化けすることなく正しく表示されました!




以上で解決なのですが、ついでにFinderの右クリックメニューから一発で上のコマンドを実行する方法もメモしておきます。


Automator で Quick Action を作成する






スクリプトの内容
```
ZIPNAME="$1-"$(date +"%Y%m%d-%H%M%S")
/usr/local/bin/7z a "$ZIPNAME.zip" "$@"
```


$@」を使うことで複数選択にも対応出来ます。


このQuick Actionを保存すれば、FinderのQuick Actionsメニューから実行出来るようになります。















 

2021年7月20日

TailwindCSS + Alpine.js でモーダルダイアログを作ろう

最近知ったのですが、 TailwindCSSAlpine.js の組み合わせがなかなか使いやすかったので紹介します。



作った手順は次の通りです。


1. TailwindCSS をCDNから読み込む。


headタグ内に次のlinkタグを追加します。

<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet" />





2. Alpine.js をCDNから読み込む。


headタグ内に次のstyleタグを追加します。

<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>



3. ページのレイアウトを作る。


bodyタグ直下のdivタグの中に、header, main, footer の3つの要素を作成します。

親のdivのスタイルで display: grid とし、それぞれのエリアの高さが header 6rem, main 1fr, footer 4rem  になるように指定します。また w-screen, h-screen で親のdivが画面一杯に広がるようにしています。

<div
class="m-0 p-0 w-screen h-screen grid"
style="grid-template-rows: 6rem 1fr 4rem;"
>


詳細はソースコードを参照してください。


下の画像のような表示になればOKです。



mainに overflow-y-auto クラスを指定しているので、コンテンツが画面に収まらない場合はフッターやヘッダーを固定にしたままmain部分だけを縦スクロールさせることが出来ます。

<main class="p-6 overflow-y-auto">




画面の中央にある「開く」ボタンのクラス指定は次のようになっています。(一部省略)

<button
class="py-2 px-4 max-h-12 bg-blue-600
hover:bg-blue-400 text-white border rounded-md shadow"
>


TailwindCSS のおかげでそれなりに見栄えの良いボタンになります。





4. モーダルダイアログのHTMLを追加。


親divの一番最後に下のHTMLを追加します。

<!-- モーダルダイアログのラッパー -->
<div>
<!-- 背景を暗くするための半透明部分 -->
<div></div>

<!-- 実際のモーダルダイアログ部分 -->
<div>
<header>
<h1>確認してください</h1>
</header>

<main>
<p>本当にこの操作を実行しますか?</p>
</main>

<footer>
<button>キャンセル</button>
<button>実行!</button>
</footer>
</div>
</div>


5. モーダルダイアログのスタイルを設定。


ラッパー用divに次のクラスを指定して、画面一杯をカバーするようにします。

<div class="absolute top-0 left-0 w-screen h-screen">


次に背景を暗くするためのdivのスタイルを設定します。

<div class="absolute w-full h-full bg-black opacity-80"></div>


ダイアログ本体部分のスタイル指定は下のようになります。

<div
class="relative w-5/6 max-w-xl h-1/2 m-auto grid bg-gray-300 border rounded-md shadow"
style="top: 20vh; grid-template-rows: 4rem 1fr 6rem;"
>


TailwindCSSで定義されていない値についてはstyle属性で独自に指定しています。

最終的にはこのようなダイアログになります。






6.  初期状態でモーダルダイアログを非表示にする。


ここから Alpine.js が活躍します。

まず、ページの一番親(body直下)のdivに x-data 属性を追加します。

<div
x-data="{ open : false }"
class="m-0 p-0 w-screen h-screen grid"
style="grid-template-rows: 6rem 1fr 4rem;"
>

次にモーダルダイアログのラッパーのdivに x-show 属性を追加します。

<!-- モーダルダイアログ -->
<div x-show="open" class="absolute top-0 left-0 w-screen h-screen">


これでモーダルダイアログが初期状態では表示されなくなります。




7. 「開く」ボタンでモーダルダイアログを表示する。


ページ中央の「開く」ボタンに @click="open = true" を追加します。

<button
@click="open = true"
class="py-2 px-4 max-h-12 bg-blue-600 ...
>開く</button>


これで「開く」ボタンをクリックするとモーダルダイアログが表示されるようになりました!


8. 「キャンセル」ボタンでモーダルダイアログを閉じる。


モーダルダイアログ内の「キャンセル」ボタンでは「開く」ボタンと反対に "open = false" とすることでダイアログを非表示にします。

<button
@click="open = false"
class="py-2 px-4 text-white bg-gray-600 ..."
>キャンセル</button>


Alpine.js シンプルで良いですね!


ちなみにx-showでの表示・非表示切替時にトランジションアニメーションを付けるには、x-transition 属性を付加するだけで大丈夫です。


x-transition ではデフォルトで250msの scale + opacityのアニメーションが実行されます。これをopacityのみに変更したい場合は、x-transitionx-transition.opacity とすればOKです。もちろん実行時間の指定も可能です。





9.  外側をクリックされたらモーダルダイアログを閉じる。


@click.outside という表記を使えば、その要素の外側がクリックされた時の処理を書くことが出来ます。

<!-- モーダルダイアログ -->
<div x-show="open" class="absolute top-0 left-0 ...">
<div class="absolute w-full h-full bg-black ..."></div>
<div
@click.outside="open = false"
class="relative w-5/6 max-w-xl h-1/2 m-auto ..."
style="top: 20vh; grid-template-rows: 4rem 1fr 6rem;"
>



10.  「実行!」ボタンが押されたらモーダルダイアログを閉じてカスタムイベントを発行する。


「実行!」ボタンの処理もキャンセルと同じように @click="..."の中に全て書いてしまっても良いのですが、ここでは Alpine.js のカスタムイベント発行の機能を使ってみます。 

<button
@click="open = false; $dispatch('dialog-ok')"
class="py-2 px-4 text-white bg-red-600 ..."
>実行!</button>





11.  カスタムイベントを受け取ったら何らかの処理を実行する。


$dispatch() で発行したカスタムイベントはDOMツリーの上位にある全ての要素で受け取ることが可能です。

ここでは body直下のdivにイベント処理を追加しました。

<div
x-data="{ open : false }"
@dialog-ok="setTimeout(() => alert('Hi'), 100)"
class="m-0 p-0 w-screen h-screen grid"
>


setTimeout()を使っているのは、これが無いとモーダルダイアログが閉じる前にアラートが表示されてしまっていたためです。



まとめ


TailwindCSSもAlpine.jsも、覚えないといけないことが少なくてすんなりと習得出来そうです。

TailwindCSSに慣れるとスタイルの設定にかかる時間が格段に短縮されます。Alpine.jsも必要最小限の使い方さえ覚えれば簡単な動作であればさくさくと実装出来て、とても便利です。


興味を持った方はぜひ試してみてください!








 🍻