Horizonの標準バリアントピッカーを、Allbirdsやゴールドウインのような「未選択スタート・選択必須」の挙動に変えるプライベートブロックです。色・サイズなどのオプションを一つも選ばない状態から商品ページが始まり、全て選び終えるまで「カートに追加する」ボタンと「今すぐ購入」ボタンが押せません。
【必須前提条件】このブロックは Horizon v4.1.4 以降でのみ正しく動作します。それより前のバージョン(v3.2.1〜v4.1.1)では、コレクション一覧の商品カードが variant.url(バリアント自体のURL)を参照しているため、通常の一覧遷移でも常にバリアント選択済みの状態で商品ページが開いてしまい、「未選択スタート」の前提が根本から崩れます。v4.1.4でHorizon公式がこれを product.url に差し戻したことで解消されました。導入前に必ずテーマのバージョンを確認してください。

👉 実際の表示は、以下のデモストアで確認できます(バリアントが未選択の状態からスタートし、全て選ぶまでカート追加ボタンが無効化されている状態)。
horizon-store-q9zl2koe.myshopify.com/products/specialty-coffee-beans
ストアパスワード:store-dojo
完成イメージ
色・サイズどちらも塗り(選択中の表示)が無い状態からスタートします。カート追加ボタンはグレーアウトし、文言も「色を選択してください」のように未選択の項目を案内する内容に変わります。

無効なボタンを押すと、未選択のオプションが枠線で示される
ボタンを押しても何も起きないだけでは、なぜ押せないのか伝わりません。無効化されたボタンの上に見た目にはほぼ見えない透明な板を重ねてクリックを検知し、押された瞬間に未選択のままのオプショングループへ赤枠と案内メッセージを表示します。

実装の仕組み
◆各オプショングループ(色・サイズ等)が未確定の間は、本物の要素を隠し、見た目だけを複製したコピーをその場に表示します。複製はHorizon自身の状態管理から完全に独立しているため、複製側の選択状態は自由に操作できます。お客様が複製で選んだ瞬間だけ、対応する本物の要素に対して本物のclick/change操作を代理実行し、複製を消して本物を表示し直します。本物の要素の選択状態を直接書き換えることはしないため、Horizon自身の部分再描画(morph)や再解決ロジックと競合しません。
◆カート追加ボタンは複製せず、本物の disabled 属性とラベル文言を直接書き換えます。disabled な要素はHorizon側の実装(ボタンのclickで直接カートに追加している可能性)に関わらず確実に送信をブロックできます。見た目だけを薄くする方式では、ボタンのclickイベントが迂回されて実際にカートへ追加されてしまう不具合が起こり得ます。
◆ただし disabled な要素はclickイベント自体を発生させず、祖先へもbubbleしません。そこで本物のボタン(disabledのまま)の上に見た目にはほぼ見えない透明な板を1枚だけ重ね、そちらでクリックを検知して未選択グループの枠線表示を行います。「今すぐ購入」等の即時決済ボタンは、Shopify標準のWebコンポーネントで内部構造を触れないため、pointer-events: none でクリックそのものを無効化しています。
追加方法
◆Shopify管理画面 → オンラインストア → テーマ →「…」→ コードを編集
◆blocks フォルダに新規ファイル _variant-picker-require-selection.liquid を作成し、コードを貼り付けます(プライベートブロックとして扱われるため、ファイル名の先頭は必ず半角アンダースコアにしてください)。
◆blocks/_product-details.liquid の schema 内、variant-picker ブロックの直後に、新しいブロックの登録を1つ追加します。

◆テーマエディタの商品ページで、標準の「バリエーションピッカー」ブロックの代わりに、新しく追加された「バリエーションピッカー(選択必須)」ブロックに差し替えれば完成です。
コードの中身(抜粋)
◆見た目コピーでの選択を、本物の要素へのイベントとして代理実行する部分です。

◆カート追加ボタンのdisabled化と、クリック検知用の透明な板の配線部分です。

◆ご購入いただくと、この「バリアント選択必須ピッカー」の完成コード(Liquidファイル全文)をご利用いただけます。
関連TIPS:
標準のバリアントピッカーを画像付きの新規ブロックに置き換える
標準のバリアントピッカーをカード型UIでラップする
バリアントの選択肢に「+15,000円」「受注生産」などの補足情報を表示する
