`<wa-slider>` から無効な `required` 属性を削除

shoelace-style/webawesome

<input type="range">required 制約は仕様上存在しないため、<wa-slider> が誤って実装していた required 属性のサポートが削除されました。これにより、バグのあるバリデーション挙動が根本から解消されます。

背景

スライダーコンポーネントに required を追加する試みが、HTML仕様の範囲外の実装であったことが判明しました。#1471 で報告されたバグによると、required を持つスライダーを含むフォームは初回の送信試行こそブロックするものの、バリデーション違反を示すUIが何も表示されず、2回目以降の送信は通過してしまうという問題がありました。

この挙動の根本原因は、仕様にあります。<input type="range"> は常に値を持つ(デフォルト値が自動的に設定される)ため、ブラウザの制約バリデーション仕様において valueMissing 状態が定義されていません。PRの説明にある通り、スライダーが「未入力」になる状態は存在せず、required制約は range 型には適用できないのです。

誤った前提に基づくバリデーションロジックを維持し続けることは、信頼性の低いフォーム挙動につながるため、required サポートごと削除する判断が取られました。

技術的な変更

変更は slider.ts のプロパティ定義と slider-validator.ts のバリデーションロジックの2箇所に集中しており、関連するドキュメントも合わせて削除されています。

slider.ts からのプロパティ削除:

変更前:

/** Makes the slider a required field. */
@property({ type: Boolean, reflect: true }) required = false;

変更後: このプロパティ定義ごと削除。

slider-validator.ts のバリデーションロジック削除:

変更前:

// Create a native range input to get localized validation messages
const nativeRequiredRange = Object.assign(document.createElement('input'), {
  type: 'range',
  required: true,
});

return {
  observedAttributes: ['required', 'min', 'max', 'step'],
  checkValidity(element) {
    // ...
    // Check required validation first
    if (element.required && !element.hasInteracted) {
      validity.isValid = false;
      validity.invalidKeys.push('valueMissing');
      validity.message = nativeRequiredRange.validationMessage || 'Please fill out this field.';
      return validity;
    }
    // ...
  }
};

変更後:

return {
  observedAttributes: ['min', 'max', 'step'],
  checkValidity(element) {
    // required チェックなし、range/step バリデーションのみ
  }
};

ローカライズされたバリデーションメッセージを取得するために生成していた nativeRequiredRange 要素も不要になり、バリデータ全体がシンプルになっています。observedAttributes からも 'required' が削除され、不要な属性監視がなくなりました。

ドキュメント側では、slider.md の「Required」セクション(使用例のコードブロックを含む11行)が丸ごと削除され、ユーザーが誤った使い方を参照できないようになっています。

設計判断

「誤った機能を修正するのではなく、削除する」 という判断が取られています。

required 状態を擬似的にエミュレートする(例: スライダーが操作されるまで valueMissing を返し続ける)という方向性も考えられますが、PRでは「スライダーは性質上、カスタムバリデーションのみをサポートする」と明確に述べられています。仕様に存在しない required 状態を独自実装することは、ブラウザ標準との乖離を生み、今回のような不整合なUXを生み出す源泉になります。

スライダーに「入力必須」のような制約を課したいユースケースには、コンポーネントが元々サポートしているカスタムバリデーション(setCustomValidity)を使うことになります。これは Web Components のフォーム統合における正しいアプローチであり、スライダー固有の意味論に基づいた検証(例: 特定の値範囲に収まること)をアプリケーション側で定義できます。

まとめ

本PRは、仕様上存在しない制約を実装したことによるバグを、パッチではなく機能の削除によって解決した変更です。required への対応を完全に除去することで、コンポーネントをHTML仕様の範囲に正しく収め、バリデーションの信頼性を回復しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
80381662

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)」という構成が明確で、ガイドラインに完全に準拠しています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト、GitHubのIssue/PRリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

Web ComponentsやHTMLのフォームバリデーション仕様に関する知識を持つエンジニアを対象としており、専門用語のレベル感が適切です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが「総論→各論」で構成され、各段落がトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、非常に読みやすいです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

slider.ts, slider-validator.ts, slider.mdの変更点を正確に引用・説明しており、Diffの内容と完全に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「制約バリデーション」「valueMissing」「カスタムバリデーション」といった技術用語が正確かつ適切な文脈で使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

「<input type="range">が常に値を持つためrequired制約が適用できない」という変更の根本理由が、HTML仕様に基づいて技術的に正確に説明されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(バグの存在、仕様上の制約、設計判断)は、PRのTitle, Description, Diffから裏付けが取れており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2156)およびIssue番号(#1471)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの主題「無効なrequired属性の削除」を的確に要約しており、内容との整合性が取れています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

HTML仕様に関する補足説明はPRの背景理解を助けるものであり、PRに記載のない不要な外部知識(バージョン情報など)は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「削除されました」といった過去形の表現で統一されており、完了した変更であることが正確に伝わります。